video: put a spinlock around a global linked list.
authorRyan C. Gordon <icculus@icculus.org>
Fri, 16 Feb 2018 14:56:28 -0500
changeset 118772a25e8690229
parent 11876 dfde5d3f9781
child 11878 625cdd85edfe
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.
src/video/SDL_pixels.c
     1.1 --- a/src/video/SDL_pixels.c	Fri Feb 16 10:23:10 2018 -0800
     1.2 +++ b/src/video/SDL_pixels.c	Fri Feb 16 14:56:28 2018 -0500
     1.3 @@ -490,16 +490,20 @@
     1.4  }
     1.5  
     1.6  static SDL_PixelFormat *formats;
     1.7 +static SDL_SpinLock formats_lock = 0;
     1.8  
     1.9  SDL_PixelFormat *
    1.10  SDL_AllocFormat(Uint32 pixel_format)
    1.11  {
    1.12      SDL_PixelFormat *format;
    1.13  
    1.14 +    SDL_AtomicLock(&formats_lock);
    1.15 +
    1.16      /* Look it up in our list of previously allocated formats */
    1.17      for (format = formats; format; format = format->next) {
    1.18          if (pixel_format == format->format) {
    1.19              ++format->refcount;
    1.20 +            SDL_AtomicUnlock(&formats_lock);
    1.21              return format;
    1.22          }
    1.23      }
    1.24 @@ -507,10 +511,12 @@
    1.25      /* Allocate an empty pixel format structure, and initialize it */
    1.26      format = SDL_malloc(sizeof(*format));
    1.27      if (format == NULL) {
    1.28 +        SDL_AtomicUnlock(&formats_lock);
    1.29          SDL_OutOfMemory();
    1.30          return NULL;
    1.31      }
    1.32      if (SDL_InitFormat(format, pixel_format) < 0) {
    1.33 +        SDL_AtomicUnlock(&formats_lock);
    1.34          SDL_free(format);
    1.35          SDL_InvalidParamError("format");
    1.36          return NULL;
    1.37 @@ -521,6 +527,9 @@
    1.38          format->next = formats;
    1.39          formats = format;
    1.40      }
    1.41 +
    1.42 +    SDL_AtomicUnlock(&formats_lock);
    1.43 +
    1.44      return format;
    1.45  }
    1.46  
    1.47 @@ -598,7 +607,11 @@
    1.48          SDL_InvalidParamError("format");
    1.49          return;
    1.50      }
    1.51 +
    1.52 +    SDL_AtomicLock(&formats_lock);
    1.53 +
    1.54      if (--format->refcount > 0) {
    1.55 +        SDL_AtomicUnlock(&formats_lock);
    1.56          return;
    1.57      }
    1.58  
    1.59 @@ -614,6 +627,8 @@
    1.60          }
    1.61      }
    1.62  
    1.63 +    SDL_AtomicUnlock(&formats_lock);
    1.64 +
    1.65      if (format->palette) {
    1.66          SDL_FreePalette(format->palette);
    1.67      }