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