src/atomic/win32/SDL_atomic.c
author Bob Pendleton <bob@pendleton.com>
Mon, 29 Jun 2009 19:54:43 +0000
changeset 3202 3aa519a5c676
parent 3199 3e1bf2b8bd81
child 3212 759032c318d8
permissions -rw-r--r--
I've made so many changes I don't dare continue until I check the current stuff in.

/test/testatomic.c performs absolutely basic tests to show that the function work as expected. Need a second test to do more detailed tests.

/include/SDL_atomic.h provides declarations for all included functions.

/src/atomic/linux/SDL_atomic.c provided all the functions. On a generic built the 64 bit functions work, but they are emulated. On a build for -march=pentium and above the 64 bit functions use native instructions
/src/atomic/dummy/SDL_atomic.c emulates all the operations using SDL_mutex.h.
/src/atomic/win32/SDL_atomic.c is a copy of dummy
/src/atomic/macosx/SDL_atomic.s is a copy of dummy

These versions of SDL_atomic.c provide a frame work for building the library with a mixture of native and emulated functions. This allows the whole library to be provided on all platforms. (I hope.)
I hope this fits with the SDL philosophy of either providing a common subset or emulating when the platform is missing a feature.

I have not added dummy, macosx, or win32 to the build. They are there as place holders for future work.

I have modified congifure.in to compile sources in /src/atomic/linux. (The SDL configure.in file is an amazing piece of work and I hope I didn't mess it up. :-)
bob@3199
     1
/*
bob@3199
     2
    SDL - Simple DirectMedia Layer
bob@3199
     3
    Copyright (C) 1997-2009 Sam Lantinga
bob@3199
     4
bob@3199
     5
    This library is free software; you can redistribute it and/or
bob@3199
     6
    modify it under the terms of the GNU Lesser General Public
bob@3199
     7
    License as published by the Free Software Foundation; either
bob@3199
     8
    version 2.1 of the License, or (at your option) any later version.
bob@3199
     9
bob@3199
    10
    This library is distributed in the hope that it will be useful,
bob@3199
    11
    but WITHOUT ANY WARRANTY; without even the implied warranty of
bob@3199
    12
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
bob@3199
    13
    Lesser General Public License for more details.
bob@3199
    14
bob@3199
    15
    You should have received a copy of the GNU Lesser General Public
bob@3199
    16
    License along with this library; if not, write to the Free Software
bob@3199
    17
    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
bob@3199
    18
bob@3199
    19
    Sam Lantinga
bob@3199
    20
    slouken@libsdl.org
bob@3199
    21
*/
bob@3199
    22
bob@3202
    23
#include "SDL_stdinc.h"
bob@3202
    24
#include "SDL_atomic.h"
bob@3199
    25
bob@3202
    26
/*
bob@3202
    27
  This file provides 8, 16, 32, and 64 bit atomic operations. If the
bob@3202
    28
  operations are provided by the native hardware and operating system
bob@3202
    29
  they are used. If they are not then the operations are emulated
bob@3202
    30
  using the SDL mutex operations. 
bob@3202
    31
 */
bob@3202
    32
bob@3202
    33
/* 
bob@3202
    34
  First, detect whether the operations are supported and create
bob@3202
    35
  #defines that indicate that they do exist. The goal is to have all
bob@3202
    36
  the system dependent code in the top part of the file so that the
bob@3202
    37
  bottom can be use unchanged across all platforms.
bob@3202
    38
bob@3202
    39
  Second, #define all the operations in each size class that are
bob@3202
    40
  supported. Doing this allows supported operations to be used along
bob@3202
    41
  side of emulated operations.
bob@3202
    42
*/
bob@3202
    43
bob@3202
    44
/* 
bob@3202
    45
   Emmulated version.
bob@3202
    46
bob@3202
    47
   Assume there is no support for atomic operations. All such
bob@3202
    48
   operations are implemented using SDL mutex operations.
bob@3202
    49
 */
bob@3202
    50
bob@3202
    51
#ifdef EMULATED_ATOMIC_OPERATIONS
bob@3202
    52
#undef EMULATED_ATOMIC_OPERATIONS
bob@3202
    53
#endif
bob@3202
    54
bob@3202
    55
#ifdef EMULATED_ATOMIC_OPERATIONS
bob@3202
    56
#define HAVE_ALL_8_BIT_OPS
bob@3202
    57
bob@3202
    58
#define nativeExchange8(ptr, value)			()
bob@3202
    59
#define nativeCompareThenSet8(ptr, oldvalue, newvalue) 	()
bob@3202
    60
#define nativeTestThenSet8(ptr)    	     		()
bob@3202
    61
#define nativeClear8(ptr)				()
bob@3202
    62
#define nativeFetchThenIncrement8(ptr)   		()
bob@3202
    63
#define nativeFetchThenDecrement8(ptr) 			()
bob@3202
    64
#define nativeFetchThenAdd8(ptr, value) 		()
bob@3202
    65
#define nativeFetchThenSubtract8(ptr, value) 		()
bob@3202
    66
#define nativeIncrementThenFetch8(ptr) 			()
bob@3202
    67
#define nativeDecrementThenFetch8(ptr) 			()
bob@3202
    68
#define nativeAddThenFetch8(ptr, value) 		()
bob@3202
    69
#define nativeSubtractThenFetch8(ptr, value) 		()
bob@3202
    70
#endif
bob@3202
    71
bob@3202
    72
#ifdef EMULATED_ATOMIC_OPERATIONS
bob@3202
    73
#define HAVE_ALL_16_BIT_OPS
bob@3202
    74
bob@3202
    75
#define nativeExchange16(ptr, value)			()
bob@3202
    76
#define nativeCompareThenSet16(ptr, oldvalue, newvalue) ()
bob@3202
    77
#define nativeTestThenSet16(ptr)    	     		()
bob@3202
    78
#define nativeClear16(ptr)				()
bob@3202
    79
#define nativeFetchThenIncrement16(ptr)   		()
bob@3202
    80
#define nativeFetchThenDecrement16(ptr) 		()
bob@3202
    81
#define nativeFetchThenAdd16(ptr, value) 		()
bob@3202
    82
#define nativeFetchThenSubtract16(ptr, value) 		()
bob@3202
    83
#define nativeIncrementThenFetch16(ptr) 		()
bob@3202
    84
#define nativeDecrementThenFetch16(ptr) 		()
bob@3202
    85
#define nativeAddThenFetch16(ptr, value) 		()
bob@3202
    86
#define nativeSubtractThenFetch16(ptr, value) 		()
bob@3202
    87
#endif
bob@3202
    88
bob@3202
    89
#ifdef EMULATED_ATOMIC_OPERATIONS
bob@3202
    90
#define HAVE_ALL_32_BIT_OPS
bob@3202
    91
bob@3202
    92
#define nativeExchange32(ptr, value)			()
bob@3202
    93
#define nativeCompareThenSet32(ptr, oldvalue, newvalue) ()
bob@3202
    94
#define nativeTestThenSet32(ptr)    	     		()
bob@3202
    95
#define nativeClear32(ptr)				()
bob@3202
    96
#define nativeFetchThenIncrement32(ptr)   		()
bob@3202
    97
#define nativeFetchThenDecrement32(ptr) 		()
bob@3202
    98
#define nativeFetchThenAdd32(ptr, value) 		()
bob@3202
    99
#define nativeFetchThenSubtract32(ptr, value) 		()
bob@3202
   100
#define nativeIncrementThenFetch32(ptr) 		()
bob@3202
   101
#define nativeDecrementThenFetch32(ptr) 		()
bob@3202
   102
#define nativeAddThenFetch32(ptr, value) 		()
bob@3202
   103
#define nativeSubtractThenFetch32(ptr, value) 		()
bob@3202
   104
#endif
bob@3202
   105
bob@3202
   106
#ifdef EMULATED_ATOMIC_OPERATIONS
bob@3202
   107
#define HAVE_ALL_64_BIT_OPS
bob@3202
   108
bob@3202
   109
#define nativeExchange64(ptr, value)			()
bob@3202
   110
#define nativeCompareThenSet64(ptr, oldvalue, newvalue) ()
bob@3202
   111
#define nativeTestThenSet64(ptr)    	     		()
bob@3202
   112
#define nativeClear64(ptr)				()
bob@3202
   113
#define nativeFetchThenIncrement64(ptr)   		()
bob@3202
   114
#define nativeFetchThenDecrement64(ptr) 		()
bob@3202
   115
#define nativeFetchThenAdd64(ptr, value) 		()
bob@3202
   116
#define nativeFetchThenSubtract64(ptr, value) 		()
bob@3202
   117
#define nativeIncrementThenFetch64(ptr) 		()
bob@3202
   118
#define nativeDecrementThenFetch64(ptr) 		()
bob@3202
   119
#define nativeAddThenFetch64(ptr, value) 		()
bob@3202
   120
#define nativeSubtractThenFetch64(ptr, value) 		()
bob@3202
   121
#endif
bob@3202
   122
bob@3202
   123
/* 
bob@3202
   124
If any of the operations are not provided then we must emulate some of
bob@3202
   125
them.
bob@3202
   126
 */
bob@3202
   127
bob@3202
   128
#if !defined(HAVE_ALL_8_BIT_OPS) || !defined(HAVE_ALL_16_BIT_OPS) || !defined(HAVE_ALL_32_BIT_OPS) || !defined(HAVE_ALL_64_BIT_OPS)
bob@3202
   129
bob@3202
   130
#include "SDL_mutex.h"
bob@3202
   131
#include "SDL_error.h"
bob@3202
   132
bob@3202
   133
static SDL_mutex * lock = NULL;
bob@3202
   134
bob@3202
   135
static __inline__ void
bob@3202
   136
privateWaitLock()
bob@3202
   137
{
bob@3202
   138
   if(NULL == lock)
bob@3202
   139
   {
bob@3202
   140
      lock = SDL_CreateMutex();
bob@3202
   141
      if (NULL == lock)
bob@3202
   142
      {
bob@3202
   143
	 SDL_SetError("SDL_atomic.c: can't create a mutex");
bob@3202
   144
	 return;
bob@3202
   145
      }
bob@3202
   146
   }
bob@3202
   147
bob@3202
   148
   if (-1 == SDL_LockMutex(lock))
bob@3202
   149
   {
bob@3202
   150
      SDL_SetError("SDL_atomic.c: can't lock mutex");
bob@3202
   151
   }
bob@3202
   152
}
bob@3202
   153
bob@3202
   154
static __inline__ void
bob@3202
   155
privateUnlock()
bob@3202
   156
{
bob@3202
   157
   if (-1 == SDL_UnlockMutex(lock))
bob@3202
   158
   {
bob@3202
   159
      SDL_SetError("SDL_atomic.c: can't unlock mutex");
bob@3202
   160
   }
bob@3202
   161
}
bob@3202
   162
bob@3202
   163
#endif
bob@3202
   164
bob@3202
   165
/* 8 bit atomic operations */
bob@3202
   166
bob@3202
   167
Uint8
bob@3202
   168
SDL_AtomicExchange8(Uint8 * ptr, Uint8 value)
bob@3202
   169
{
bob@3202
   170
#ifdef nativeExchange8
bob@3202
   171
   return nativeExchange8(ptr, value);
bob@3202
   172
#else
bob@3202
   173
   Uint8 tmp = 0;;
bob@3202
   174
bob@3202
   175
   privateWaitLock();
bob@3202
   176
   tmp = *ptr;
bob@3202
   177
   *ptr = value;
bob@3202
   178
   privateUnlock();
bob@3202
   179
bob@3202
   180
   return tmp;
bob@3202
   181
#endif
bob@3202
   182
}
bob@3202
   183
bob@3202
   184
SDL_bool
bob@3202
   185
SDL_AtomicCompareThenSet8(Uint8 * ptr, Uint8 oldvalue, Uint8 newvalue)
bob@3202
   186
{
bob@3202
   187
#ifdef nativeCompareThenSet8
bob@3202
   188
   return (SDL_bool)nativeCompareThenSet8(ptr, oldvalue, newvalue);
bob@3202
   189
#else
bob@3202
   190
   SDL_bool result = SDL_FALSE;
bob@3202
   191
bob@3202
   192
   privateWaitLock();
bob@3202
   193
   result = (*ptr == oldvalue);
bob@3202
   194
   if (result)
bob@3202
   195
   {
bob@3202
   196
      *ptr = newvalue;
bob@3202
   197
   }
bob@3202
   198
   privateUnlock();
bob@3202
   199
bob@3202
   200
   return result;
bob@3202
   201
#endif
bob@3202
   202
}
bob@3202
   203
bob@3202
   204
SDL_bool
bob@3202
   205
SDL_AtomicTestThenSet8(Uint8 * ptr)
bob@3202
   206
{
bob@3202
   207
#ifdef nativeTestThenSet8
bob@3202
   208
   return (SDL_bool)nativeTestThenSet8(ptr);
bob@3202
   209
#else
bob@3202
   210
   SDL_bool result = SDL_FALSE;
bob@3202
   211
bob@3202
   212
   privateWaitLock();
bob@3202
   213
   result = (*ptr == 0);
bob@3202
   214
   if (result)
bob@3202
   215
   {
bob@3202
   216
      *ptr = 1;
bob@3202
   217
   }
bob@3202
   218
   privateUnlock();
bob@3202
   219
bob@3202
   220
   return result;
bob@3202
   221
#endif
bob@3202
   222
}
bob@3202
   223
bob@3202
   224
void
bob@3202
   225
SDL_AtomicClear8(Uint8 * ptr)
bob@3202
   226
{
bob@3202
   227
#ifdef nativeClear8
bob@3202
   228
   nativeClear8(ptr);
bob@3202
   229
#else
bob@3202
   230
   privateWaitLock();
bob@3202
   231
   *ptr = 0;
bob@3202
   232
   privateUnlock();
bob@3202
   233
bob@3202
   234
   return;
bob@3202
   235
#endif
bob@3202
   236
}
bob@3202
   237
bob@3202
   238
Uint8
bob@3202
   239
SDL_AtomicFetchThenIncrement8(Uint8 * ptr)
bob@3202
   240
{
bob@3202
   241
#ifdef nativeFetchThenIncrement8
bob@3202
   242
   return nativeFetchThenIncrement8(ptr);
bob@3202
   243
#else
bob@3202
   244
   Uint8 tmp = 0;;
bob@3202
   245
bob@3202
   246
   privateWaitLock();
bob@3202
   247
   tmp = *ptr;
bob@3202
   248
   (*ptr)+= 1;
bob@3202
   249
   privateUnlock();
bob@3202
   250
bob@3202
   251
   return tmp;
bob@3202
   252
#endif
bob@3202
   253
}
bob@3202
   254
bob@3202
   255
Uint8
bob@3202
   256
SDL_AtomicFetchThenDecrement8(Uint8 * ptr)
bob@3202
   257
{
bob@3202
   258
#ifdef nativeFetchThenDecrement8
bob@3202
   259
   return nativeFetchThenDecrement8(ptr);
bob@3202
   260
#else
bob@3202
   261
   Uint8 tmp = 0;;
bob@3202
   262
bob@3202
   263
   privateWaitLock();
bob@3202
   264
   tmp = *ptr;
bob@3202
   265
   (*ptr) -= 1;
bob@3202
   266
   privateUnlock();
bob@3202
   267
bob@3202
   268
   return tmp;
bob@3202
   269
#endif
bob@3202
   270
}
bob@3202
   271
bob@3202
   272
Uint8
bob@3202
   273
SDL_AtomicFetchThenAdd8(Uint8 * ptr, Uint8 value)
bob@3202
   274
{
bob@3202
   275
#ifdef nativeFetchThenAdd8
bob@3202
   276
   return nativeFetchThenAdd8(ptr, value);
bob@3202
   277
#else
bob@3202
   278
   Uint8 tmp = 0;;
bob@3202
   279
bob@3202
   280
   privateWaitLock();
bob@3202
   281
   tmp = *ptr;
bob@3202
   282
   (*ptr)+= value;
bob@3202
   283
   privateUnlock();
bob@3202
   284
bob@3202
   285
   return tmp;
bob@3202
   286
#endif
bob@3202
   287
}
bob@3202
   288
bob@3202
   289
Uint8
bob@3202
   290
SDL_AtomicFetchThenSubtract8(Uint8 * ptr, Uint8 value)
bob@3202
   291
{
bob@3202
   292
#ifdef nativeFetchThenSubtract8
bob@3202
   293
   return nativeFetchThenSubtract8(ptr, value);
bob@3202
   294
#else
bob@3202
   295
   Uint8 tmp = 0;;
bob@3202
   296
bob@3202
   297
   privateWaitLock();
bob@3202
   298
   tmp = *ptr;
bob@3202
   299
   (*ptr)-= value;
bob@3202
   300
   privateUnlock();
bob@3202
   301
bob@3202
   302
   return tmp;
bob@3202
   303
#endif
bob@3202
   304
}
bob@3202
   305
bob@3202
   306
Uint8
bob@3202
   307
SDL_AtomicIncrementThenFetch8(Uint8 * ptr)
bob@3202
   308
{
bob@3202
   309
#ifdef nativeIncrementThenFetch8
bob@3202
   310
   return nativeIncrementThenFetch8(ptr);
bob@3202
   311
#else
bob@3202
   312
   Uint8 tmp = 0;;
bob@3202
   313
bob@3202
   314
   privateWaitLock();
bob@3202
   315
   (*ptr)+= 1;
bob@3202
   316
   tmp = *ptr;
bob@3202
   317
   privateUnlock();
bob@3202
   318
bob@3202
   319
   return tmp;
bob@3202
   320
#endif
bob@3202
   321
}
bob@3202
   322
bob@3202
   323
Uint8
bob@3202
   324
SDL_AtomicDecrementThenFetch8(Uint8 * ptr)
bob@3202
   325
{
bob@3202
   326
#ifdef nativeDecrementThenFetch8
bob@3202
   327
   return nativeDecrementThenFetch8(ptr);
bob@3202
   328
#else
bob@3202
   329
   Uint8 tmp = 0;;
bob@3202
   330
bob@3202
   331
   privateWaitLock();
bob@3202
   332
   (*ptr)-= 1;
bob@3202
   333
   tmp = *ptr;
bob@3202
   334
   privateUnlock();
bob@3202
   335
bob@3202
   336
   return tmp;
bob@3202
   337
#endif
bob@3202
   338
}
bob@3202
   339
bob@3202
   340
Uint8
bob@3202
   341
SDL_AtomicAddThenFetch8(Uint8 * ptr, Uint8 value)
bob@3202
   342
{
bob@3202
   343
#ifdef nativeAddThenFetch8
bob@3202
   344
   return nativeAddThenFetch8(ptr, value);
bob@3202
   345
#else
bob@3202
   346
   Uint8 tmp = 0;;
bob@3202
   347
bob@3202
   348
   privateWaitLock();
bob@3202
   349
   (*ptr)+= value;
bob@3202
   350
   tmp = *ptr;
bob@3202
   351
   privateUnlock();
bob@3202
   352
bob@3202
   353
   return tmp;
bob@3202
   354
#endif
bob@3202
   355
}
bob@3202
   356
bob@3202
   357
Uint8
bob@3202
   358
SDL_AtomicSubtractThenFetch8(Uint8 * ptr, Uint8 value)
bob@3202
   359
{
bob@3202
   360
#ifdef nativeSubtractThenFetch8
bob@3202
   361
   return nativeSubtractThenFetch8(ptr, value);
bob@3202
   362
#else
bob@3202
   363
   Uint8 tmp = 0;;
bob@3202
   364
bob@3202
   365
   privateWaitLock();
bob@3202
   366
   (*ptr)-= value;
bob@3202
   367
   tmp = *ptr;
bob@3202
   368
   privateUnlock();
bob@3202
   369
bob@3202
   370
   return tmp;
bob@3202
   371
#endif
bob@3202
   372
}
bob@3202
   373
bob@3202
   374
/* 16 bit atomic operations */
bob@3202
   375
bob@3202
   376
Uint16
bob@3202
   377
SDL_AtomicExchange16(Uint16 * ptr, Uint16 value)
bob@3202
   378
{
bob@3202
   379
#ifdef nativeExchange16
bob@3202
   380
   return nativeExchange16(ptr, value);
bob@3202
   381
#else
bob@3202
   382
   Uint16 tmp = 0;;
bob@3202
   383
bob@3202
   384
   privateWaitLock();
bob@3202
   385
   tmp = *ptr;
bob@3202
   386
   *ptr = value;
bob@3202
   387
   privateUnlock();
bob@3202
   388
bob@3202
   389
   return tmp;
bob@3202
   390
#endif
bob@3202
   391
}
bob@3202
   392
bob@3202
   393
SDL_bool
bob@3202
   394
SDL_AtomicCompareThenSet16(Uint16 * ptr, Uint16 oldvalue, Uint16 newvalue)
bob@3202
   395
{
bob@3202
   396
#ifdef nativeCompareThenSet16
bob@3202
   397
   return (SDL_bool)nativeCompareThenSet16(ptr, oldvalue, newvalue);
bob@3202
   398
#else
bob@3202
   399
   SDL_bool result = SDL_FALSE;
bob@3202
   400
bob@3202
   401
   privateWaitLock();
bob@3202
   402
   result = (*ptr == oldvalue);
bob@3202
   403
   if (result)
bob@3202
   404
   {
bob@3202
   405
      *ptr = newvalue;
bob@3202
   406
   }
bob@3202
   407
   privateUnlock();
bob@3202
   408
bob@3202
   409
   return result;
bob@3202
   410
#endif
bob@3202
   411
}
bob@3202
   412
bob@3202
   413
SDL_bool
bob@3202
   414
SDL_AtomicTestThenSet16(Uint16 * ptr)
bob@3202
   415
{
bob@3202
   416
#ifdef nativeTestThenSet16
bob@3202
   417
   return (SDL_bool)nativeTestThenSet16(ptr);
bob@3202
   418
#else
bob@3202
   419
   SDL_bool result = SDL_FALSE;
bob@3202
   420
bob@3202
   421
   privateWaitLock();
bob@3202
   422
   result = (*ptr == 0);
bob@3202
   423
   if (result)
bob@3202
   424
   {
bob@3202
   425
      *ptr = 1;
bob@3202
   426
   }
bob@3202
   427
   privateUnlock();
bob@3202
   428
bob@3202
   429
   return result;
bob@3202
   430
#endif
bob@3202
   431
}
bob@3202
   432
bob@3202
   433
void
bob@3202
   434
SDL_AtomicClear16(Uint16 * ptr)
bob@3202
   435
{
bob@3202
   436
#ifdef nativeClear16
bob@3202
   437
   nativeClear16(ptr);
bob@3202
   438
#else
bob@3202
   439
   privateWaitLock();
bob@3202
   440
   *ptr = 0;
bob@3202
   441
   privateUnlock();
bob@3202
   442
bob@3202
   443
   return;
bob@3202
   444
#endif
bob@3202
   445
}
bob@3202
   446
bob@3202
   447
Uint16
bob@3202
   448
SDL_AtomicFetchThenIncrement16(Uint16 * ptr)
bob@3202
   449
{
bob@3202
   450
#ifdef nativeFetchThenIncrement16
bob@3202
   451
   return nativeFetchThenIncrement16(ptr);
bob@3202
   452
#else
bob@3202
   453
   Uint16 tmp = 0;;
bob@3202
   454
bob@3202
   455
   privateWaitLock();
bob@3202
   456
   tmp = *ptr;
bob@3202
   457
   (*ptr)+= 1;
bob@3202
   458
   privateUnlock();
bob@3202
   459
bob@3202
   460
   return tmp;
bob@3202
   461
#endif
bob@3202
   462
}
bob@3202
   463
bob@3202
   464
Uint16
bob@3202
   465
SDL_AtomicFetchThenDecrement16(Uint16 * ptr)
bob@3202
   466
{
bob@3202
   467
#ifdef nativeFetchThenDecrement16
bob@3202
   468
   return nativeFetchThenDecrement16(ptr);
bob@3202
   469
#else
bob@3202
   470
   Uint16 tmp = 0;;
bob@3202
   471
bob@3202
   472
   privateWaitLock();
bob@3202
   473
   tmp = *ptr;
bob@3202
   474
   (*ptr) -= 1;
bob@3202
   475
   privateUnlock();
bob@3202
   476
bob@3202
   477
   return tmp;
bob@3202
   478
#endif
bob@3202
   479
}
bob@3202
   480
bob@3202
   481
Uint16
bob@3202
   482
SDL_AtomicFetchThenAdd16(Uint16 * ptr, Uint16 value)
bob@3202
   483
{
bob@3202
   484
#ifdef nativeFetchThenAdd16
bob@3202
   485
   return nativeFetchThenAdd16(ptr, value);
bob@3202
   486
#else
bob@3202
   487
   Uint16 tmp = 0;;
bob@3202
   488
bob@3202
   489
   privateWaitLock();
bob@3202
   490
   tmp = *ptr;
bob@3202
   491
   (*ptr)+= value;
bob@3202
   492
   privateUnlock();
bob@3202
   493
bob@3202
   494
   return tmp;
bob@3202
   495
#endif
bob@3202
   496
}
bob@3202
   497
bob@3202
   498
Uint16
bob@3202
   499
SDL_AtomicFetchThenSubtract16(Uint16 * ptr, Uint16 value)
bob@3202
   500
{
bob@3202
   501
#ifdef nativeFetchThenSubtract16
bob@3202
   502
   return nativeFetchThenSubtract16(ptr, value);
bob@3202
   503
#else
bob@3202
   504
   Uint16 tmp = 0;;
bob@3202
   505
bob@3202
   506
   privateWaitLock();
bob@3202
   507
   tmp = *ptr;
bob@3202
   508
   (*ptr)-= value;
bob@3202
   509
   privateUnlock();
bob@3202
   510
bob@3202
   511
   return tmp;
bob@3202
   512
#endif
bob@3202
   513
}
bob@3202
   514
bob@3202
   515
Uint16
bob@3202
   516
SDL_AtomicIncrementThenFetch16(Uint16 * ptr)
bob@3202
   517
{
bob@3202
   518
#ifdef nativeIncrementThenFetch16
bob@3202
   519
   return nativeIncrementThenFetch16(ptr);
bob@3202
   520
#else
bob@3202
   521
   Uint16 tmp = 0;;
bob@3202
   522
bob@3202
   523
   privateWaitLock();
bob@3202
   524
   (*ptr)+= 1;
bob@3202
   525
   tmp = *ptr;
bob@3202
   526
   privateUnlock();
bob@3202
   527
bob@3202
   528
   return tmp;
bob@3202
   529
#endif
bob@3202
   530
}
bob@3202
   531
bob@3202
   532
Uint16
bob@3202
   533
SDL_AtomicDecrementThenFetch16(Uint16 * ptr)
bob@3202
   534
{
bob@3202
   535
#ifdef nativeDecrementThenFetch16
bob@3202
   536
   return nativeDecrementThenFetch16(ptr);
bob@3202
   537
#else
bob@3202
   538
   Uint16 tmp = 0;;
bob@3202
   539
bob@3202
   540
   privateWaitLock();
bob@3202
   541
   (*ptr)-= 1;
bob@3202
   542
   tmp = *ptr;
bob@3202
   543
   privateUnlock();
bob@3202
   544
bob@3202
   545
   return tmp;
bob@3202
   546
#endif
bob@3202
   547
}
bob@3202
   548
bob@3202
   549
Uint16
bob@3202
   550
SDL_AtomicAddThenFetch16(Uint16 * ptr, Uint16 value)
bob@3202
   551
{
bob@3202
   552
#ifdef nativeAddThenFetch16
bob@3202
   553
   return nativeAddThenFetch16(ptr, value);
bob@3202
   554
#else
bob@3202
   555
   Uint16 tmp = 0;;
bob@3202
   556
bob@3202
   557
   privateWaitLock();
bob@3202
   558
   (*ptr)+= value;
bob@3202
   559
   tmp = *ptr;
bob@3202
   560
   privateUnlock();
bob@3202
   561
bob@3202
   562
   return tmp;
bob@3202
   563
#endif
bob@3202
   564
}
bob@3202
   565
bob@3202
   566
Uint16
bob@3202
   567
SDL_AtomicSubtractThenFetch16(Uint16 * ptr, Uint16 value)
bob@3202
   568
{
bob@3202
   569
#ifdef nativeSubtractThenFetch16
bob@3202
   570
   return nativeSubtractThenFetch16(ptr, value);
bob@3202
   571
#else
bob@3202
   572
   Uint16 tmp = 0;;
bob@3202
   573
bob@3202
   574
   privateWaitLock();
bob@3202
   575
   (*ptr)-= value;
bob@3202
   576
   tmp = *ptr;
bob@3202
   577
   privateUnlock();
bob@3202
   578
bob@3202
   579
   return tmp;
bob@3202
   580
#endif
bob@3202
   581
}
bob@3202
   582
bob@3202
   583
/* 32 bit atomic operations */
bob@3199
   584
bob@3199
   585
Uint32
bob@3199
   586
SDL_AtomicExchange32(Uint32 * ptr, Uint32 value)
bob@3199
   587
{
bob@3202
   588
#ifdef nativeExchange32
bob@3202
   589
   return nativeExchange32(ptr, value);
bob@3202
   590
#else
bob@3202
   591
   Uint32 tmp = 0;;
bob@3202
   592
bob@3202
   593
   privateWaitLock();
bob@3202
   594
   tmp = *ptr;
bob@3202
   595
   *ptr = value;
bob@3202
   596
   privateUnlock();
bob@3202
   597
bob@3202
   598
   return tmp;
bob@3202
   599
#endif
bob@3199
   600
}
bob@3199
   601
bob@3199
   602
SDL_bool
bob@3199
   603
SDL_AtomicCompareThenSet32(Uint32 * ptr, Uint32 oldvalue, Uint32 newvalue)
bob@3199
   604
{
bob@3202
   605
#ifdef nativeCompareThenSet32
bob@3202
   606
   return (SDL_bool)nativeCompareThenSet32(ptr, oldvalue, newvalue);
bob@3202
   607
#else
bob@3202
   608
   SDL_bool result = SDL_FALSE;
bob@3202
   609
bob@3202
   610
   privateWaitLock();
bob@3202
   611
   result = (*ptr == oldvalue);
bob@3202
   612
   if (result)
bob@3202
   613
   {
bob@3202
   614
      *ptr = newvalue;
bob@3202
   615
   }
bob@3202
   616
   privateUnlock();
bob@3202
   617
bob@3202
   618
   return result;
bob@3202
   619
#endif
bob@3199
   620
}
bob@3199
   621
bob@3199
   622
SDL_bool
bob@3199
   623
SDL_AtomicTestThenSet32(Uint32 * ptr)
bob@3199
   624
{
bob@3202
   625
#ifdef nativeTestThenSet32
bob@3202
   626
   return (SDL_bool)nativeTestThenSet32(ptr);
bob@3202
   627
#else
bob@3202
   628
   SDL_bool result = SDL_FALSE;
bob@3202
   629
bob@3202
   630
   privateWaitLock();
bob@3202
   631
   result = (*ptr == 0);
bob@3202
   632
   if (result)
bob@3202
   633
   {
bob@3202
   634
      *ptr = 1;
bob@3202
   635
   }
bob@3202
   636
   privateUnlock();
bob@3202
   637
bob@3202
   638
   return result;
bob@3202
   639
#endif
bob@3199
   640
}
bob@3199
   641
bob@3199
   642
void
bob@3199
   643
SDL_AtomicClear32(Uint32 * ptr)
bob@3199
   644
{
bob@3202
   645
#ifdef nativeClear32
bob@3202
   646
   nativeClear32(ptr);
bob@3202
   647
#else
bob@3202
   648
   privateWaitLock();
bob@3202
   649
   *ptr = 0;
bob@3202
   650
   privateUnlock();
bob@3202
   651
bob@3202
   652
   return;
bob@3202
   653
#endif
bob@3199
   654
}
bob@3199
   655
bob@3199
   656
Uint32
bob@3199
   657
SDL_AtomicFetchThenIncrement32(Uint32 * ptr)
bob@3199
   658
{
bob@3202
   659
#ifdef nativeFetchThenIncrement32
bob@3202
   660
   return nativeFetchThenIncrement32(ptr);
bob@3202
   661
#else
bob@3202
   662
   Uint32 tmp = 0;;
bob@3202
   663
bob@3202
   664
   privateWaitLock();
bob@3202
   665
   tmp = *ptr;
bob@3202
   666
   (*ptr)+= 1;
bob@3202
   667
   privateUnlock();
bob@3202
   668
bob@3202
   669
   return tmp;
bob@3202
   670
#endif
bob@3199
   671
}
bob@3199
   672
bob@3199
   673
Uint32
bob@3199
   674
SDL_AtomicFetchThenDecrement32(Uint32 * ptr)
bob@3199
   675
{
bob@3202
   676
#ifdef nativeFetchThenDecrement32
bob@3202
   677
   return nativeFetchThenDecrement32(ptr);
bob@3202
   678
#else
bob@3202
   679
   Uint32 tmp = 0;;
bob@3202
   680
bob@3202
   681
   privateWaitLock();
bob@3202
   682
   tmp = *ptr;
bob@3202
   683
   (*ptr) -= 1;
bob@3202
   684
   privateUnlock();
bob@3202
   685
bob@3202
   686
   return tmp;
bob@3202
   687
#endif
bob@3199
   688
}
bob@3199
   689
bob@3199
   690
Uint32
bob@3199
   691
SDL_AtomicFetchThenAdd32(Uint32 * ptr, Uint32 value)
bob@3199
   692
{
bob@3202
   693
#ifdef nativeFetchThenAdd32
bob@3202
   694
   return nativeFetchThenAdd32(ptr, value);
bob@3202
   695
#else
bob@3202
   696
   Uint32 tmp = 0;;
bob@3202
   697
bob@3202
   698
   privateWaitLock();
bob@3202
   699
   tmp = *ptr;
bob@3202
   700
   (*ptr)+= value;
bob@3202
   701
   privateUnlock();
bob@3202
   702
bob@3202
   703
   return tmp;
bob@3202
   704
#endif
bob@3199
   705
}
bob@3199
   706
bob@3199
   707
Uint32
bob@3199
   708
SDL_AtomicFetchThenSubtract32(Uint32 * ptr, Uint32 value)
bob@3199
   709
{
bob@3202
   710
#ifdef nativeFetchThenSubtract32
bob@3202
   711
   return nativeFetchThenSubtract32(ptr, value);
bob@3202
   712
#else
bob@3202
   713
   Uint32 tmp = 0;;
bob@3202
   714
bob@3202
   715
   privateWaitLock();
bob@3202
   716
   tmp = *ptr;
bob@3202
   717
   (*ptr)-= value;
bob@3202
   718
   privateUnlock();
bob@3202
   719
bob@3202
   720
   return tmp;
bob@3202
   721
#endif
bob@3199
   722
}
bob@3199
   723
bob@3199
   724
Uint32
bob@3199
   725
SDL_AtomicIncrementThenFetch32(Uint32 * ptr)
bob@3199
   726
{
bob@3202
   727
#ifdef nativeIncrementThenFetch32
bob@3202
   728
   return nativeIncrementThenFetch32(ptr);
bob@3202
   729
#else
bob@3202
   730
   Uint32 tmp = 0;;
bob@3202
   731
bob@3202
   732
   privateWaitLock();
bob@3202
   733
   (*ptr)+= 1;
bob@3202
   734
   tmp = *ptr;
bob@3202
   735
   privateUnlock();
bob@3202
   736
bob@3202
   737
   return tmp;
bob@3202
   738
#endif
bob@3199
   739
}
bob@3199
   740
bob@3199
   741
Uint32
bob@3199
   742
SDL_AtomicDecrementThenFetch32(Uint32 * ptr)
bob@3199
   743
{
bob@3202
   744
#ifdef nativeDecrementThenFetch32
bob@3202
   745
   return nativeDecrementThenFetch32(ptr);
bob@3202
   746
#else
bob@3202
   747
   Uint32 tmp = 0;;
bob@3202
   748
bob@3202
   749
   privateWaitLock();
bob@3202
   750
   (*ptr)-= 1;
bob@3202
   751
   tmp = *ptr;
bob@3202
   752
   privateUnlock();
bob@3202
   753
bob@3202
   754
   return tmp;
bob@3202
   755
#endif
bob@3199
   756
}
bob@3199
   757
bob@3199
   758
Uint32
bob@3199
   759
SDL_AtomicAddThenFetch32(Uint32 * ptr, Uint32 value)
bob@3199
   760
{
bob@3202
   761
#ifdef nativeAddThenFetch32
bob@3202
   762
   return nativeAddThenFetch32(ptr, value);
bob@3202
   763
#else
bob@3202
   764
   Uint32 tmp = 0;;
bob@3202
   765
bob@3202
   766
   privateWaitLock();
bob@3202
   767
   (*ptr)+= value;
bob@3202
   768
   tmp = *ptr;
bob@3202
   769
   privateUnlock();
bob@3202
   770
bob@3202
   771
   return tmp;
bob@3202
   772
#endif
bob@3199
   773
}
bob@3199
   774
bob@3199
   775
Uint32
bob@3199
   776
SDL_AtomicSubtractThenFetch32(Uint32 * ptr, Uint32 value)
bob@3199
   777
{
bob@3202
   778
#ifdef nativeSubtractThenFetch32
bob@3202
   779
   return nativeSubtractThenFetch32(ptr, value);
bob@3202
   780
#else
bob@3202
   781
   Uint32 tmp = 0;;
bob@3202
   782
bob@3202
   783
   privateWaitLock();
bob@3202
   784
   (*ptr)-= value;
bob@3202
   785
   tmp = *ptr;
bob@3202
   786
   privateUnlock();
bob@3202
   787
bob@3202
   788
   return tmp;
bob@3202
   789
#endif
bob@3199
   790
}
bob@3199
   791
bob@3202
   792
/* 64 bit atomic operations */
bob@3199
   793
#ifdef SDL_HAS_64BIT_TYPE
bob@3199
   794
bob@3199
   795
Uint64
bob@3199
   796
SDL_AtomicExchange64(Uint64 * ptr, Uint64 value)
bob@3199
   797
{
bob@3202
   798
#ifdef nativeExchange64
bob@3202
   799
   return nativeExchange64(ptr, value);
bob@3202
   800
#else
bob@3202
   801
   Uint64 tmp = 0;;
bob@3202
   802
bob@3202
   803
   privateWaitLock();
bob@3202
   804
   tmp = *ptr;
bob@3202
   805
   *ptr = value;
bob@3202
   806
   privateUnlock();
bob@3202
   807
bob@3202
   808
   return tmp;
bob@3202
   809
#endif
bob@3199
   810
}
bob@3199
   811
bob@3199
   812
SDL_bool
bob@3202
   813
SDL_AtomicCompareThenSet64(Uint64 * ptr, Uint64 oldvalue, Uint64 newvalue)
bob@3199
   814
{
bob@3202
   815
#ifdef nativeCompareThenSet64
bob@3202
   816
   return (SDL_bool)nativeCompareThenSet64(ptr, oldvalue, newvalue);
bob@3202
   817
#else
bob@3202
   818
   SDL_bool result = SDL_FALSE;
bob@3202
   819
bob@3202
   820
   privateWaitLock();
bob@3202
   821
   result = (*ptr == oldvalue);
bob@3202
   822
   if (result)
bob@3202
   823
   {
bob@3202
   824
      *ptr = newvalue;
bob@3202
   825
   }
bob@3202
   826
   privateUnlock();
bob@3202
   827
bob@3202
   828
   return result;
bob@3202
   829
#endif
bob@3199
   830
}
bob@3199
   831
bob@3199
   832
SDL_bool
bob@3199
   833
SDL_AtomicTestThenSet64(Uint64 * ptr)
bob@3199
   834
{
bob@3202
   835
#ifdef nativeTestThenSet64
bob@3202
   836
   return (SDL_bool)nativeTestThenSet64(ptr);
bob@3202
   837
#else
bob@3202
   838
   SDL_bool result = SDL_FALSE;
bob@3202
   839
bob@3202
   840
   privateWaitLock();
bob@3202
   841
   result = (*ptr == 0);
bob@3202
   842
   if (result)
bob@3202
   843
   {
bob@3202
   844
      *ptr = 1;
bob@3202
   845
   }
bob@3202
   846
   privateUnlock();
bob@3202
   847
bob@3202
   848
   return result;
bob@3202
   849
#endif
bob@3199
   850
}
bob@3199
   851
bob@3199
   852
void
bob@3199
   853
SDL_AtomicClear64(Uint64 * ptr)
bob@3199
   854
{
bob@3202
   855
#ifdef nativeClear64
bob@3202
   856
   nativeClear64(ptr);
bob@3202
   857
#else
bob@3202
   858
   privateWaitLock();
bob@3202
   859
   *ptr = 0;
bob@3202
   860
   privateUnlock();
bob@3202
   861
bob@3202
   862
   return;
bob@3202
   863
#endif
bob@3199
   864
}
bob@3199
   865
bob@3199
   866
Uint64
bob@3199
   867
SDL_AtomicFetchThenIncrement64(Uint64 * ptr)
bob@3199
   868
{
bob@3202
   869
#ifdef nativeFetchThenIncrement64
bob@3202
   870
   return nativeFetchThenIncrement64(ptr);
bob@3202
   871
#else
bob@3202
   872
   Uint64 tmp = 0;;
bob@3202
   873
bob@3202
   874
   privateWaitLock();
bob@3202
   875
   tmp = *ptr;
bob@3202
   876
   (*ptr)+= 1;
bob@3202
   877
   privateUnlock();
bob@3202
   878
bob@3202
   879
   return tmp;
bob@3202
   880
#endif
bob@3199
   881
}
bob@3199
   882
bob@3199
   883
Uint64
bob@3199
   884
SDL_AtomicFetchThenDecrement64(Uint64 * ptr)
bob@3199
   885
{
bob@3202
   886
#ifdef nativeFetchThenDecrement64
bob@3202
   887
   return nativeFetchThenDecrement64(ptr);
bob@3202
   888
#else
bob@3202
   889
   Uint64 tmp = 0;;
bob@3202
   890
bob@3202
   891
   privateWaitLock();
bob@3202
   892
   tmp = *ptr;
bob@3202
   893
   (*ptr) -= 1;
bob@3202
   894
   privateUnlock();
bob@3202
   895
bob@3202
   896
   return tmp;
bob@3202
   897
#endif
bob@3199
   898
}
bob@3199
   899
bob@3199
   900
Uint64
bob@3199
   901
SDL_AtomicFetchThenAdd64(Uint64 * ptr, Uint64 value)
bob@3199
   902
{
bob@3202
   903
#ifdef nativeFetchThenAdd64
bob@3202
   904
   return nativeFetchThenAdd64(ptr, value);
bob@3202
   905
#else
bob@3202
   906
   Uint64 tmp = 0;;
bob@3202
   907
bob@3202
   908
   privateWaitLock();
bob@3202
   909
   tmp = *ptr;
bob@3202
   910
   (*ptr)+= value;
bob@3202
   911
   privateUnlock();
bob@3202
   912
bob@3202
   913
   return tmp;
bob@3202
   914
#endif
bob@3199
   915
}
bob@3199
   916
bob@3199
   917
Uint64
bob@3199
   918
SDL_AtomicFetchThenSubtract64(Uint64 * ptr, Uint64 value)
bob@3199
   919
{
bob@3202
   920
#ifdef nativeFetchThenSubtract64
bob@3202
   921
   return nativeFetchThenSubtract64(ptr, value);
bob@3202
   922
#else
bob@3202
   923
   Uint64 tmp = 0;;
bob@3202
   924
bob@3202
   925
   privateWaitLock();
bob@3202
   926
   tmp = *ptr;
bob@3202
   927
   (*ptr)-= value;
bob@3202
   928
   privateUnlock();
bob@3202
   929
bob@3202
   930
   return tmp;
bob@3202
   931
#endif
bob@3199
   932
}
bob@3199
   933
bob@3199
   934
Uint64
bob@3199
   935
SDL_AtomicIncrementThenFetch64(Uint64 * ptr)
bob@3199
   936
{
bob@3202
   937
#ifdef nativeIncrementThenFetch64
bob@3202
   938
   return nativeIncrementThenFetch64(ptr);
bob@3202
   939
#else
bob@3202
   940
   Uint64 tmp = 0;;
bob@3202
   941
bob@3202
   942
   privateWaitLock();
bob@3202
   943
   (*ptr)+= 1;
bob@3202
   944
   tmp = *ptr;
bob@3202
   945
   privateUnlock();
bob@3202
   946
bob@3202
   947
   return tmp;
bob@3202
   948
#endif
bob@3199
   949
}
bob@3199
   950
bob@3199
   951
Uint64
bob@3199
   952
SDL_AtomicDecrementThenFetch64(Uint64 * ptr)
bob@3199
   953
{
bob@3202
   954
#ifdef nativeDecrementThenFetch64
bob@3202
   955
   return nativeDecrementThenFetch64(ptr);
bob@3202
   956
#else
bob@3202
   957
   Uint64 tmp = 0;;
bob@3202
   958
bob@3202
   959
   privateWaitLock();
bob@3202
   960
   (*ptr)-= 1;
bob@3202
   961
   tmp = *ptr;
bob@3202
   962
   privateUnlock();
bob@3202
   963
bob@3202
   964
   return tmp;
bob@3202
   965
#endif
bob@3199
   966
}
bob@3199
   967
bob@3199
   968
Uint64
bob@3199
   969
SDL_AtomicAddThenFetch64(Uint64 * ptr, Uint64 value)
bob@3199
   970
{
bob@3202
   971
#ifdef nativeAddThenFetch64
bob@3202
   972
   return nativeAddThenFetch64(ptr, value);
bob@3202
   973
#else
bob@3202
   974
   Uint64 tmp = 0;;
bob@3202
   975
bob@3202
   976
   privateWaitLock();
bob@3202
   977
   (*ptr)+= value;
bob@3202
   978
   tmp = *ptr;
bob@3202
   979
   privateUnlock();
bob@3202
   980
bob@3202
   981
   return tmp;
bob@3202
   982
#endif
bob@3199
   983
}
bob@3199
   984
bob@3199
   985
Uint64
bob@3199
   986
SDL_AtomicSubtractThenFetch64(Uint64 * ptr, Uint64 value)
bob@3199
   987
{
bob@3202
   988
#ifdef nativeSubtractThenFetch64
bob@3202
   989
   return nativeSubtractThenFetch64(ptr, value);
bob@3202
   990
#else
bob@3202
   991
   Uint64 tmp = 0;;
bob@3202
   992
bob@3202
   993
   privateWaitLock();
bob@3202
   994
   (*ptr)-= value;
bob@3202
   995
   tmp = *ptr;
bob@3202
   996
   privateUnlock();
bob@3202
   997
bob@3202
   998
   return tmp;
bob@3202
   999
#endif
bob@3199
  1000
}
bob@3202
  1001
#endif
bob@3199
  1002