src/atomic/SDL_spinlock.c
author Sam Lantinga <slouken@libsdl.org>
Tue, 25 Jan 2011 18:02:41 -0800
changeset 5097 b938ad843e52
parent 5095 dceec93471e7
child 5225 5d01d426f2ea
permissions -rw-r--r--
More fixes for compilation on Visual Studio
     1 /*
     2   SDL - Simple DirectMedia Layer
     3   Copyright (C) 1997-2010 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_timer.h"
    26 
    27 /* Don't do the check for Visual Studio 2005, it's safe here */
    28 #ifdef __WIN32__
    29 #include "../core/windows/SDL_windows.h"
    30 #endif
    31 
    32 /* This function is where all the magic happens... */
    33 SDL_bool
    34 SDL_AtomicTryLock(SDL_SpinLock *lock)
    35 {
    36 #if defined(_MSC_VER)
    37     SDL_COMPILE_TIME_ASSERT(locksize, sizeof(*lock) == sizeof(long));
    38     return (InterlockedExchange((long*)lock, 1) == 0);
    39 
    40 #elif defined(__MACOSX__)
    41     return OSAtomicCompareAndSwap32Barrier(0, 1, lock);
    42 
    43 #elif HAVE_GCC_ATOMICS || HAVE_GCC_SYNC_LOCK_TEST_AND_SET
    44     return (__sync_lock_test_and_set(lock, 1) == 0);
    45 
    46 #elif defined(__GNUC__) && defined(__arm__) && defined(__ARM_ARCH_5__)
    47     int result;
    48     __asm__ __volatile__ (
    49         "swp %0, %1, [%2]\n"
    50         : "=&r,&r" (result) : "r,0" (1), "r,r" (lock) : "memory");
    51     return (result == 0);
    52 
    53 #elif defined(__GNUC__) && defined(__arm__)
    54     int result;
    55     __asm__ __volatile__ (
    56         "ldrex %0, [%2]\nteq   %0, #0\nstrexeq %0, %1, [%2]"
    57         : "=&r" (result) : "r" (1), "r" (lock) : "cc", "memory");
    58     return (result == 0);
    59 
    60 #else
    61     /* Need CPU instructions for spinlock here! */
    62     __need_spinlock_implementation__
    63 #endif
    64 }
    65 
    66 void
    67 SDL_AtomicLock(SDL_SpinLock *lock)
    68 {
    69     /* FIXME: Should we have an eventual timeout? */
    70     while (!SDL_AtomicTryLock(lock)) {
    71         SDL_Delay(0);
    72     }
    73 }
    74 
    75 void
    76 SDL_AtomicUnlock(SDL_SpinLock *lock)
    77 {
    78 #if defined(_MSC_VER)
    79     _ReadWriteBarrier();
    80     *lock = 0;
    81 
    82 #elif HAVE_GCC_ATOMICS || HAVE_GCC_SYNC_LOCK_TEST_AND_SET
    83     __sync_lock_release(lock);
    84 
    85 #else
    86     *lock = 0;
    87 #endif
    88 }
    89 
    90 /* vi: set ts=4 sw=4 expandtab: */