Skip to content
Permalink
Browse files

video: put a spinlock around a global linked list.

This should only contend if you're allocating or freeing surfaces from
multiple threads at once, and then just for a short time.

Fixes Bugzilla #4084.
  • Loading branch information
icculus committed Feb 16, 2018
1 parent 8ddebfa commit 6867f6189fa31bd22d623d87367975f830f14a46
Showing with 15 additions and 0 deletions.
  1. +15 −0 src/video/SDL_pixels.c
@@ -490,27 +490,33 @@ SDL_MasksToPixelFormatEnum(int bpp, Uint32 Rmask, Uint32 Gmask, Uint32 Bmask,
}

static SDL_PixelFormat *formats;
static SDL_SpinLock formats_lock = 0;

SDL_PixelFormat *
SDL_AllocFormat(Uint32 pixel_format)
{
SDL_PixelFormat *format;

SDL_AtomicLock(&formats_lock);

/* Look it up in our list of previously allocated formats */
for (format = formats; format; format = format->next) {
if (pixel_format == format->format) {
++format->refcount;
SDL_AtomicUnlock(&formats_lock);
return format;
}
}

/* Allocate an empty pixel format structure, and initialize it */
format = SDL_malloc(sizeof(*format));
if (format == NULL) {
SDL_AtomicUnlock(&formats_lock);
SDL_OutOfMemory();
return NULL;
}
if (SDL_InitFormat(format, pixel_format) < 0) {
SDL_AtomicUnlock(&formats_lock);
SDL_free(format);
SDL_InvalidParamError("format");
return NULL;
@@ -521,6 +527,9 @@ SDL_AllocFormat(Uint32 pixel_format)
format->next = formats;
formats = format;
}

SDL_AtomicUnlock(&formats_lock);

return format;
}

@@ -598,7 +607,11 @@ SDL_FreeFormat(SDL_PixelFormat *format)
SDL_InvalidParamError("format");
return;
}

SDL_AtomicLock(&formats_lock);

if (--format->refcount > 0) {
SDL_AtomicUnlock(&formats_lock);
return;
}

@@ -614,6 +627,8 @@ SDL_FreeFormat(SDL_PixelFormat *format)
}
}

SDL_AtomicUnlock(&formats_lock);

if (format->palette) {
SDL_FreePalette(format->palette);
}

0 comments on commit 6867f61

Please sign in to comment.