Navigation Menu

Skip to content

Commit

Permalink
video: put a spinlock around a global linked list.
Browse files Browse the repository at this point in the history
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 6867f61
Showing 1 changed file with 15 additions and 0 deletions.
15 changes: 15 additions & 0 deletions src/video/SDL_pixels.c
Expand Up @@ -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;
Expand All @@ -521,6 +527,9 @@ SDL_AllocFormat(Uint32 pixel_format)
format->next = formats;
formats = format;
}

SDL_AtomicUnlock(&formats_lock);

return format;
}

Expand Down Expand Up @@ -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;
}

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

SDL_AtomicUnlock(&formats_lock);

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

0 comments on commit 6867f61

Please sign in to comment.