src/atomic/SDL_atomic.c
author Ryan C. Gordon <icculus@icculus.org>
Fri, 12 Aug 2016 19:59:00 -0400
changeset 10266 c09f06c4e8c8
parent 9998 f67cf37e9cd4
permissions -rw-r--r--
emscripten: send fake mouse events for touches, like other targets do. (This really should be handled at the higher level and not in the individual targets, but this fixes the immediate bug.)
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
5003
3a95a2b93eb3 Updated the atomic API for better use cases
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
     1
/*
5535
96594ac5fd1a SDL 1.3 is now under the zlib license.
Sam Lantinga <slouken@libsdl.org>
parents: 5262
diff changeset
     2
  Simple DirectMedia Layer
9998
f67cf37e9cd4 Updated copyright to 2016
Sam Lantinga <slouken@libsdl.org>
parents: 9619
diff changeset
     3
  Copyright (C) 1997-2016 Sam Lantinga <slouken@libsdl.org>
5003
3a95a2b93eb3 Updated the atomic API for better use cases
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
     4
5535
96594ac5fd1a SDL 1.3 is now under the zlib license.
Sam Lantinga <slouken@libsdl.org>
parents: 5262
diff changeset
     5
  This software is provided 'as-is', without any express or implied
96594ac5fd1a SDL 1.3 is now under the zlib license.
Sam Lantinga <slouken@libsdl.org>
parents: 5262
diff changeset
     6
  warranty.  In no event will the authors be held liable for any damages
96594ac5fd1a SDL 1.3 is now under the zlib license.
Sam Lantinga <slouken@libsdl.org>
parents: 5262
diff changeset
     7
  arising from the use of this software.
5003
3a95a2b93eb3 Updated the atomic API for better use cases
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
     8
5535
96594ac5fd1a SDL 1.3 is now under the zlib license.
Sam Lantinga <slouken@libsdl.org>
parents: 5262
diff changeset
     9
  Permission is granted to anyone to use this software for any purpose,
96594ac5fd1a SDL 1.3 is now under the zlib license.
Sam Lantinga <slouken@libsdl.org>
parents: 5262
diff changeset
    10
  including commercial applications, and to alter it and redistribute it
96594ac5fd1a SDL 1.3 is now under the zlib license.
Sam Lantinga <slouken@libsdl.org>
parents: 5262
diff changeset
    11
  freely, subject to the following restrictions:
5003
3a95a2b93eb3 Updated the atomic API for better use cases
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    12
5535
96594ac5fd1a SDL 1.3 is now under the zlib license.
Sam Lantinga <slouken@libsdl.org>
parents: 5262
diff changeset
    13
  1. The origin of this software must not be misrepresented; you must not
96594ac5fd1a SDL 1.3 is now under the zlib license.
Sam Lantinga <slouken@libsdl.org>
parents: 5262
diff changeset
    14
     claim that you wrote the original software. If you use this software
96594ac5fd1a SDL 1.3 is now under the zlib license.
Sam Lantinga <slouken@libsdl.org>
parents: 5262
diff changeset
    15
     in a product, an acknowledgment in the product documentation would be
96594ac5fd1a SDL 1.3 is now under the zlib license.
Sam Lantinga <slouken@libsdl.org>
parents: 5262
diff changeset
    16
     appreciated but is not required.
96594ac5fd1a SDL 1.3 is now under the zlib license.
Sam Lantinga <slouken@libsdl.org>
parents: 5262
diff changeset
    17
  2. Altered source versions must be plainly marked as such, and must not be
96594ac5fd1a SDL 1.3 is now under the zlib license.
Sam Lantinga <slouken@libsdl.org>
parents: 5262
diff changeset
    18
     misrepresented as being the original software.
96594ac5fd1a SDL 1.3 is now under the zlib license.
Sam Lantinga <slouken@libsdl.org>
parents: 5262
diff changeset
    19
  3. This notice may not be removed or altered from any source distribution.
5003
3a95a2b93eb3 Updated the atomic API for better use cases
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    20
*/
8093
b43765095a6f Make internal SDL sources include SDL_internal.h instead of SDL_config.h
Ryan C. Gordon <icculus@icculus.org>
parents: 8092
diff changeset
    21
#include "../SDL_internal.h"
5003
3a95a2b93eb3 Updated the atomic API for better use cases
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    22
3a95a2b93eb3 Updated the atomic API for better use cases
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    23
#include "SDL_atomic.h"
3a95a2b93eb3 Updated the atomic API for better use cases
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    24
8088
e5d77d5e0fe2 Moved atomic API implementation out of headers.
Ryan C. Gordon <icculus@icculus.org>
parents: 7860
diff changeset
    25
#if defined(_MSC_VER) && (_MSC_VER >= 1500)
e5d77d5e0fe2 Moved atomic API implementation out of headers.
Ryan C. Gordon <icculus@icculus.org>
parents: 7860
diff changeset
    26
#include <intrin.h>
e5d77d5e0fe2 Moved atomic API implementation out of headers.
Ryan C. Gordon <icculus@icculus.org>
parents: 7860
diff changeset
    27
#define HAVE_MSC_ATOMICS 1
e5d77d5e0fe2 Moved atomic API implementation out of headers.
Ryan C. Gordon <icculus@icculus.org>
parents: 7860
diff changeset
    28
#endif
e5d77d5e0fe2 Moved atomic API implementation out of headers.
Ryan C. Gordon <icculus@icculus.org>
parents: 7860
diff changeset
    29
e5d77d5e0fe2 Moved atomic API implementation out of headers.
Ryan C. Gordon <icculus@icculus.org>
parents: 7860
diff changeset
    30
#if defined(__MACOSX__)  /* !!! FIXME: should we favor gcc atomics? */
e5d77d5e0fe2 Moved atomic API implementation out of headers.
Ryan C. Gordon <icculus@icculus.org>
parents: 7860
diff changeset
    31
#include <libkern/OSAtomic.h>
e5d77d5e0fe2 Moved atomic API implementation out of headers.
Ryan C. Gordon <icculus@icculus.org>
parents: 7860
diff changeset
    32
#endif
7191
75360622e65f File style cleanup for the SDL 2.0 release
Sam Lantinga <slouken@libsdl.org>
parents: 6978
diff changeset
    33
8979
1e283b7a1580 2620 solaris port missing atomics if not using gcc
Shawn Walker <binarycrusader@gmail.com>
parents: 8149
diff changeset
    34
#if !defined(HAVE_GCC_ATOMICS) && defined(__SOLARIS__)
1e283b7a1580 2620 solaris port missing atomics if not using gcc
Shawn Walker <binarycrusader@gmail.com>
parents: 8149
diff changeset
    35
#include <atomic.h>
1e283b7a1580 2620 solaris port missing atomics if not using gcc
Shawn Walker <binarycrusader@gmail.com>
parents: 8149
diff changeset
    36
#endif
1e283b7a1580 2620 solaris port missing atomics if not using gcc
Shawn Walker <binarycrusader@gmail.com>
parents: 8149
diff changeset
    37
7191
75360622e65f File style cleanup for the SDL 2.0 release
Sam Lantinga <slouken@libsdl.org>
parents: 6978
diff changeset
    38
/*
5003
3a95a2b93eb3 Updated the atomic API for better use cases
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    39
  If any of the operations are not provided then we must emulate some
3a95a2b93eb3 Updated the atomic API for better use cases
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    40
  of them. That means we need a nice implementation of spin locks
3a95a2b93eb3 Updated the atomic API for better use cases
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    41
  that avoids the "one big lock" problem. We use a vector of spin
3a95a2b93eb3 Updated the atomic API for better use cases
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    42
  locks and pick which one to use based on the address of the operand
3a95a2b93eb3 Updated the atomic API for better use cases
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    43
  of the function.
3a95a2b93eb3 Updated the atomic API for better use cases
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    44
3a95a2b93eb3 Updated the atomic API for better use cases
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    45
  To generate the index of the lock we first shift by 3 bits to get
3a95a2b93eb3 Updated the atomic API for better use cases
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    46
  rid on the zero bits that result from 32 and 64 bit allignment of
3a95a2b93eb3 Updated the atomic API for better use cases
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    47
  data. We then mask off all but 5 bits and use those 5 bits as an
7191
75360622e65f File style cleanup for the SDL 2.0 release
Sam Lantinga <slouken@libsdl.org>
parents: 6978
diff changeset
    48
  index into the table.
5003
3a95a2b93eb3 Updated the atomic API for better use cases
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    49
3a95a2b93eb3 Updated the atomic API for better use cases
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    50
  Picking the lock this way insures that accesses to the same data at
3a95a2b93eb3 Updated the atomic API for better use cases
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    51
  the same time will go to the same lock. OTOH, accesses to different
3a95a2b93eb3 Updated the atomic API for better use cases
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    52
  data have only a 1/32 chance of hitting the same lock. That should
3a95a2b93eb3 Updated the atomic API for better use cases
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    53
  pretty much eliminate the chances of several atomic operations on
3a95a2b93eb3 Updated the atomic API for better use cases
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    54
  different data from waiting on the same "big lock". If it isn't
3a95a2b93eb3 Updated the atomic API for better use cases
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    55
  then the table of locks can be expanded to a new size so long as
3a95a2b93eb3 Updated the atomic API for better use cases
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    56
  the new size is a power of two.
3a95a2b93eb3 Updated the atomic API for better use cases
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    57
3a95a2b93eb3 Updated the atomic API for better use cases
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    58
  Contributed by Bob Pendleton, bob@pendleton.com
3a95a2b93eb3 Updated the atomic API for better use cases
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    59
*/
3a95a2b93eb3 Updated the atomic API for better use cases
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    60
8979
1e283b7a1580 2620 solaris port missing atomics if not using gcc
Shawn Walker <binarycrusader@gmail.com>
parents: 8149
diff changeset
    61
#if !defined(HAVE_MSC_ATOMICS) && !defined(HAVE_GCC_ATOMICS) && !defined(__MACOSX__) && !defined(__SOLARIS__)
8088
e5d77d5e0fe2 Moved atomic API implementation out of headers.
Ryan C. Gordon <icculus@icculus.org>
parents: 7860
diff changeset
    62
#define EMULATE_CAS 1
e5d77d5e0fe2 Moved atomic API implementation out of headers.
Ryan C. Gordon <icculus@icculus.org>
parents: 7860
diff changeset
    63
#endif
e5d77d5e0fe2 Moved atomic API implementation out of headers.
Ryan C. Gordon <icculus@icculus.org>
parents: 7860
diff changeset
    64
e5d77d5e0fe2 Moved atomic API implementation out of headers.
Ryan C. Gordon <icculus@icculus.org>
parents: 7860
diff changeset
    65
#if EMULATE_CAS
5003
3a95a2b93eb3 Updated the atomic API for better use cases
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    66
static SDL_SpinLock locks[32];
3a95a2b93eb3 Updated the atomic API for better use cases
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    67
7860
2b0bcdea3a79 Fixed bug 2129 - fix for bug 2121 breaks linking for mingw and throws multiple warnings
Sam Lantinga <slouken@libsdl.org>
parents: 7394
diff changeset
    68
static SDL_INLINE void
5003
3a95a2b93eb3 Updated the atomic API for better use cases
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    69
enterLock(void *a)
3a95a2b93eb3 Updated the atomic API for better use cases
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    70
{
5004
0c72ae7b7cb2 Added native atomic operations for Windows, Mac OS X, and gcc compiler intrinsics.
Sam Lantinga <slouken@libsdl.org>
parents: 5003
diff changeset
    71
    uintptr_t index = ((((uintptr_t)a) >> 3) & 0x1f);
5003
3a95a2b93eb3 Updated the atomic API for better use cases
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    72
5004
0c72ae7b7cb2 Added native atomic operations for Windows, Mac OS X, and gcc compiler intrinsics.
Sam Lantinga <slouken@libsdl.org>
parents: 5003
diff changeset
    73
    SDL_AtomicLock(&locks[index]);
5003
3a95a2b93eb3 Updated the atomic API for better use cases
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    74
}
3a95a2b93eb3 Updated the atomic API for better use cases
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    75
7860
2b0bcdea3a79 Fixed bug 2129 - fix for bug 2121 breaks linking for mingw and throws multiple warnings
Sam Lantinga <slouken@libsdl.org>
parents: 7394
diff changeset
    76
static SDL_INLINE void
5003
3a95a2b93eb3 Updated the atomic API for better use cases
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    77
leaveLock(void *a)
3a95a2b93eb3 Updated the atomic API for better use cases
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    78
{
5004
0c72ae7b7cb2 Added native atomic operations for Windows, Mac OS X, and gcc compiler intrinsics.
Sam Lantinga <slouken@libsdl.org>
parents: 5003
diff changeset
    79
    uintptr_t index = ((((uintptr_t)a) >> 3) & 0x1f);
5003
3a95a2b93eb3 Updated the atomic API for better use cases
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    80
5004
0c72ae7b7cb2 Added native atomic operations for Windows, Mac OS X, and gcc compiler intrinsics.
Sam Lantinga <slouken@libsdl.org>
parents: 5003
diff changeset
    81
    SDL_AtomicUnlock(&locks[index]);
5003
3a95a2b93eb3 Updated the atomic API for better use cases
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    82
}
8088
e5d77d5e0fe2 Moved atomic API implementation out of headers.
Ryan C. Gordon <icculus@icculus.org>
parents: 7860
diff changeset
    83
#endif
5003
3a95a2b93eb3 Updated the atomic API for better use cases
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    84
8088
e5d77d5e0fe2 Moved atomic API implementation out of headers.
Ryan C. Gordon <icculus@icculus.org>
parents: 7860
diff changeset
    85
e5d77d5e0fe2 Moved atomic API implementation out of headers.
Ryan C. Gordon <icculus@icculus.org>
parents: 7860
diff changeset
    86
SDL_bool
6978
e851407e9294 Put the real SDL_AtomicCAS() and SDL_AtomicCASPtr() symbols into the library.
Sam Lantinga <slouken@libsdl.org>
parents: 6885
diff changeset
    87
SDL_AtomicCAS(SDL_atomic_t *a, int oldval, int newval)
5003
3a95a2b93eb3 Updated the atomic API for better use cases
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
    88
{
8088
e5d77d5e0fe2 Moved atomic API implementation out of headers.
Ryan C. Gordon <icculus@icculus.org>
parents: 7860
diff changeset
    89
#ifdef HAVE_MSC_ATOMICS
e5d77d5e0fe2 Moved atomic API implementation out of headers.
Ryan C. Gordon <icculus@icculus.org>
parents: 7860
diff changeset
    90
    return (_InterlockedCompareExchange((long*)&a->value, (long)newval, (long)oldval) == (long)oldval);
e5d77d5e0fe2 Moved atomic API implementation out of headers.
Ryan C. Gordon <icculus@icculus.org>
parents: 7860
diff changeset
    91
#elif defined(__MACOSX__)  /* !!! FIXME: should we favor gcc atomics? */
e5d77d5e0fe2 Moved atomic API implementation out of headers.
Ryan C. Gordon <icculus@icculus.org>
parents: 7860
diff changeset
    92
    return (SDL_bool) OSAtomicCompareAndSwap32Barrier(oldval, newval, &a->value);
e5d77d5e0fe2 Moved atomic API implementation out of headers.
Ryan C. Gordon <icculus@icculus.org>
parents: 7860
diff changeset
    93
#elif defined(HAVE_GCC_ATOMICS)
e5d77d5e0fe2 Moved atomic API implementation out of headers.
Ryan C. Gordon <icculus@icculus.org>
parents: 7860
diff changeset
    94
    return (SDL_bool) __sync_bool_compare_and_swap(&a->value, oldval, newval);
8979
1e283b7a1580 2620 solaris port missing atomics if not using gcc
Shawn Walker <binarycrusader@gmail.com>
parents: 8149
diff changeset
    95
#elif defined(__SOLARIS__) && defined(_LP64)
1e283b7a1580 2620 solaris port missing atomics if not using gcc
Shawn Walker <binarycrusader@gmail.com>
parents: 8149
diff changeset
    96
    return (SDL_bool) ((int) atomic_cas_64((volatile uint64_t*)&a->value, (uint64_t)oldval, (uint64_t)newval) == oldval);
1e283b7a1580 2620 solaris port missing atomics if not using gcc
Shawn Walker <binarycrusader@gmail.com>
parents: 8149
diff changeset
    97
#elif defined(__SOLARIS__) && !defined(_LP64)
1e283b7a1580 2620 solaris port missing atomics if not using gcc
Shawn Walker <binarycrusader@gmail.com>
parents: 8149
diff changeset
    98
    return (SDL_bool) ((int) atomic_cas_32((volatile uint32_t*)&a->value, (uint32_t)oldval, (uint32_t)newval) == oldval);
8088
e5d77d5e0fe2 Moved atomic API implementation out of headers.
Ryan C. Gordon <icculus@icculus.org>
parents: 7860
diff changeset
    99
#elif EMULATE_CAS
5004
0c72ae7b7cb2 Added native atomic operations for Windows, Mac OS X, and gcc compiler intrinsics.
Sam Lantinga <slouken@libsdl.org>
parents: 5003
diff changeset
   100
    SDL_bool retval = SDL_FALSE;
5003
3a95a2b93eb3 Updated the atomic API for better use cases
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
   101
3a95a2b93eb3 Updated the atomic API for better use cases
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
   102
    enterLock(a);
5004
0c72ae7b7cb2 Added native atomic operations for Windows, Mac OS X, and gcc compiler intrinsics.
Sam Lantinga <slouken@libsdl.org>
parents: 5003
diff changeset
   103
    if (a->value == oldval) {
5003
3a95a2b93eb3 Updated the atomic API for better use cases
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
   104
        a->value = newval;
5004
0c72ae7b7cb2 Added native atomic operations for Windows, Mac OS X, and gcc compiler intrinsics.
Sam Lantinga <slouken@libsdl.org>
parents: 5003
diff changeset
   105
        retval = SDL_TRUE;
5003
3a95a2b93eb3 Updated the atomic API for better use cases
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
   106
    }
3a95a2b93eb3 Updated the atomic API for better use cases
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
   107
    leaveLock(a);
3a95a2b93eb3 Updated the atomic API for better use cases
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
   108
5004
0c72ae7b7cb2 Added native atomic operations for Windows, Mac OS X, and gcc compiler intrinsics.
Sam Lantinga <slouken@libsdl.org>
parents: 5003
diff changeset
   109
    return retval;
8088
e5d77d5e0fe2 Moved atomic API implementation out of headers.
Ryan C. Gordon <icculus@icculus.org>
parents: 7860
diff changeset
   110
#else
e5d77d5e0fe2 Moved atomic API implementation out of headers.
Ryan C. Gordon <icculus@icculus.org>
parents: 7860
diff changeset
   111
    #error Please define your platform.
e5d77d5e0fe2 Moved atomic API implementation out of headers.
Ryan C. Gordon <icculus@icculus.org>
parents: 7860
diff changeset
   112
#endif
5003
3a95a2b93eb3 Updated the atomic API for better use cases
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
   113
}
3a95a2b93eb3 Updated the atomic API for better use cases
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
   114
8088
e5d77d5e0fe2 Moved atomic API implementation out of headers.
Ryan C. Gordon <icculus@icculus.org>
parents: 7860
diff changeset
   115
SDL_bool
6978
e851407e9294 Put the real SDL_AtomicCAS() and SDL_AtomicCASPtr() symbols into the library.
Sam Lantinga <slouken@libsdl.org>
parents: 6885
diff changeset
   116
SDL_AtomicCASPtr(void **a, void *oldval, void *newval)
5003
3a95a2b93eb3 Updated the atomic API for better use cases
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
   117
{
8088
e5d77d5e0fe2 Moved atomic API implementation out of headers.
Ryan C. Gordon <icculus@icculus.org>
parents: 7860
diff changeset
   118
#if defined(HAVE_MSC_ATOMICS) && (_M_IX86)
e5d77d5e0fe2 Moved atomic API implementation out of headers.
Ryan C. Gordon <icculus@icculus.org>
parents: 7860
diff changeset
   119
    return (_InterlockedCompareExchange((long*)a, (long)newval, (long)oldval) == (long)oldval);
e5d77d5e0fe2 Moved atomic API implementation out of headers.
Ryan C. Gordon <icculus@icculus.org>
parents: 7860
diff changeset
   120
#elif defined(HAVE_MSC_ATOMICS) && (!_M_IX86)
e5d77d5e0fe2 Moved atomic API implementation out of headers.
Ryan C. Gordon <icculus@icculus.org>
parents: 7860
diff changeset
   121
    return (_InterlockedCompareExchangePointer(a, newval, oldval) == oldval);
e5d77d5e0fe2 Moved atomic API implementation out of headers.
Ryan C. Gordon <icculus@icculus.org>
parents: 7860
diff changeset
   122
#elif defined(__MACOSX__) && defined(__LP64__)   /* !!! FIXME: should we favor gcc atomics? */
e5d77d5e0fe2 Moved atomic API implementation out of headers.
Ryan C. Gordon <icculus@icculus.org>
parents: 7860
diff changeset
   123
    return (SDL_bool) OSAtomicCompareAndSwap64Barrier((int64_t)oldval, (int64_t)newval, (int64_t*) a);
e5d77d5e0fe2 Moved atomic API implementation out of headers.
Ryan C. Gordon <icculus@icculus.org>
parents: 7860
diff changeset
   124
#elif defined(__MACOSX__) && !defined(__LP64__)  /* !!! FIXME: should we favor gcc atomics? */
e5d77d5e0fe2 Moved atomic API implementation out of headers.
Ryan C. Gordon <icculus@icculus.org>
parents: 7860
diff changeset
   125
    return (SDL_bool) OSAtomicCompareAndSwap32Barrier((int32_t)oldval, (int32_t)newval, (int32_t*) a);
e5d77d5e0fe2 Moved atomic API implementation out of headers.
Ryan C. Gordon <icculus@icculus.org>
parents: 7860
diff changeset
   126
#elif defined(HAVE_GCC_ATOMICS)
e5d77d5e0fe2 Moved atomic API implementation out of headers.
Ryan C. Gordon <icculus@icculus.org>
parents: 7860
diff changeset
   127
    return __sync_bool_compare_and_swap(a, oldval, newval);
8979
1e283b7a1580 2620 solaris port missing atomics if not using gcc
Shawn Walker <binarycrusader@gmail.com>
parents: 8149
diff changeset
   128
#elif defined(__SOLARIS__)
1e283b7a1580 2620 solaris port missing atomics if not using gcc
Shawn Walker <binarycrusader@gmail.com>
parents: 8149
diff changeset
   129
    return (SDL_bool) (atomic_cas_ptr(a, oldval, newval) == oldval);
8088
e5d77d5e0fe2 Moved atomic API implementation out of headers.
Ryan C. Gordon <icculus@icculus.org>
parents: 7860
diff changeset
   130
#elif EMULATE_CAS
5004
0c72ae7b7cb2 Added native atomic operations for Windows, Mac OS X, and gcc compiler intrinsics.
Sam Lantinga <slouken@libsdl.org>
parents: 5003
diff changeset
   131
    SDL_bool retval = SDL_FALSE;
5003
3a95a2b93eb3 Updated the atomic API for better use cases
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
   132
3a95a2b93eb3 Updated the atomic API for better use cases
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
   133
    enterLock(a);
3a95a2b93eb3 Updated the atomic API for better use cases
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
   134
    if (*a == oldval) {
3a95a2b93eb3 Updated the atomic API for better use cases
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
   135
        *a = newval;
5004
0c72ae7b7cb2 Added native atomic operations for Windows, Mac OS X, and gcc compiler intrinsics.
Sam Lantinga <slouken@libsdl.org>
parents: 5003
diff changeset
   136
        retval = SDL_TRUE;
5003
3a95a2b93eb3 Updated the atomic API for better use cases
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
   137
    }
3a95a2b93eb3 Updated the atomic API for better use cases
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
   138
    leaveLock(a);
3a95a2b93eb3 Updated the atomic API for better use cases
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
   139
5004
0c72ae7b7cb2 Added native atomic operations for Windows, Mac OS X, and gcc compiler intrinsics.
Sam Lantinga <slouken@libsdl.org>
parents: 5003
diff changeset
   140
    return retval;
8088
e5d77d5e0fe2 Moved atomic API implementation out of headers.
Ryan C. Gordon <icculus@icculus.org>
parents: 7860
diff changeset
   141
#else
e5d77d5e0fe2 Moved atomic API implementation out of headers.
Ryan C. Gordon <icculus@icculus.org>
parents: 7860
diff changeset
   142
    #error Please define your platform.
e5d77d5e0fe2 Moved atomic API implementation out of headers.
Ryan C. Gordon <icculus@icculus.org>
parents: 7860
diff changeset
   143
#endif
e5d77d5e0fe2 Moved atomic API implementation out of headers.
Ryan C. Gordon <icculus@icculus.org>
parents: 7860
diff changeset
   144
}
e5d77d5e0fe2 Moved atomic API implementation out of headers.
Ryan C. Gordon <icculus@icculus.org>
parents: 7860
diff changeset
   145
e5d77d5e0fe2 Moved atomic API implementation out of headers.
Ryan C. Gordon <icculus@icculus.org>
parents: 7860
diff changeset
   146
int
e5d77d5e0fe2 Moved atomic API implementation out of headers.
Ryan C. Gordon <icculus@icculus.org>
parents: 7860
diff changeset
   147
SDL_AtomicSet(SDL_atomic_t *a, int v)
e5d77d5e0fe2 Moved atomic API implementation out of headers.
Ryan C. Gordon <icculus@icculus.org>
parents: 7860
diff changeset
   148
{
e5d77d5e0fe2 Moved atomic API implementation out of headers.
Ryan C. Gordon <icculus@icculus.org>
parents: 7860
diff changeset
   149
#ifdef HAVE_MSC_ATOMICS
e5d77d5e0fe2 Moved atomic API implementation out of headers.
Ryan C. Gordon <icculus@icculus.org>
parents: 7860
diff changeset
   150
    return _InterlockedExchange((long*)&a->value, v);
e5d77d5e0fe2 Moved atomic API implementation out of headers.
Ryan C. Gordon <icculus@icculus.org>
parents: 7860
diff changeset
   151
#elif defined(HAVE_GCC_ATOMICS)
e5d77d5e0fe2 Moved atomic API implementation out of headers.
Ryan C. Gordon <icculus@icculus.org>
parents: 7860
diff changeset
   152
    return __sync_lock_test_and_set(&a->value, v);
8979
1e283b7a1580 2620 solaris port missing atomics if not using gcc
Shawn Walker <binarycrusader@gmail.com>
parents: 8149
diff changeset
   153
#elif defined(__SOLARIS__) && defined(_LP64)
1e283b7a1580 2620 solaris port missing atomics if not using gcc
Shawn Walker <binarycrusader@gmail.com>
parents: 8149
diff changeset
   154
    return (int) atomic_swap_64((volatile uint64_t*)&a->value, (uint64_t)v);
1e283b7a1580 2620 solaris port missing atomics if not using gcc
Shawn Walker <binarycrusader@gmail.com>
parents: 8149
diff changeset
   155
#elif defined(__SOLARIS__) && !defined(_LP64)
1e283b7a1580 2620 solaris port missing atomics if not using gcc
Shawn Walker <binarycrusader@gmail.com>
parents: 8149
diff changeset
   156
    return (int) atomic_swap_32((volatile uint32_t*)&a->value, (uint32_t)v);
8088
e5d77d5e0fe2 Moved atomic API implementation out of headers.
Ryan C. Gordon <icculus@icculus.org>
parents: 7860
diff changeset
   157
#else
e5d77d5e0fe2 Moved atomic API implementation out of headers.
Ryan C. Gordon <icculus@icculus.org>
parents: 7860
diff changeset
   158
    int value;
e5d77d5e0fe2 Moved atomic API implementation out of headers.
Ryan C. Gordon <icculus@icculus.org>
parents: 7860
diff changeset
   159
    do {
e5d77d5e0fe2 Moved atomic API implementation out of headers.
Ryan C. Gordon <icculus@icculus.org>
parents: 7860
diff changeset
   160
        value = a->value;
e5d77d5e0fe2 Moved atomic API implementation out of headers.
Ryan C. Gordon <icculus@icculus.org>
parents: 7860
diff changeset
   161
    } while (!SDL_AtomicCAS(a, value, v));
e5d77d5e0fe2 Moved atomic API implementation out of headers.
Ryan C. Gordon <icculus@icculus.org>
parents: 7860
diff changeset
   162
    return value;
e5d77d5e0fe2 Moved atomic API implementation out of headers.
Ryan C. Gordon <icculus@icculus.org>
parents: 7860
diff changeset
   163
#endif
e5d77d5e0fe2 Moved atomic API implementation out of headers.
Ryan C. Gordon <icculus@icculus.org>
parents: 7860
diff changeset
   164
}
e5d77d5e0fe2 Moved atomic API implementation out of headers.
Ryan C. Gordon <icculus@icculus.org>
parents: 7860
diff changeset
   165
e5d77d5e0fe2 Moved atomic API implementation out of headers.
Ryan C. Gordon <icculus@icculus.org>
parents: 7860
diff changeset
   166
void*
e5d77d5e0fe2 Moved atomic API implementation out of headers.
Ryan C. Gordon <icculus@icculus.org>
parents: 7860
diff changeset
   167
SDL_AtomicSetPtr(void **a, void *v)
e5d77d5e0fe2 Moved atomic API implementation out of headers.
Ryan C. Gordon <icculus@icculus.org>
parents: 7860
diff changeset
   168
{
8092
46fb898f098d Patched stdlib changes to compile on Windows.
Ryan C. Gordon <icculus@icculus.org>
parents: 8088
diff changeset
   169
#if defined(HAVE_MSC_ATOMICS) && (_M_IX86)
46fb898f098d Patched stdlib changes to compile on Windows.
Ryan C. Gordon <icculus@icculus.org>
parents: 8088
diff changeset
   170
    return (void *) _InterlockedExchange((long *)a, (long) v);
46fb898f098d Patched stdlib changes to compile on Windows.
Ryan C. Gordon <icculus@icculus.org>
parents: 8088
diff changeset
   171
#elif defined(HAVE_MSC_ATOMICS) && (!_M_IX86)
8088
e5d77d5e0fe2 Moved atomic API implementation out of headers.
Ryan C. Gordon <icculus@icculus.org>
parents: 7860
diff changeset
   172
    return _InterlockedExchangePointer(a, v);
e5d77d5e0fe2 Moved atomic API implementation out of headers.
Ryan C. Gordon <icculus@icculus.org>
parents: 7860
diff changeset
   173
#elif defined(HAVE_GCC_ATOMICS)
e5d77d5e0fe2 Moved atomic API implementation out of headers.
Ryan C. Gordon <icculus@icculus.org>
parents: 7860
diff changeset
   174
    return __sync_lock_test_and_set(a, v);
8979
1e283b7a1580 2620 solaris port missing atomics if not using gcc
Shawn Walker <binarycrusader@gmail.com>
parents: 8149
diff changeset
   175
#elif defined(__SOLARIS__)
1e283b7a1580 2620 solaris port missing atomics if not using gcc
Shawn Walker <binarycrusader@gmail.com>
parents: 8149
diff changeset
   176
    return atomic_swap_ptr(a, v);
8088
e5d77d5e0fe2 Moved atomic API implementation out of headers.
Ryan C. Gordon <icculus@icculus.org>
parents: 7860
diff changeset
   177
#else
e5d77d5e0fe2 Moved atomic API implementation out of headers.
Ryan C. Gordon <icculus@icculus.org>
parents: 7860
diff changeset
   178
    void *value;
e5d77d5e0fe2 Moved atomic API implementation out of headers.
Ryan C. Gordon <icculus@icculus.org>
parents: 7860
diff changeset
   179
    do {
e5d77d5e0fe2 Moved atomic API implementation out of headers.
Ryan C. Gordon <icculus@icculus.org>
parents: 7860
diff changeset
   180
        value = *a;
e5d77d5e0fe2 Moved atomic API implementation out of headers.
Ryan C. Gordon <icculus@icculus.org>
parents: 7860
diff changeset
   181
    } while (!SDL_AtomicCASPtr(a, value, v));
e5d77d5e0fe2 Moved atomic API implementation out of headers.
Ryan C. Gordon <icculus@icculus.org>
parents: 7860
diff changeset
   182
    return value;
e5d77d5e0fe2 Moved atomic API implementation out of headers.
Ryan C. Gordon <icculus@icculus.org>
parents: 7860
diff changeset
   183
#endif
5003
3a95a2b93eb3 Updated the atomic API for better use cases
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
   184
}
3a95a2b93eb3 Updated the atomic API for better use cases
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
   185
8088
e5d77d5e0fe2 Moved atomic API implementation out of headers.
Ryan C. Gordon <icculus@icculus.org>
parents: 7860
diff changeset
   186
int
e5d77d5e0fe2 Moved atomic API implementation out of headers.
Ryan C. Gordon <icculus@icculus.org>
parents: 7860
diff changeset
   187
SDL_AtomicAdd(SDL_atomic_t *a, int v)
e5d77d5e0fe2 Moved atomic API implementation out of headers.
Ryan C. Gordon <icculus@icculus.org>
parents: 7860
diff changeset
   188
{
e5d77d5e0fe2 Moved atomic API implementation out of headers.
Ryan C. Gordon <icculus@icculus.org>
parents: 7860
diff changeset
   189
#ifdef HAVE_MSC_ATOMICS
e5d77d5e0fe2 Moved atomic API implementation out of headers.
Ryan C. Gordon <icculus@icculus.org>
parents: 7860
diff changeset
   190
    return _InterlockedExchangeAdd((long*)&a->value, v);
e5d77d5e0fe2 Moved atomic API implementation out of headers.
Ryan C. Gordon <icculus@icculus.org>
parents: 7860
diff changeset
   191
#elif defined(HAVE_GCC_ATOMICS)
e5d77d5e0fe2 Moved atomic API implementation out of headers.
Ryan C. Gordon <icculus@icculus.org>
parents: 7860
diff changeset
   192
    return __sync_fetch_and_add(&a->value, v);
8979
1e283b7a1580 2620 solaris port missing atomics if not using gcc
Shawn Walker <binarycrusader@gmail.com>
parents: 8149
diff changeset
   193
#elif defined(__SOLARIS__)
1e283b7a1580 2620 solaris port missing atomics if not using gcc
Shawn Walker <binarycrusader@gmail.com>
parents: 8149
diff changeset
   194
    int pv = a->value;
1e283b7a1580 2620 solaris port missing atomics if not using gcc
Shawn Walker <binarycrusader@gmail.com>
parents: 8149
diff changeset
   195
    membar_consumer();
1e283b7a1580 2620 solaris port missing atomics if not using gcc
Shawn Walker <binarycrusader@gmail.com>
parents: 8149
diff changeset
   196
#if defined(_LP64)
1e283b7a1580 2620 solaris port missing atomics if not using gcc
Shawn Walker <binarycrusader@gmail.com>
parents: 8149
diff changeset
   197
    atomic_add_64((volatile uint64_t*)&a->value, v);
1e283b7a1580 2620 solaris port missing atomics if not using gcc
Shawn Walker <binarycrusader@gmail.com>
parents: 8149
diff changeset
   198
#elif !defined(_LP64)
1e283b7a1580 2620 solaris port missing atomics if not using gcc
Shawn Walker <binarycrusader@gmail.com>
parents: 8149
diff changeset
   199
    atomic_add_32((volatile uint32_t*)&a->value, v);
1e283b7a1580 2620 solaris port missing atomics if not using gcc
Shawn Walker <binarycrusader@gmail.com>
parents: 8149
diff changeset
   200
#endif
1e283b7a1580 2620 solaris port missing atomics if not using gcc
Shawn Walker <binarycrusader@gmail.com>
parents: 8149
diff changeset
   201
    return pv;
8088
e5d77d5e0fe2 Moved atomic API implementation out of headers.
Ryan C. Gordon <icculus@icculus.org>
parents: 7860
diff changeset
   202
#else
e5d77d5e0fe2 Moved atomic API implementation out of headers.
Ryan C. Gordon <icculus@icculus.org>
parents: 7860
diff changeset
   203
    int value;
e5d77d5e0fe2 Moved atomic API implementation out of headers.
Ryan C. Gordon <icculus@icculus.org>
parents: 7860
diff changeset
   204
    do {
e5d77d5e0fe2 Moved atomic API implementation out of headers.
Ryan C. Gordon <icculus@icculus.org>
parents: 7860
diff changeset
   205
        value = a->value;
e5d77d5e0fe2 Moved atomic API implementation out of headers.
Ryan C. Gordon <icculus@icculus.org>
parents: 7860
diff changeset
   206
    } while (!SDL_AtomicCAS(a, value, (value + v)));
e5d77d5e0fe2 Moved atomic API implementation out of headers.
Ryan C. Gordon <icculus@icculus.org>
parents: 7860
diff changeset
   207
    return value;
e5d77d5e0fe2 Moved atomic API implementation out of headers.
Ryan C. Gordon <icculus@icculus.org>
parents: 7860
diff changeset
   208
#endif
e5d77d5e0fe2 Moved atomic API implementation out of headers.
Ryan C. Gordon <icculus@icculus.org>
parents: 7860
diff changeset
   209
}
e5d77d5e0fe2 Moved atomic API implementation out of headers.
Ryan C. Gordon <icculus@icculus.org>
parents: 7860
diff changeset
   210
e5d77d5e0fe2 Moved atomic API implementation out of headers.
Ryan C. Gordon <icculus@icculus.org>
parents: 7860
diff changeset
   211
int
e5d77d5e0fe2 Moved atomic API implementation out of headers.
Ryan C. Gordon <icculus@icculus.org>
parents: 7860
diff changeset
   212
SDL_AtomicGet(SDL_atomic_t *a)
e5d77d5e0fe2 Moved atomic API implementation out of headers.
Ryan C. Gordon <icculus@icculus.org>
parents: 7860
diff changeset
   213
{
e5d77d5e0fe2 Moved atomic API implementation out of headers.
Ryan C. Gordon <icculus@icculus.org>
parents: 7860
diff changeset
   214
    int value;
e5d77d5e0fe2 Moved atomic API implementation out of headers.
Ryan C. Gordon <icculus@icculus.org>
parents: 7860
diff changeset
   215
    do {
e5d77d5e0fe2 Moved atomic API implementation out of headers.
Ryan C. Gordon <icculus@icculus.org>
parents: 7860
diff changeset
   216
        value = a->value;
e5d77d5e0fe2 Moved atomic API implementation out of headers.
Ryan C. Gordon <icculus@icculus.org>
parents: 7860
diff changeset
   217
    } while (!SDL_AtomicCAS(a, value, value));
e5d77d5e0fe2 Moved atomic API implementation out of headers.
Ryan C. Gordon <icculus@icculus.org>
parents: 7860
diff changeset
   218
    return value;
e5d77d5e0fe2 Moved atomic API implementation out of headers.
Ryan C. Gordon <icculus@icculus.org>
parents: 7860
diff changeset
   219
}
e5d77d5e0fe2 Moved atomic API implementation out of headers.
Ryan C. Gordon <icculus@icculus.org>
parents: 7860
diff changeset
   220
e5d77d5e0fe2 Moved atomic API implementation out of headers.
Ryan C. Gordon <icculus@icculus.org>
parents: 7860
diff changeset
   221
void *
e5d77d5e0fe2 Moved atomic API implementation out of headers.
Ryan C. Gordon <icculus@icculus.org>
parents: 7860
diff changeset
   222
SDL_AtomicGetPtr(void **a)
e5d77d5e0fe2 Moved atomic API implementation out of headers.
Ryan C. Gordon <icculus@icculus.org>
parents: 7860
diff changeset
   223
{
e5d77d5e0fe2 Moved atomic API implementation out of headers.
Ryan C. Gordon <icculus@icculus.org>
parents: 7860
diff changeset
   224
    void *value;
e5d77d5e0fe2 Moved atomic API implementation out of headers.
Ryan C. Gordon <icculus@icculus.org>
parents: 7860
diff changeset
   225
    do {
e5d77d5e0fe2 Moved atomic API implementation out of headers.
Ryan C. Gordon <icculus@icculus.org>
parents: 7860
diff changeset
   226
        value = *a;
e5d77d5e0fe2 Moved atomic API implementation out of headers.
Ryan C. Gordon <icculus@icculus.org>
parents: 7860
diff changeset
   227
    } while (!SDL_AtomicCASPtr(a, value, value));
e5d77d5e0fe2 Moved atomic API implementation out of headers.
Ryan C. Gordon <icculus@icculus.org>
parents: 7860
diff changeset
   228
    return value;
e5d77d5e0fe2 Moved atomic API implementation out of headers.
Ryan C. Gordon <icculus@icculus.org>
parents: 7860
diff changeset
   229
}
e5d77d5e0fe2 Moved atomic API implementation out of headers.
Ryan C. Gordon <icculus@icculus.org>
parents: 7860
diff changeset
   230
e5d77d5e0fe2 Moved atomic API implementation out of headers.
Ryan C. Gordon <icculus@icculus.org>
parents: 7860
diff changeset
   231
#ifdef __thumb__
8096
132b47684fbf Patched to compile on Android (I think).
Ryan C. Gordon <icculus@icculus.org>
parents: 8093
diff changeset
   232
#if defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) || defined(__ARM_ARCH_6K__) || defined(__ARM_ARCH_6T2__) || defined(__ARM_ARCH_6Z__) || defined(__ARM_ARCH_6ZK__)
7394
38dc4961ab15 Added PowerPC and ARM versions of the memory barrier functions.
Sam Lantinga <slouken@libsdl.org>
parents: 7191
diff changeset
   233
__asm__(
38dc4961ab15 Added PowerPC and ARM versions of the memory barrier functions.
Sam Lantinga <slouken@libsdl.org>
parents: 7191
diff changeset
   234
"   .align 2\n"
38dc4961ab15 Added PowerPC and ARM versions of the memory barrier functions.
Sam Lantinga <slouken@libsdl.org>
parents: 7191
diff changeset
   235
"   .globl _SDL_MemoryBarrierRelease\n"
38dc4961ab15 Added PowerPC and ARM versions of the memory barrier functions.
Sam Lantinga <slouken@libsdl.org>
parents: 7191
diff changeset
   236
"   .globl _SDL_MemoryBarrierAcquire\n"
38dc4961ab15 Added PowerPC and ARM versions of the memory barrier functions.
Sam Lantinga <slouken@libsdl.org>
parents: 7191
diff changeset
   237
"_SDL_MemoryBarrierRelease:\n"
38dc4961ab15 Added PowerPC and ARM versions of the memory barrier functions.
Sam Lantinga <slouken@libsdl.org>
parents: 7191
diff changeset
   238
"_SDL_MemoryBarrierAcquire:\n"
38dc4961ab15 Added PowerPC and ARM versions of the memory barrier functions.
Sam Lantinga <slouken@libsdl.org>
parents: 7191
diff changeset
   239
"   mov r0, #0\n"
38dc4961ab15 Added PowerPC and ARM versions of the memory barrier functions.
Sam Lantinga <slouken@libsdl.org>
parents: 7191
diff changeset
   240
"   mcr p15, 0, r0, c7, c10, 5\n"
38dc4961ab15 Added PowerPC and ARM versions of the memory barrier functions.
Sam Lantinga <slouken@libsdl.org>
parents: 7191
diff changeset
   241
"   bx lr\n"
38dc4961ab15 Added PowerPC and ARM versions of the memory barrier functions.
Sam Lantinga <slouken@libsdl.org>
parents: 7191
diff changeset
   242
);
8088
e5d77d5e0fe2 Moved atomic API implementation out of headers.
Ryan C. Gordon <icculus@icculus.org>
parents: 7860
diff changeset
   243
#endif
8096
132b47684fbf Patched to compile on Android (I think).
Ryan C. Gordon <icculus@icculus.org>
parents: 8093
diff changeset
   244
#endif
7394
38dc4961ab15 Added PowerPC and ARM versions of the memory barrier functions.
Sam Lantinga <slouken@libsdl.org>
parents: 7191
diff changeset
   245
5003
3a95a2b93eb3 Updated the atomic API for better use cases
Sam Lantinga <slouken@libsdl.org>
parents:
diff changeset
   246
/* vi: set ts=4 sw=4 expandtab: */