src/atomic/SDL_spinlock.c
author Sam Lantinga <slouken@libsdl.org>
Sun, 13 Feb 2011 14:01:02 -0800
changeset 5289 1916a9e9714d
parent 5262 b530ef003506
child 5328 f34a5f9ce9f6
permissions -rw-r--r--
Frank Zago to SDL

On 02/12/2011 01:44 PM, Sam Lantinga wrote:
> BTW, you probably want to nuke the NDS renderer and just implement these three
> functions instead:
> int (*CreateWindowFramebuffer) (_THIS, SDL_Window * window, Uint32 *
> format, void ** pixels, int *pitch);
> int (*UpdateWindowFramebuffer) (_THIS, SDL_Window * window, int numrects,
> SDL_Rect * rects);
> void (*DestroyWindowFramebuffer) (_THIS, SDL_Window * window);

Patch attached. The renderer for the DS is not used anymore, but I left the
file in place if someone wants to finish it.

I've also added a README.ds and fixed the spinlocks.
     1 /*
     2   SDL - Simple DirectMedia Layer
     3   Copyright (C) 1997-2011 Sam Lantinga
     4 
     5   This library is free software; you can redistribute it and/or
     6   modify it under the terms of the GNU Lesser General Public
     7   License as published by the Free Software Foundation; either
     8   version 2.1 of the License, or (at your option) any later version.
     9 
    10   This library is distributed in the hope that it will be useful,
    11   but WITHOUT ANY WARRANTY; without even the implied warranty of
    12   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    13   Lesser General Public License for more details.
    14 
    15   You should have received a copy of the GNU Lesser General Public
    16   License along with this library; if not, write to the Free Software
    17   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
    18 
    19   Sam Lantinga
    20   slouken@libsdl.org
    21 */
    22 #include "SDL_stdinc.h"
    23 
    24 #include "SDL_atomic.h"
    25 #include "SDL_mutex.h"
    26 #include "SDL_timer.h"
    27 
    28 /* Don't do the check for Visual Studio 2005, it's safe here */
    29 #ifdef __WIN32__
    30 #include "../core/windows/SDL_windows.h"
    31 #endif
    32 
    33 /* This function is where all the magic happens... */
    34 SDL_bool
    35 SDL_AtomicTryLock(SDL_SpinLock *lock)
    36 {
    37 #if SDL_ATOMIC_DISABLED
    38     /* Terrible terrible damage */
    39     static SDL_mutex *_spinlock_mutex;
    40 
    41     if (!_spinlock_mutex) {
    42         /* Race condition on first lock... */
    43         _spinlock_mutex = SDL_CreateMutex();
    44     }
    45     SDL_mutexP(_spinlock_mutex);
    46     if (*lock == 0) {
    47         *lock = 1;
    48         SDL_mutexV(_spinlock_mutex);
    49         return SDL_TRUE;
    50     } else {
    51         SDL_mutexV(_spinlock_mutex);
    52         return SDL_FALSE;
    53     }
    54 
    55 #elif defined(_MSC_VER)
    56     SDL_COMPILE_TIME_ASSERT(locksize, sizeof(*lock) == sizeof(long));
    57     return (InterlockedExchange((long*)lock, 1) == 0);
    58 
    59 #elif defined(__MACOSX__)
    60     return OSAtomicCompareAndSwap32Barrier(0, 1, lock);
    61 
    62 #elif HAVE_GCC_ATOMICS || HAVE_GCC_SYNC_LOCK_TEST_AND_SET
    63     return (__sync_lock_test_and_set(lock, 1) == 0);
    64 
    65 #elif defined(__GNUC__) && defined(__arm__) && (defined(__ARM_ARCH_5__) || defined(__ARM_ARCH_5TE__))
    66     int result;
    67     __asm__ __volatile__ (
    68         "swp %0, %1, [%2]\n"
    69         : "=&r,&r" (result) : "r,0" (1), "r,r" (lock) : "memory");
    70     return (result == 0);
    71 
    72 #elif defined(__GNUC__) && defined(__arm__)
    73     int result;
    74     __asm__ __volatile__ (
    75         "ldrex %0, [%2]\nteq   %0, #0\nstrexeq %0, %1, [%2]"
    76         : "=&r" (result) : "r" (1), "r" (lock) : "cc", "memory");
    77     return (result == 0);
    78 
    79 #else
    80     /* Need CPU instructions for spinlock here! */
    81     __need_spinlock_implementation__
    82 #endif
    83 }
    84 
    85 void
    86 SDL_AtomicLock(SDL_SpinLock *lock)
    87 {
    88     /* FIXME: Should we have an eventual timeout? */
    89     while (!SDL_AtomicTryLock(lock)) {
    90         SDL_Delay(0);
    91     }
    92 }
    93 
    94 void
    95 SDL_AtomicUnlock(SDL_SpinLock *lock)
    96 {
    97 #if defined(_MSC_VER)
    98     _ReadWriteBarrier();
    99     *lock = 0;
   100 
   101 #elif HAVE_GCC_ATOMICS || HAVE_GCC_SYNC_LOCK_TEST_AND_SET
   102     __sync_lock_release(lock);
   103 
   104 #else
   105     *lock = 0;
   106 #endif
   107 }
   108 
   109 /* vi: set ts=4 sw=4 expandtab: */