First commit for SDL atomic operations.
authorBob Pendleton <bob@pendleton.com>
Tue, 09 Jun 2009 17:33:44 +0000
changeset 318077d6336711fc
parent 3179 9b34679fda8b
child 3181 030899df1af5
First commit for SDL atomic operations.
On my linux box it compiles and installs correctly and testatomic runs without errors.
Makefile.in
configure.in
include/SDL.h
include/SDL_atomic.h
include/SDL_config.h.in
include/SDL_config_dreamcast.h
include/SDL_config_macosx.h
include/SDL_config_os2.h
include/SDL_config_win32.h
test/Makefile.in
test/testatomic.c
     1.1 --- a/Makefile.in	Tue Jun 09 15:45:33 2009 +0000
     1.2 +++ b/Makefile.in	Tue Jun 09 17:33:44 2009 +0000
     1.3 @@ -42,7 +42,7 @@
     1.4  
     1.5  DIST = acinclude.m4 autogen.sh Borland.html Borland.zip BUGS build-scripts configure configure.in COPYING CREDITS docs docs.html include INSTALL Makefile.dc Makefile.minimal Makefile.in README* sdl-config.in sdl.m4 sdl.pc.in SDL.qpg.in SDL.spec SDL.spec.in src test TODO VisualC.html VisualC VisualCE Watcom-OS2.zip Watcom-Win32.zip WhatsNew Xcode
     1.6  
     1.7 -HDRS = SDL.h SDL_audio.h SDL_cdrom.h SDL_compat.h SDL_cpuinfo.h SDL_endian.h SDL_error.h SDL_events.h SDL_haptic.h SDL_joystick.h SDL_keyboard.h SDL_keysym.h SDL_loadso.h SDL_main.h SDL_mouse.h SDL_mutex.h SDL_name.h SDL_opengl.h SDL_opengles.h SDL_pixels.h SDL_platform.h SDL_power.h SDL_quit.h SDL_rect.h SDL_revision.h SDL_rwops.h SDL_scancode.h SDL_stdinc.h SDL_surface.h SDL_syswm.h SDL_thread.h SDL_timer.h SDL_types.h SDL_version.h SDL_video.h begin_code.h close_code.h
     1.8 +HDRS = SDL.h SDL_atomic.h SDL_audio.h SDL_cdrom.h SDL_compat.h SDL_cpuinfo.h SDL_endian.h SDL_error.h SDL_events.h SDL_haptic.h SDL_joystick.h SDL_keyboard.h SDL_keysym.h SDL_loadso.h SDL_main.h SDL_mouse.h SDL_mutex.h SDL_name.h SDL_opengl.h SDL_opengles.h SDL_pixels.h SDL_platform.h SDL_power.h SDL_quit.h SDL_rect.h SDL_revision.h SDL_rwops.h SDL_scancode.h SDL_stdinc.h SDL_surface.h SDL_syswm.h SDL_thread.h SDL_timer.h SDL_types.h SDL_version.h SDL_video.h begin_code.h close_code.h
     1.9  
    1.10  LT_AGE      = @LT_AGE@
    1.11  LT_CURRENT  = @LT_CURRENT@
     2.1 --- a/configure.in	Tue Jun 09 15:45:33 2009 +0000
     2.2 +++ b/configure.in	Tue Jun 09 17:33:44 2009 +0000
     2.3 @@ -159,6 +159,7 @@
     2.4      AC_CHECK_FUNCS(iconv)
     2.5  fi
     2.6  
     2.7 +AC_CHECK_SIZEOF(void*)
     2.8  if test x$have_inttypes != xyes; then
     2.9      AC_CHECK_SIZEOF(char, 1)
    2.10      AC_CHECK_SIZEOF(short, 2)
     3.1 --- a/include/SDL.h	Tue Jun 09 15:45:33 2009 +0000
     3.2 +++ b/include/SDL.h	Tue Jun 09 17:33:44 2009 +0000
     3.3 @@ -76,6 +76,7 @@
     3.4  
     3.5  #include "SDL_main.h"
     3.6  #include "SDL_stdinc.h"
     3.7 +#include "SDL_atomic.h"
     3.8  #include "SDL_audio.h"
     3.9  #include "SDL_cdrom.h"
    3.10  #include "SDL_cpuinfo.h"
     4.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.2 +++ b/include/SDL_atomic.h	Tue Jun 09 17:33:44 2009 +0000
     4.3 @@ -0,0 +1,674 @@
     4.4 +/*
     4.5 +    SDL - Simple DirectMedia Layer
     4.6 +    Copyright (C) 1997-2006 Sam Lantinga
     4.7 +
     4.8 +    This library is free software; you can redistribute it and/or
     4.9 +    modify it under the terms of the GNU Lesser General Public
    4.10 +    License as published by the Free Software Foundation; either
    4.11 +    version 2.1 of the License, or (at your option) any later version.
    4.12 +
    4.13 +    This library is distributed in the hope that it will be useful,
    4.14 +    but WITHOUT ANY WARRANTY; without even the implied warranty of
    4.15 +    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    4.16 +    Lesser General Public License for more details.
    4.17 +
    4.18 +    You should have received a copy of the GNU Lesser General Public
    4.19 +    License along with this library; if not, write to the Free Software
    4.20 +    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
    4.21 +
    4.22 +    Sam Lantinga
    4.23 +    slouken@libsdl.org
    4.24 + */
    4.25 +
    4.26 +/**
    4.27 + * \file SDL_atomic.h
    4.28 + *
    4.29 + * Atomic int and pointer magic
    4.30 + */
    4.31 +
    4.32 +#ifndef _SDL_atomic_h_
    4.33 +#define _SDL_atomic_h_
    4.34 +
    4.35 +
    4.36 +#include "SDL_stdinc.h"
    4.37 +#include "SDL_platform.h"
    4.38 +
    4.39 +#include "begin_code.h"
    4.40 +
    4.41 +/* Set up for C function definitions, even when using C++ */
    4.42 +#ifdef __cplusplus
    4.43 +/* *INDENT-OFF* */
    4.44 +extern "C" {
    4.45 +/* *INDENT-ON* */
    4.46 +#endif
    4.47 +
    4.48 +#if defined(__GNUC__) && (defined(i386) || defined(__i386__)  || defined(__x86_64__))
    4.49 +static __inline__ void
    4.50 +SDL_atomic_int_add(volatile int* atomic, int value)
    4.51 +{
    4.52 +  __asm__ __volatile__("lock;"
    4.53 +                       "addl %1, %0"
    4.54 +                       : "=m" (*atomic)
    4.55 +                       : "ir" (value),
    4.56 +                         "m" (*atomic));
    4.57 +}
    4.58 +
    4.59 +static __inline__ int
    4.60 +SDL_atomic_int_xchg_add(volatile int* atomic, int value)
    4.61 +{                                              
    4.62 +  int rv;                                    
    4.63 +  __asm__ __volatile__("lock;"               
    4.64 +                       "xaddl %0, %1"        
    4.65 +                       : "=r" (rv),          
    4.66 +                         "=m" (*atomic)    
    4.67 +                       : "0" (value),        
    4.68 +                         "m" (*atomic));   
    4.69 +  return rv;                                        
    4.70 +}
    4.71 +
    4.72 +static __inline__ SDL_bool
    4.73 +SDL_atomic_int_cmp_xchg(volatile int* atomic, int oldvalue, int newvalue)
    4.74 +{
    4.75 +  int rv;                                                      
    4.76 +  __asm__ __volatile__("lock;"                               
    4.77 +                       "cmpxchgl %2, %1"                     
    4.78 +                       : "=a" (rv),                          
    4.79 +                         "=m" (*atomic)             
    4.80 +                       : "r" (newvalue),                     
    4.81 +                         "m" (*atomic),                    
    4.82 +                         "0" (oldvalue));
    4.83 +  return (rv == oldvalue);                                          
    4.84 +}
    4.85 +
    4.86 +static __inline__ SDL_bool
    4.87 +SDL_atomic_ptr_cmp_xchg(volatile void** atomic, void* oldvalue, void* newvalue)
    4.88 +{
    4.89 +  void* rv;
    4.90 +  __asm__ __volatile__("lock;"
    4.91 +# if defined(__x86_64__)                       
    4.92 +                       "cmpxchgq %q2, %1"
    4.93 +# else
    4.94 +                       "cmpxchgl %2, %1"
    4.95 +# endif                       
    4.96 +                       : "=a" (rv),
    4.97 +                         "=m" (*atomic)
    4.98 +                       : "r" (newvalue),
    4.99 +                         "m" (*atomic),
   4.100 +                         "0" (oldvalue));
   4.101 +  return (rv == oldvalue);
   4.102 +}
   4.103 +#elif defined(__GNUC__) && defined(__alpha__)
   4.104 +# define ATOMIC_MEMORY_BARRIER (__asm__ __volatile__ ("mb" : : : "memory"))
   4.105 +# define ATOMIC_INT_CMP_XCHG(atomic,value)              \
   4.106 +  ({                                                    \
   4.107 +    int rv,prev;                                        \
   4.108 +    __asm__ __volatile__("   mb\n"                      \
   4.109 +                         "1: ldl_l   %0,%2\n"           \
   4.110 +                         "   cmpeq   %0,%3,%1\n"        \
   4.111 +                         "   beq     %1,2f\n"           \
   4.112 +                         "   mov     %4,%1\n"           \
   4.113 +                         "   stl_c   %1,%2\n"           \
   4.114 +                         "   beq     %1,1b\n"           \
   4.115 +                         "   mb\n"                      \
   4.116 +                         "2:"                           \
   4.117 +                         : "=&r" (prev),                \
   4.118 +                           "=&r" (rv)                   \
   4.119 +                         : "m" (*(atomic)),             \
   4.120 +                           "Ir" (oldvalue),             \
   4.121 +                           "Ir" (newvalue)              \
   4.122 +                         : "memory");                   \
   4.123 +    (rv != 0);                                          \
   4.124 +  })
   4.125 +
   4.126 +# if (SIZEOF_VOIDP == 4)
   4.127 +static __inline__ SDL_bool
   4.128 +SDL_atomic_ptr_cmp_xchg(volatile void** atomic, void* oldvalue, void* newvalue)
   4.129 +{
   4.130 +  int rv;
   4.131 +  void* prev;
   4.132 +  __asm__ __volatile__("   mb\n"
   4.133 +                       "1: ldl_l %0,%2\n"
   4.134 +                       "   cmpeq %0,%3,%1\n"
   4.135 +                       "   beq   $1,2f\n"
   4.136 +                       "   mov   %4,%1\n"
   4.137 +                       "   stl_c %1,%2\n"
   4.138 +                       "   beq   %1,1b\n"
   4.139 +                       "   mb\n"
   4.140 +                       "2:"
   4.141 +                       : "=&r" (prev),
   4.142 +                         "=&r" (rv)
   4.143 +                       : "m" (*atomic),
   4.144 +                         "Ir" (oldvalue),
   4.145 +                         "Ir" (newvalue)
   4.146 +                       : "memory");
   4.147 +  return (rv != 0);
   4.148 +}
   4.149 +# elif (SIZEOF_VOIDP == 8)
   4.150 +static __inline__ SDL_bool
   4.151 +SDL_atomic_ptr_cmp_xchg(volatile void** atomic, void* oldvalue, void* newvalue)
   4.152 +{
   4.153 +  int rv;
   4.154 +  void* prev;
   4.155 +  __asm__ __volatile__("   mb\n"
   4.156 +                       "1: ldq_l %0,%2\n"
   4.157 +                       "   cmpeq %0,%3,%1\n"
   4.158 +                       "   beq   %1,2f\n"
   4.159 +                       "   mov   %4,%1\n"
   4.160 +                       "   stq_c %1,%2\n"
   4.161 +                       "   beq   %1,1b\n"
   4.162 +                       "   mb\n"
   4.163 +                       "2:"
   4.164 +                       : "=&r" (prev),
   4.165 +                         "=&r" (rv)
   4.166 +                       : "m" (*atomic),
   4.167 +                         "Ir" (oldvalue),
   4.168 +                         "Ir" (newvalue)
   4.169 +                       : "memory");
   4.170 +  return (rv != 0);
   4.171 +}
   4.172 +# else
   4.173 +#  error "Your system has an unsupported pointer size"  
   4.174 +# endif  /* SIZEOF_VOIDP */
   4.175 +#elif defined(__GNUC__) && defined(__sparc__)
   4.176 +# define ATOMIC_MEMORY_BARRIER                                          \
   4.177 +  (__asm__ __volatile__("membar #LoadLoad | #LoadStore"                 \
   4.178 +                        " | #StoreLoad | #StoreStore" : : : "memory"))
   4.179 +# define ATOMIC_INT_CMP_XCHG(atomic,oldvalue,newvalue)                  \
   4.180 +  ({                                                                    \
   4.181 +    int rv;                                                             \
   4.182 +    __asm__ __volatile__("cas [%4], %2, %0"                             \
   4.183 +                         : "=r" (rv), "=m" (*(atomic))                  \
   4.184 +                         : "r" (oldvalue), "m" (*(atomic)),             \
   4.185 +                         "r" (atomic), "0" (newvalue));                 \
   4.186 +    rv == oldvalue;                                                     \
   4.187 +  })
   4.188 +
   4.189 +# if (SIZEOF_VOIDP == 4)
   4.190 +static __inline__ SDL_bool
   4.191 +SDL_atomic_ptr_cmp_xchg(volatile void** atomic, void* oldvalue, void* newvalue)
   4.192 +{
   4.193 +  void* rv;
   4.194 +  __asm__ __volatile__("cas [%4], %2, %0"
   4.195 +                       : "=r" (rv),
   4.196 +                         "=m" (*atomic)
   4.197 +                       : "r" (oldvalue),
   4.198 +                         "m" (*atomic),
   4.199 +                         "r" (atomic),
   4.200 +                         "0" (newvalue));
   4.201 +  return (rv == oldvalue);
   4.202 +}
   4.203 +# elif (SIZEOF_VOIDP == 8)
   4.204 +static __inline__ SDL_bool
   4.205 +SDL_atomic_ptr_cmp_xchg(volatile void** atomic, void* oldvalue, void* newvalue)
   4.206 +{
   4.207 +  void* rv;
   4.208 +  void** a = atomic;
   4.209 +  __asm__ __volatile__("casx [%4], %2, %0"
   4.210 +                       : "=r" (rv),
   4.211 +                         "=m" (*a)
   4.212 +                       : "r" (oldvalue),
   4.213 +                         "m" (*a),
   4.214 +                         "r" (a),
   4.215 +                         "0" (newvalue));
   4.216 +  return (rv == oldvalue);
   4.217 +}
   4.218 +# else
   4.219 +#  error "Your system has an unsupported pointer size"
   4.220 +# endif /* SIZEOF_VOIDP */
   4.221 +#elif defined(__GNUC__) && (defined(__POWERPC__) || defined(__powerpc__) || defined(__ppc__) || defined(_M_PPC))
   4.222 +# define ATOMIC_MEMORY_BARRIER \
   4.223 +  (__asm__ __volatile__ ("sync" : : : "memory"))
   4.224 +static __inline__ void
   4.225 +SDL_atomic_int_add(volatile int* atomic, int value)
   4.226 +{                                           
   4.227 +  int rv,tmp;                                   
   4.228 +  __asm__ __volatile__("1: lwarx   %0,  0, %3\n" 
   4.229 +                       "   add     %1, %0, %4\n"
   4.230 +                       "   stwcx.  %1,  0, %3\n" 
   4.231 +                       "   bne-    1b"          
   4.232 +                       : "=&b" (rv),            
   4.233 +                         "=&r" (tmp),           
   4.234 +                         "=m" (*atomic)       
   4.235 +                       : "b" (atomic),          
   4.236 +                         "r" (value),           
   4.237 +                         "m" (*atomic)        
   4.238 +                       : "cr0",                 
   4.239 +                         "memory");             
   4.240 +}
   4.241 +
   4.242 +static __inline__ int
   4.243 +SDL_atomic_int_xchg_add(volatile int* atomic, int value)
   4.244 +{                                          
   4.245 +  int rv,tmp;                               
   4.246 +  __asm__ __volatile__("1: lwarx  %0, 0, %3\n"        
   4.247 +                       "   add    %1, %0, %4\n"       
   4.248 +                       "   stwcx. %1, 0, %3\n"        
   4.249 +                       "   bne-   1b"                 
   4.250 +                       : "=&b" (rv),                  
   4.251 +                         "=&r" (tmp),                 
   4.252 +                         "=m" (*atomic)
   4.253 +                       : "b" (atomic),                
   4.254 +                         "r" (value),                 
   4.255 +                         "m" (*atomic)
   4.256 +                       : "cr0",                       
   4.257 +                       "memory");                   
   4.258 +  return rv;                                                 
   4.259 +}
   4.260 +
   4.261 +# if (SIZEOF_VOIDP == 4)
   4.262 +static __inline__ SDL_bool
   4.263 +SDL_atomic_int_cmp_xchg(volatile int* atomic, int oldvalue, int newvalue)
   4.264 +{                                                        
   4.265 +  int rv;                                                 
   4.266 +  __asm__ __volatile__("   sync\n"                         
   4.267 +                       "1: lwarx   %0, 0, %1\n"           
   4.268 +                       "   subf.   %0, %2, %0\n"          
   4.269 +                       "   bne     2f\n"                  
   4.270 +                       "   stwcx.  %3, 0, %1\n"           
   4.271 +                       "   bne-    1b\n"                  
   4.272 +                       "2: isync"                         
   4.273 +                       : "=&r" (rv)                       
   4.274 +                       : "b" (atomic),                    
   4.275 +                         "r" (oldvalue),                  
   4.276 +                         "r"                              
   4.277 +                       : "cr0",                           
   4.278 +                         "memory");                         
   4.279 +  return (rv == 0);                                              
   4.280 +}
   4.281 +
   4.282 +static __inline__ SDL_bool
   4.283 +SDL_atomic_ptr_cmp_xchg(volatile void** atomic, void* oldvalue, void* newvalue)
   4.284 +{
   4.285 +  void* rv;
   4.286 +  __asm__ __volatile__("sync\n"
   4.287 +                       "1: lwarx  %0,  0, %1\n"
   4.288 +                       "   subf.  %0, %2, %0\n"
   4.289 +                       "   bne    2f\n"
   4.290 +                       "   stwcx. %3,  0, %1\n"
   4.291 +                       "   bne-   1b\n"
   4.292 +                       "2: isync"
   4.293 +                       : "=&r" (rv)
   4.294 +                       : "b" (atomic),
   4.295 +                         "r" (oldvalue),
   4.296 +                         "r" (newvalue)
   4.297 +                       : "cr0",
   4.298 +                       "memory");
   4.299 +  return (rv == 0);
   4.300 +}
   4.301 +# elif (SIZEOF_VOIDP == 8)
   4.302 +static __inline__ SDL_bool
   4.303 +SDL_atomic_int_cmp_xchg(volatile int* atomic, int oldvalue, int newvalue)
   4.304 +{                                                        
   4.305 +  int rv;                                                 
   4.306 +  __asm__ __volatile__("   sync\n"                         
   4.307 +                       "1: lwarx   %0,  0, %1\n"
   4.308 +                       "   extsw   %0, %0\n"
   4.309 +                       "   subf.   %0, %2, %0\n"          
   4.310 +                       "   bne     2f\n"                  
   4.311 +                       "   stwcx.  %3,  0, %1\n"           
   4.312 +                       "   bne-    1b\n"                  
   4.313 +                       "2: isync"                         
   4.314 +                       : "=&r" (rv)                       
   4.315 +                       : "b" (atomic),                    
   4.316 +                         "r" (oldvalue),                  
   4.317 +                         "r"                              
   4.318 +                       : "cr0",                           
   4.319 +                         "memory");                         
   4.320 +  return (rv == 0);                                              
   4.321 +}
   4.322 +
   4.323 +static __inline__ SDL_bool
   4.324 +SDL_atomic_ptr_cmp_xchg(volatile void** atomic, void* oldvalue, void* newvalue)
   4.325 +{
   4.326 +  void* rv;
   4.327 +  __asm__ __volatile__("sync\n"
   4.328 +                       "1: ldarx  %0,  0, %1\n"
   4.329 +                       "   subf.  %0, %2, %0\n"
   4.330 +                       "   bne    2f\n"
   4.331 +                       "   stdcx. %3,  0, %1\n"
   4.332 +                       "   bne-   1b\n"
   4.333 +                       "2: isync"
   4.334 +                       : "=&r" (rv)
   4.335 +                       : "b" (atomic),
   4.336 +                         "r" (oldvalue),
   4.337 +                         "r" (newvalue)
   4.338 +                       : "cr0",
   4.339 +                       "memory");
   4.340 +  return (rv == 0);
   4.341 +}
   4.342 +# else
   4.343 +#  error "Your system has an unsupported pointer size"
   4.344 +# endif /* SIZEOF_VOIDP */
   4.345 +#elif defined(__GNUC__) && (defined(__IA64__) || defined(__ia64__))
   4.346 +# define ATOMIC_MEMORY_BARRIER (__sync_synchronize())
   4.347 +# define SDL_atomic_int_xchg_add(atomic, value)     \
   4.348 +  (__sync_fetch_and_add((atomic),(value)))
   4.349 +# define SDL_atomic_int_add(atomic, value)                  \
   4.350 +  ((void)__sync_fetch_and_add((atomic),(value)))
   4.351 +# define SDL_atomic_int_cmp_xchg(atomic,oldvalue,newvalue)  \
   4.352 +  (__sync_bool_compare_and_swap((atomic),(oldvalue),(newvalue)))
   4.353 +# define SDL_atomic_ptr_cmp_xchg(atomic,oldvalue,newvalue)              \
   4.354 +  (__sync_bool_compare_and_swap((long*)(atomic),(long)(oldvalue),(long)(newvalue)))
   4.355 +#elif defined(__GNUC__) && defined(__LINUX__) && (defined(__mips__) || defined(__MIPS__))
   4.356 +static __inline__ int
   4.357 +SDL_atomic_int_xchg_add(volatile int* atomic, int value)
   4.358 +{                                            
   4.359 +  int rv,tmp;                                 
   4.360 +  __asm__ __volatile__("1:              \n"                 
   4.361 +                       ".set  push      \n"         
   4.362 +                       ".set  mips2     \n"        
   4.363 +                       "ll    %0,%3     \n"        
   4.364 +                       "addu  %1,%4,%0  \n"     
   4.365 +                       "sc    %1,%2     \n"        
   4.366 +                       ".set  pop       \n"          
   4.367 +                       "beqz  %1,1b     \n"        
   4.368 +                       : "=&r" (rv),          
   4.369 +                         "=&r" (tmp),         
   4.370 +                         "=m" (*atomic)     
   4.371 +                       : "m" (*atomic),     
   4.372 +                         "r" (value)          
   4.373 +                       : "memory");           
   4.374 +  return rv;                                         
   4.375 +}
   4.376 +
   4.377 +static __inline__ void
   4.378 +SDL_atomic_int_add(volatile int* atomic, int value)
   4.379 +{                                           
   4.380 +  int rv;                                    
   4.381 +  __asm__ __volatile__("1:               \n"                
   4.382 +                       ".set  push       \n"        
   4.383 +                       ".set  mips2      \n"       
   4.384 +                       "ll    %0,%2      \n"       
   4.385 +                       "addu  %0,%3,%0   \n"    
   4.386 +                       "sc    %0,%1      \n"       
   4.387 +                       ".set  pop        \n"         
   4.388 +                       "beqz  %0,1b      \n"       
   4.389 +                       : "=&r" (rv),         
   4.390 +                         "=m" (*atomic)    
   4.391 +                       : "m" (*atomic),    
   4.392 +                         "r" (value)         
   4.393 +                       : "memory");          
   4.394 +}
   4.395 +
   4.396 +static __inline__ SDL_bool
   4.397 +SDL_atomic_int_cmp_xchg(volatile int* atomic, int oldvalue, int newvalue)
   4.398 +{
   4.399 +  int rv;
   4.400 +  __asm__ __volatile__("     .set push        \n"
   4.401 +                       "     .set noat        \n"
   4.402 +                       "     .set mips3       \n"
   4.403 +                       "1:   ll   %0, %2      \n"
   4.404 +                       "     bne  %0, %z3, 2f \n"
   4.405 +                       "     .set mips0       \n"
   4.406 +                       "     move $1, %z4     \n"
   4.407 +                       "     .set mips3       \n"
   4.408 +                       "     sc   $1, %1      \n"
   4.409 +                       "     beqz $1, 1b      \n"
   4.410 +                       "     sync             \n"
   4.411 +                       "2:                    \n"
   4.412 +                       "     .set pop         \n"
   4.413 +                       : "=&r" (rv),
   4.414 +                         "=R" (*atomic)
   4.415 +                       : "R" (*atomic),
   4.416 +                         "Jr" (oldvalue),
   4.417 +                         "Jr" (newvalue)
   4.418 +                       : "memory");
   4.419 +  return (SDL_bool)rv;                  
   4.420 +}
   4.421 +
   4.422 +static __inline__ SDL_bool
   4.423 +SDL_atomic_ptr_cmp_xchg(volatile void** atomic, void* oldvalue, void* newvalue)
   4.424 +{                                                     
   4.425 +  int rv;
   4.426 +  __asm__ __volatile__("     .set push        \n"
   4.427 +                       "     .set noat        \n"
   4.428 +                       "     .set mips3       \n"
   4.429 +# if defined(__mips64)
   4.430 +                       "1:   lld  %0, %2      \n"
   4.431 +# else
   4.432 +                       "1:   ll   %0, %2      \n"
   4.433 +# endif                       
   4.434 +                       "     bne  %0, %z3, 2f \n"
   4.435 +                       "     move $1, %z4     \n"
   4.436 +# if defined(__mips64)
   4.437 +                       "     sc   $1, %1      \n"
   4.438 +# else
   4.439 +                       "     scd  $1, %1      \n"
   4.440 +# endif                       
   4.441 +                       "     beqz $1, 1b      \n"
   4.442 +                       "     sync             \n"
   4.443 +                       "2:                    \n"
   4.444 +                       "     .set pop         \n"
   4.445 +                       : "=&r" (rv),
   4.446 +                         "=R" (*atomic)
   4.447 +                       : "R" (*atomic),
   4.448 +                         "Jr" (oldvalue),
   4.449 +                         "Jr" (newvalue)
   4.450 +                       : "memory");
   4.451 +  return (SDL_bool)rv;                                                  
   4.452 +}
   4.453 +#elif defined(__GNUC__) && defined(__m68k__)
   4.454 +static __inline__ int
   4.455 +SDL_atomic_int_xchg_add(volatile int* atomic, int value)
   4.456 +{                                          
   4.457 +  int rv = *atomic;
   4.458 +  int tmp;
   4.459 +  __asm__ __volatile__("1: move%.l %0,%1    \n"
   4.460 +                       "   add%.l  %2,%1    \n"
   4.461 +                       "   cas%.l  %0,%1,%3 \n"
   4.462 +                       "   jbne    1b       \n"
   4.463 +                       : "=d" (rv),
   4.464 +                         "=&d" (tmp)
   4.465 +                       : "d" (value),
   4.466 +                         "m" (*atomic),
   4.467 +                         "0" (rv)
   4.468 +                       : "memory");
   4.469 +  return rv;
   4.470 +}
   4.471 +
   4.472 +static __inline__ void
   4.473 +SDL_atomic_int_add(volatile int* atomic, int value)
   4.474 +{                                           
   4.475 +  __asm__ __volatile__("add%.l %0,%1"        
   4.476 +                       :                     
   4.477 +                       : "id" (value),       
   4.478 +                         "m" (*atomic)
   4.479 +                       : "memory");          
   4.480 +}
   4.481 +
   4.482 +static __inline__ SDL_bool
   4.483 +SDL_atomic_int_cmp_xchg(volatile int* atomic, int oldvalue, int newvalue)
   4.484 +{                                           
   4.485 +  char rv;                                   
   4.486 +  int readvalue;                             
   4.487 +  __asm__ __volatile__("cas%.l %2,%3,%1\n"   
   4.488 +                       "seq    %0"           
   4.489 +                       : "=dm" (rv),         
   4.490 +                         "=m" (*atomic),   
   4.491 +                         "=d" (readvalue)    
   4.492 +                       : "d" (newvalue),     
   4.493 +                         "m" (*atomic),    
   4.494 +                         "2" (oldvalue));    
   4.495 +    return rv;                                        
   4.496 +}
   4.497 +
   4.498 +static __inline__ SDL_bool
   4.499 +SDL_atomic_ptr_cmp_xchg(volatile void** atomic, void* oldvalue, void* newvalue)
   4.500 +{
   4.501 +  char rv;                                   
   4.502 +  int readvalue;                             
   4.503 +  __asm__ __volatile__("cas%.l %2,%3,%1\n"   
   4.504 +                       "seq    %0"           
   4.505 +                       : "=dm" (rv),         
   4.506 +                         "=m" (*atomic),   
   4.507 +                         "=d" (readvalue)    
   4.508 +                       : "d" (newvalue),     
   4.509 +                         "m" (*atomic),    
   4.510 +                         "2" (oldvalue));    
   4.511 +    return rv;                                        
   4.512 +}
   4.513 +#elif defined(__GNUC__) && defined(__s390__)
   4.514 +# define ATOMIC_INT_CMP_XCHG(atomic,oldvalue,newvalue)  \
   4.515 +  ({                                                    \
   4.516 +    int rv = oldvalue;                                  \
   4.517 +    __asm__ __volatile__("cs %0, %2, %1"                \
   4.518 +                         : "+d" (rv),                   \
   4.519 +                           "=Q" (*(atomic))             \
   4.520 +                         : "d" (newvalue),              \
   4.521 +                           "m" (*(atomic))              \
   4.522 +                         : "cc");                       \
   4.523 +    rv == oldvalue;                                     \
   4.524 +  })
   4.525 +# if (SIZEOF_VOIDP == 4)
   4.526 +static __inline__ SDL_bool
   4.527 +SDL_atomic_ptr_cmp_xchg(volatile void** atomic, void* oldvalue, void* newvalue)
   4.528 +{
   4.529 +  void* rv = oldvalue;
   4.530 +  __asm__ __volatile__("cs %0, %2, %1"
   4.531 +                       : "+d" (rv),
   4.532 +                         "=Q" (*atomic)
   4.533 +                       : "d" (newvalue),
   4.534 +                         "m" (*atomic)
   4.535 +                       : "cc");
   4.536 +  return (rv == oldvalue);
   4.537 +}
   4.538 +# elif (SIZEOF_VOIDP == 8)
   4.539 +static __inline__ SDL_bool
   4.540 +SDL_atomic_ptr_cmp_xchg(volatile void** atomic, void* oldvalue, void* newvalue)
   4.541 +{
   4.542 +  void* rv = oldvalue;
   4.543 +  void** a = atomic;
   4.544 +  __asm__ __volatile__("csg %0, %2, %1"
   4.545 +                       : "+d" (rv),
   4.546 +                         "=Q" (*a)
   4.547 +                       : "d" ((long)(newvalue)),
   4.548 +                         "m" (*a)
   4.549 +                       : "cc");
   4.550 +  return (rv == oldvalue);
   4.551 +}
   4.552 +# else
   4.553 +#  error "Your system has an unsupported pointer size"
   4.554 +# endif /* SIZEOF_VOIDP */
   4.555 +#elif defined(__WIN32__)
   4.556 +# include <windows.h>
   4.557 +static __inline__ int
   4.558 +SDL_atomic_int_xchg_add(volatile int* atomic, int value)
   4.559 +{
   4.560 +  return InterlockedExchangeAdd(atomic, value);
   4.561 +}
   4.562 +
   4.563 +static __inline__ void
   4.564 +SDL_atomic_int_add(volatile int* atomic, int value)
   4.565 +{
   4.566 +  InterlockedExchangeAdd(atomic, value);
   4.567 +}
   4.568 +
   4.569 +# if (WINVER > 0X0400)
   4.570 +static __inline__ SDL_bool
   4.571 +SDL_atmoic_int_cmp_xchg(volatile int* atomic, int oldvalue, int newvalue)
   4.572 +{
   4.573 +  return ((SDL_bool)InterlockedCompareExchangePointer((PVOID*)atomic,
   4.574 +                                                      (PVOID)newvalue,
   4.575 +                                                      (PVOID)oldvalue) == oldvalue);
   4.576 +}
   4.577 +
   4.578 +
   4.579 +static __inline__ SDL_bool
   4.580 +SDL_atomic_ptr_cmp_xchg(volatile void** atomic, void* oldvalue, void* newvalue)
   4.581 +{
   4.582 +  return (InterlockedCompareExchangePointer(atomic, newvalue, oldvalue) == oldvalue);
   4.583 +}
   4.584 +# else /* WINVER <= 0x0400 */
   4.585 +#  if (SIZEOF_VOIDP != 4)
   4.586 +#   error "InterlockedCompareExchangePointer needed"
   4.587 +#  endif
   4.588 +
   4.589 +static __inline__ SDL_bool
   4.590 +SDL_atomic_int_cmp_xchg(volatile int* atomic, int oldvalue, int newvalue)
   4.591 +{
   4.592 +  return (InterlockedCompareExchange(atomic, newvalue, oldvalue) == oldvalue);
   4.593 +}
   4.594 +
   4.595 +static __inline__ SDL_bool
   4.596 +SDL_atomic_ptr_cmp_xchg(volatile void** atomic, void* oldvalue, void* newvalue)
   4.597 +{
   4.598 +  return (InterlockedCompareExchange(atomic, newvalue, oldvalue) == oldvalue);
   4.599 +}
   4.600 +# endif
   4.601 +#else /* when all else fails */
   4.602 +# define SDL_ATOMIC_OPS_NOT_SUPPORTED
   4.603 +# warning "Atomic Ops for this platform not supported!"
   4.604 +static __inline__ int
   4.605 +SDL_atomic_int_xchg_add(volatile int* atomic, int value)
   4.606 +{                                           
   4.607 +  int rv = *atomic;                          
   4.608 +  *(atomic) += value;                        
   4.609 +  return rv;                                        
   4.610 +}
   4.611 +
   4.612 +static __inline__ SDL_bool
   4.613 +SDL_atomic_int_cmp_xchg(volatile int* atomic, int oldvalue, int newvalue)
   4.614 +{
   4.615 +  return (*atomic == oldvalue) ?  
   4.616 +    ((*atomic = newvalue), SDL_TRUE) : SDL_FALSE;
   4.617 +}
   4.618 +
   4.619 +static __inline__ void
   4.620 +SDL_atomic_int_add(volatile int* atomic, int value)
   4.621 +{
   4.622 +  *atomic += value;
   4.623 +}
   4.624 +#endif /* arch & platforms */
   4.625 +  
   4.626 +#ifdef ATOMIC_INT_CMP_XCHG
   4.627 +static __inline__ SDL_bool
   4.628 +SDL_atomic_int_cmp_xchg(volatile int* atomic, int oldvalue, int newvalue)
   4.629 +{
   4.630 +  return ATOMIC_INT_CMP_XCHG(atomic,oldvalue,newvalue);
   4.631 +}
   4.632 +
   4.633 +static __inline__ int
   4.634 +SDL_atomic_int_xchg_add(volatile int* atomic, int value)   
   4.635 +{                                                   
   4.636 +  int rv;                                            
   4.637 +  do                                                 
   4.638 +    rv = *atomic;                                
   4.639 +  while(!ATOMIC_INT_CMP_XCHG(atomic,rv,rv+value)); 
   4.640 +  return rv;                                                
   4.641 +}
   4.642 +
   4.643 +static __inline__ void
   4.644 +SDL_atomic_int_add(volatile int* atomic, int value)
   4.645 +{
   4.646 +  int rv;
   4.647 +  do
   4.648 +    rv = *atomic;
   4.649 +  while(!ATOMIC_INT_CMP_XCHG(atomic,rv,rv+value));
   4.650 +}
   4.651 +#endif /* ATOMIC_CMP_XCHG */
   4.652 +
   4.653 +#ifdef ATOMIC_MEMORY_BARRIER
   4.654 +# define SDL_atomic_int_get(atomic) \
   4.655 +  (ATOMIC_MEMORY_BARRIER,*(atomic))
   4.656 +# define SDL_atomic_int_set(atomic,value) \
   4.657 +  (*(atomic)=value,ATOMIC_MEMORY_BARRIER)
   4.658 +#else
   4.659 +# define SDL_atomic_int_get(atomic) (*(atomic))
   4.660 +# define SDL_atomic_int_set(atomic, newvalue) ((void)(*(atomic) = (newvalue)))
   4.661 +#endif /* MEMORY_BARRIER_NEEDED */
   4.662 +
   4.663 +#define SDL_atomic_int_inc(atomic) (SDL_atomic_int_add((atomic),1))
   4.664 +#define SDL_atomic_int_dec_test(atomic) (SDL_atomic_int_xchg_add((atomic),-1) == 1)
   4.665 +
   4.666 +/* Ends C function definitions when using C++ */
   4.667 +#ifdef __cplusplus
   4.668 +/* *INDENT-OFF* */
   4.669 +}
   4.670 +/* *INDENT-ON* */
   4.671 +#endif
   4.672 +
   4.673 +#include "close_code.h"
   4.674 +
   4.675 +#endif /* _SDL_atomic_h_ */
   4.676 +
   4.677 +/* vi: set ts=4 sw=4 expandtab: */
     5.1 --- a/include/SDL_config.h.in	Tue Jun 09 15:45:33 2009 +0000
     5.2 +++ b/include/SDL_config.h.in	Tue Jun 09 17:33:44 2009 +0000
     5.3 @@ -49,6 +49,7 @@
     5.4  #undef int64_t
     5.5  #undef uint64_t
     5.6  #undef uintptr_t
     5.7 +#undef SIZEOF_VOIDP
     5.8  #undef SDL_HAS_64BIT_TYPE
     5.9  
    5.10  /* Endianness */
     6.1 --- a/include/SDL_config_dreamcast.h	Tue Jun 09 15:45:33 2009 +0000
     6.2 +++ b/include/SDL_config_dreamcast.h	Tue Jun 09 17:33:44 2009 +0000
     6.3 @@ -36,6 +36,7 @@
     6.4  typedef signed long long int64_t;
     6.5  typedef unsigned long long uint64_t;
     6.6  typedef unsigned long uintptr_t;
     6.7 +#define SIZEOF_VOIDP 4
     6.8  #define SDL_HAS_64BIT_TYPE	1
     6.9  
    6.10  /* Useful headers */
     7.1 --- a/include/SDL_config_macosx.h	Tue Jun 09 15:45:33 2009 +0000
     7.2 +++ b/include/SDL_config_macosx.h	Tue Jun 09 17:33:44 2009 +0000
     7.3 @@ -30,6 +30,7 @@
     7.4  
     7.5  /* This is a set of defines to configure the SDL features */
     7.6  
     7.7 +#define SIZEOF_VOIDP 4
     7.8  #define SDL_HAS_64BIT_TYPE	1
     7.9  
    7.10  /* Useful headers */
     8.1 --- a/include/SDL_config_os2.h	Tue Jun 09 15:45:33 2009 +0000
     8.2 +++ b/include/SDL_config_os2.h	Tue Jun 09 17:33:44 2009 +0000
     8.3 @@ -38,6 +38,7 @@
     8.4  typedef signed long long int64_t;
     8.5  typedef unsigned long long uint64_t;
     8.6  
     8.7 +#define SIZEOF_VOIDP 4
     8.8  #define SDL_HAS_64BIT_TYPE	1
     8.9  
    8.10  /* Use Watcom's LIBC */
     9.1 --- a/include/SDL_config_win32.h	Tue Jun 09 15:45:33 2009 +0000
     9.2 +++ b/include/SDL_config_win32.h	Tue Jun 09 17:33:44 2009 +0000
     9.3 @@ -68,6 +68,12 @@
     9.4  #endif
     9.5  typedef unsigned int uintptr_t;
     9.6  #endif /* __GNUC__ || _MSC_VER */
     9.7 +
     9.8 +#ifdef _WIN64
     9.9 +# define SIZEOF_VOIDP 8
    9.10 +#else
    9.11 +# define SIZEOF_VOIDP 4
    9.12 +#endif
    9.13  #define SDL_HAS_64BIT_TYPE	1
    9.14  
    9.15  /* Enabled for SDL 1.2 (binary compatibility) */
    10.1 --- a/test/Makefile.in	Tue Jun 09 15:45:33 2009 +0000
    10.2 +++ b/test/Makefile.in	Tue Jun 09 17:33:44 2009 +0000
    10.3 @@ -7,7 +7,7 @@
    10.4  CFLAGS  = @CFLAGS@
    10.5  LIBS	= @LIBS@
    10.6  
    10.7 -TARGETS = checkkeys$(EXE) graywin$(EXE) loopwave$(EXE) testresample$(EXE) testaudioinfo$(EXE) testmultiaudio$(EXE) testpower$(EXE) testalpha$(EXE) testbitmap$(EXE) testblitspeed$(EXE) testcdrom$(EXE) testcursor$(EXE) testintersections$(EXE) testdraw2$(EXE) testdyngl$(EXE) testdyngles$(EXE) testerror$(EXE) testfile$(EXE) testgamma$(EXE) testgl$(EXE) testgl2$(EXE) testgles$(EXE) testhread$(EXE) testiconv$(EXE) testjoystick$(EXE) testkeys$(EXE) testlock$(EXE) testoverlay2$(EXE) testoverlay$(EXE) testpalette$(EXE) testplatform$(EXE) testsem$(EXE) testsprite$(EXE) testsprite2$(EXE) testtimer$(EXE) testver$(EXE) testvidinfo$(EXE) testwin$(EXE) testwm$(EXE) testwm2$(EXE) threadwin$(EXE) torturethread$(EXE) testloadso$(EXE) testhaptic$(EXE) testmmousetablet$(EXE)
    10.8 +TARGETS = checkkeys$(EXE) graywin$(EXE) loopwave$(EXE) testresample$(EXE) testaudioinfo$(EXE) testmultiaudio$(EXE) testpower$(EXE) testalpha$(EXE) testbitmap$(EXE) testblitspeed$(EXE) testcdrom$(EXE) testcursor$(EXE) testintersections$(EXE) testdraw2$(EXE) testdyngl$(EXE) testdyngles$(EXE) testerror$(EXE) testfile$(EXE) testgamma$(EXE) testgl$(EXE) testgl2$(EXE) testgles$(EXE) testhread$(EXE) testiconv$(EXE) testjoystick$(EXE) testkeys$(EXE) testlock$(EXE) testoverlay2$(EXE) testoverlay$(EXE) testpalette$(EXE) testplatform$(EXE) testsem$(EXE) testsprite$(EXE) testsprite2$(EXE) testtimer$(EXE) testver$(EXE) testvidinfo$(EXE) testwin$(EXE) testwm$(EXE) testwm2$(EXE) threadwin$(EXE) torturethread$(EXE) testloadso$(EXE) testhaptic$(EXE) testmmousetablet$(EXE) testatomic$(EXE)
    10.9  
   10.10  all: Makefile $(TARGETS)
   10.11  
   10.12 @@ -149,6 +149,9 @@
   10.13  testmmousetablet$(EXE): $(srcdir)/testmmousetablet.c
   10.14  	$(CC) -o $@ $? $(CFLAGS) $(LIBS)
   10.15  
   10.16 +testatomic$(EXE): $(srcdir)/testatomic.c
   10.17 +	$(CC) -o $@ $? $(CFLAGS) $(LIBS)
   10.18 + 
   10.19  clean:
   10.20  	rm -f $(TARGETS)
   10.21  
    11.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    11.2 +++ b/test/testatomic.c	Tue Jun 09 17:33:44 2009 +0000
    11.3 @@ -0,0 +1,64 @@
    11.4 +#include "SDL.h"
    11.5 +
    11.6 +int
    11.7 +main(int argc, char** argv)
    11.8 +{
    11.9 +  int rv = 10;
   11.10 +  volatile int atomic;
   11.11 +
   11.12 +  SDL_atomic_int_set(&atomic, 10);
   11.13 +  if(SDL_atomic_int_get(&atomic) != 10)
   11.14 +    printf("Error: ");
   11.15 +  printf("SDL_atomic_int_set(atomic, 10): atomic-> %d\n",
   11.16 +         SDL_atomic_int_get(&atomic));
   11.17 +    
   11.18 +  SDL_atomic_int_add(&atomic, 10);
   11.19 +  if(SDL_atomic_int_get(&atomic) != 20)
   11.20 +    printf("Error: ");
   11.21 +  printf("SDL_atomic_int_add(atomic, 10): atomic-> %d\n",
   11.22 +         SDL_atomic_int_get(&atomic));
   11.23 +  
   11.24 +  rv = SDL_atomic_int_cmp_xchg(&atomic, 20, 30);
   11.25 +  if(rv != SDL_TRUE || SDL_atomic_int_get(&atomic) != 30)
   11.26 +    printf("Error: ");
   11.27 +  printf("SDL_atomic_int_cmp_xchg(atomic, 20, 30): rv-> %d, atomic-> %d\n",
   11.28 +         rv, SDL_atomic_int_get(&atomic));
   11.29 +  
   11.30 +  rv = SDL_atomic_int_cmp_xchg(&atomic, 20, 30);
   11.31 +  if(rv != SDL_FALSE || SDL_atomic_int_get(&atomic) != 30)
   11.32 +    printf("Error: ");
   11.33 +  printf("SDL_atomic_int_cmp_xchg(atomic, 20, 40): rv-> %d, atomic-> %d\n",
   11.34 +         rv, SDL_atomic_int_get(&atomic));
   11.35 +  
   11.36 +  rv = SDL_atomic_int_xchg_add(&atomic, 10);
   11.37 +  if(rv != 30 || SDL_atomic_int_get(&atomic) != 40)
   11.38 +    printf("Error: ");
   11.39 +  printf("SDL_atomic_int_xchg_add(atomic, 10): rv-> %d, atomic-> %d\n",
   11.40 +         rv, SDL_atomic_int_get(&atomic));
   11.41 +
   11.42 +  SDL_atomic_int_inc(&atomic);
   11.43 +  if(SDL_atomic_int_get(&atomic) != 41)
   11.44 +    printf("Error: ");
   11.45 +  printf("SDL_atomic_int_inc(atomic): atomic-> %d\n",
   11.46 +         SDL_atomic_int_get(&atomic));
   11.47 +
   11.48 +  rv = SDL_atomic_int_dec_test(&atomic);
   11.49 +  if(rv != SDL_FALSE || SDL_atomic_int_get(&atomic) != 40)
   11.50 +    printf("Error: ");
   11.51 +  printf("SDL_atomic_int_dec_test(atomic): rv-> %d, atomic-> %d\n",
   11.52 +         rv, SDL_atomic_int_get(&atomic));
   11.53 +  
   11.54 +  SDL_atomic_int_set(&atomic, 1);
   11.55 +  if(SDL_atomic_int_get(&atomic) != 1)
   11.56 +    printf("Error: ");    
   11.57 +    printf("SDL_atomic_int_set(atomic, 1): atomic-> %d\n",
   11.58 +           SDL_atomic_int_get(&atomic));
   11.59 +
   11.60 +  rv = SDL_atomic_int_dec_test(&atomic);
   11.61 +  if(rv != SDL_TRUE || SDL_atomic_int_get(&atomic) != 0)
   11.62 +    printf("Error: ");
   11.63 +  printf("SDL_atomic_int_dec_test(atomic): rv-> %d, atomic-> %d\n",
   11.64 +         rv, SDL_atomic_int_get(&atomic));
   11.65 +  
   11.66 +  return 0;
   11.67 +}