2006-09-08 15:43:44 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								# ifndef foopulseatomichfoo 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# define foopulseatomichfoo 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/***
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  This  file  is  part  of  PulseAudio . 
							 
						 
					
						
							
								
									
										
										
										
											2007-01-04 13:43:45 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-06-16 19:00:47 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								  Copyright  2006 - 2008  Lennart  Poettering 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  Copyright  2008  Nokia  Corporation 
							 
						 
					
						
							
								
									
										
										
										
											2007-02-13 15:35:19 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-09-08 15:43:44 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								  PulseAudio  is  free  software ;  you  can  redistribute  it  and / or  modify 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  it  under  the  terms  of  the  GNU  Lesser  General  Public  License  as 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-03 20:23:02 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								  published  by  the  Free  Software  Foundation ;  either  version  2.1  of  the 
							 
						 
					
						
							
								
									
										
										
										
											2006-09-08 15:43:44 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								  License ,  or  ( at  your  option )  any  later  version . 
							 
						 
					
						
							
								
									
										
										
										
											2007-01-04 13:43:45 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-09-08 15:43:44 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								  PulseAudio  is  distributed  in  the  hope  that  it  will  be  useful ,  but 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  WITHOUT  ANY  WARRANTY ;  without  even  the  implied  warranty  of 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  MERCHANTABILITY  or  FITNESS  FOR  A  PARTICULAR  PURPOSE .  See  the  GNU 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  General  Public  License  for  more  details . 
							 
						 
					
						
							
								
									
										
										
										
											2007-01-04 13:43:45 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-09-08 15:43:44 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								  You  should  have  received  a  copy  of  the  GNU  Lesser  General  Public 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  License  along  with  PulseAudio ;  if  not ,  write  to  the  Free  Software 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  Foundation ,  Inc . ,  59  Temple  Place ,  Suite  330 ,  Boston ,  MA  02111 - 1307 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  USA . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								* * */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-08-29 20:24:46 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								# include  <pulsecore/macro.h> 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-10-28 19:13:50 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								/*
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  atomic_ops  guarantees  us  that  sizeof ( AO_t )  = =  sizeof ( void * ) .   It  is 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  not  guaranteed  however ,  that  sizeof ( AO_t )  = =  sizeof ( size_t ) . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  however  very  likely . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  For  now  we  do  only  full  memory  barriers .  Eventually  we  might  want 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  to  support  more  elaborate  memory  barriers ,  in  which  case  we  will  add 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  suffixes  to  the  function  names . 
							 
						 
					
						
							
								
									
										
										
										
											2006-09-08 15:43:44 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								 * 
							 
						 
					
						
							
								
									
										
										
										
											2007-10-28 19:13:50 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								 *  On  gcc  > =  4.1  we  use  the  builtin  atomic  functions .  otherwise  we  use 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  libatomic_ops 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 */ 
							 
						 
					
						
							
								
									
										
										
										
											2008-08-29 20:24:46 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-10-28 19:13:50 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								# ifndef PACKAGE 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# error "Please include config.h before including this file!" 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# endif 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-08-29 23:53:55 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								# ifdef HAVE_ATOMIC_BUILTINS 
 
							 
						 
					
						
							
								
									
										
										
										
											2007-10-28 19:13:50 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/* __sync based implementation */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								typedef  struct  pa_atomic  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    volatile  int  value ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								}  pa_atomic_t ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-09-08 15:43:44 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-09-09 22:54:11 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								# define PA_ATOMIC_INIT(v) { .value = (v) } 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-10-28 19:13:50 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								static  inline  int  pa_atomic_load ( const  pa_atomic_t  * a )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    __sync_synchronize ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    return  a - > value ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								static  inline  void  pa_atomic_store ( pa_atomic_t  * a ,  int  i )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    a - > value  =  i ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    __sync_synchronize ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/* Returns the previously set value */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								static  inline  int  pa_atomic_add ( pa_atomic_t  * a ,  int  i )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    return  __sync_fetch_and_add ( & a - > value ,  i ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/* Returns the previously set value */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								static  inline  int  pa_atomic_sub ( pa_atomic_t  * a ,  int  i )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    return  __sync_fetch_and_sub ( & a - > value ,  i ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/* Returns the previously set value */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								static  inline  int  pa_atomic_inc ( pa_atomic_t  * a )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    return  pa_atomic_add ( a ,  1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/* Returns the previously set value */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								static  inline  int  pa_atomic_dec ( pa_atomic_t  * a )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    return  pa_atomic_sub ( a ,  1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-08-29 20:24:46 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								/* Returns TRUE when the operation was successful. */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								static  inline  pa_bool_t  pa_atomic_cmpxchg ( pa_atomic_t  * a ,  int  old_i ,  int  new_i )  { 
							 
						 
					
						
							
								
									
										
										
										
											2007-10-28 19:13:50 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    return  __sync_bool_compare_and_swap ( & a - > value ,  old_i ,  new_i ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								typedef  struct  pa_atomic_ptr  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    volatile  unsigned  long  value ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								}  pa_atomic_ptr_t ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# define PA_ATOMIC_PTR_INIT(v) { .value = (long) (v) } 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								static  inline  void *  pa_atomic_ptr_load ( const  pa_atomic_ptr_t  * a )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    __sync_synchronize ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    return  ( void * )  a - > value ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								static  inline  void  pa_atomic_ptr_store ( pa_atomic_ptr_t  * a ,  void  * p )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    a - > value  =  ( unsigned  long )  p ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    __sync_synchronize ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-08-29 20:24:46 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								static  inline  pa_bool_t  pa_atomic_ptr_cmpxchg ( pa_atomic_ptr_t  * a ,  void  * old_p ,  void *  new_p )  { 
							 
						 
					
						
							
								
									
										
										
										
											2007-10-28 19:13:50 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    return  __sync_bool_compare_and_swap ( & a - > value ,  ( long )  old_p ,  ( long )  new_p ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-01-22 01:52:35 +01:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								# elif defined(__NetBSD__) && defined(HAVE_SYS_ATOMIC_H) 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/* NetBSD 5.0+ atomic_ops(3) implementation */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# include  <sys/atomic.h> 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								typedef  struct  pa_atomic  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    volatile  unsigned  int  value ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								}  pa_atomic_t ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# define PA_ATOMIC_INIT(v) { .value = (unsigned int) (v) } 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								static  inline  int  pa_atomic_load ( const  pa_atomic_t  * a )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    membar_sync ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    return  ( int )  a - > value ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								static  inline  void  pa_atomic_store ( pa_atomic_t  * a ,  int  i )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    a - > value  =  ( unsigned  int )  i ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    membar_sync ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/* Returns the previously set value */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								static  inline  int  pa_atomic_add ( pa_atomic_t  * a ,  int  i )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    int  nv  =  ( int )  atomic_add_int_nv ( & a - > value ,  i ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    return  nv  -  i ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/* Returns the previously set value */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								static  inline  int  pa_atomic_sub ( pa_atomic_t  * a ,  int  i )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    int  nv  =  ( int )  atomic_add_int_nv ( & a - > value ,  - i ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    return  nv  +  i ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/* Returns the previously set value */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								static  inline  int  pa_atomic_inc ( pa_atomic_t  * a )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    int  nv  =  ( int )  atomic_inc_uint_nv ( & a - > value ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    return  nv  -  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/* Returns the previously set value */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								static  inline  int  pa_atomic_dec ( pa_atomic_t  * a )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    int  nv  =  ( int )  atomic_dec_uint_nv ( & a - > value ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    return  nv  +  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/* Returns TRUE when the operation was successful. */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								static  inline  pa_bool_t  pa_atomic_cmpxchg ( pa_atomic_t  * a ,  int  old_i ,  int  new_i )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    unsigned  int  r  =  atomic_cas_uint ( & a - > value ,  ( unsigned  int )  old_i ,  ( unsigned  int )  new_i ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    return  ( int )  r  = =  old_i ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								typedef  struct  pa_atomic_ptr  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    volatile  void  * value ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								}  pa_atomic_ptr_t ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# define PA_ATOMIC_PTR_INIT(v) { .value = (v) } 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								static  inline  void *  pa_atomic_ptr_load ( const  pa_atomic_ptr_t  * a )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    membar_sync ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    return  ( void  * )  a - > value ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								static  inline  void  pa_atomic_ptr_store ( pa_atomic_ptr_t  * a ,  void  * p )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    a - > value  =  p ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    membar_sync ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								static  inline  pa_bool_t  pa_atomic_ptr_cmpxchg ( pa_atomic_ptr_t  * a ,  void  * old_p ,  void *  new_p )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    void  * r  =  atomic_cas_ptr ( & a - > value ,  old_p ,  new_p ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    return  r  = =  old_p ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-10-28 19:13:50 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								# elif defined(__GNUC__) && (defined(__amd64__) || defined(__x86_64__)) 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-08-29 21:46:12 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								# warn "The native atomic operations implementation for AMD64 has not been tested thoroughly. libatomic_ops is known to not work properly on AMD64 and your gcc version is too old for the gcc-builtin atomic ops support. You have three options now: test the native atomic operations implementation for AMD64, fix libatomic_ops, or upgrade your GCC." 
 
							 
						 
					
						
							
								
									
										
										
										
											2007-10-28 19:13:50 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/* Addapted from glibc */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								typedef  struct  pa_atomic  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    volatile  int  value ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								}  pa_atomic_t ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# define PA_ATOMIC_INIT(v) { .value = (v) } 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								static  inline  int  pa_atomic_load ( const  pa_atomic_t  * a )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    return  a - > value ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								static  inline  void  pa_atomic_store ( pa_atomic_t  * a ,  int  i )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    a - > value  =  i ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								static  inline  int  pa_atomic_add ( pa_atomic_t  * a ,  int  i )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    int  result ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    __asm  __volatile  ( " lock; xaddl %0, %1 " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                      :  " =r "  ( result ) ,  " =m "  ( a - > value ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                      :  " 0 "  ( i ) ,  " m "  ( a - > value ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    return  result ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								static  inline  int  pa_atomic_sub ( pa_atomic_t  * a ,  int  i )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    return  pa_atomic_add ( a ,  - i ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								static  inline  int  pa_atomic_inc ( pa_atomic_t  * a )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    return  pa_atomic_add ( a ,  1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
									
										
										
										
											2006-09-08 15:43:44 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-10-28 19:13:50 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								static  inline  int  pa_atomic_dec ( pa_atomic_t  * a )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    return  pa_atomic_sub ( a ,  1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-08-29 20:24:46 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								static  inline  pa_bool_t  pa_atomic_cmpxchg ( pa_atomic_t  * a ,  int  old_i ,  int  new_i )  { 
							 
						 
					
						
							
								
									
										
										
										
											2007-10-28 19:13:50 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    int  result ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    __asm__  __volatile__  ( " lock; cmpxchgl %2, %1 " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                          :  " =a "  ( result ) ,  " =m "  ( a - > value ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                          :  " r "  ( new_i ) ,  " m "  ( a - > value ) ,  " 0 "  ( old_i ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-08-29 21:42:09 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    return  result  = =  old_i ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-10-28 19:13:50 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								typedef  struct  pa_atomic_ptr  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    volatile  unsigned  long  value ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								}  pa_atomic_ptr_t ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# define PA_ATOMIC_PTR_INIT(v) { .value = (long) (v) } 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								static  inline  void *  pa_atomic_ptr_load ( const  pa_atomic_ptr_t  * a )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    return  ( void * )  a - > value ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								static  inline  void  pa_atomic_ptr_store ( pa_atomic_ptr_t  * a ,  void  * p )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    a - > value  =  ( unsigned  long )  p ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-08-29 20:24:46 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								static  inline  pa_bool_t  pa_atomic_ptr_cmpxchg ( pa_atomic_ptr_t  * a ,  void  * old_p ,  void *  new_p )  { 
							 
						 
					
						
							
								
									
										
										
										
											2007-10-28 19:13:50 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    void  * result ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    __asm__  __volatile__  ( " lock; cmpxchgq %q2, %1 " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                          :  " =a "  ( result ) ,  " =m "  ( a - > value ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                          :  " r "  ( new_p ) ,  " m "  ( a - > value ) ,  " 0 "  ( old_p ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-08-29 20:24:46 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    return  result  = =  old_p ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-10-28 19:13:50 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-03-26 21:15:52 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								# elif defined(ATOMIC_ARM_INLINE_ASM) 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/*
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								   These  should  only  be  enabled  if  we  have  ARMv6  or  better . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								*/ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								typedef  struct  pa_atomic  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    volatile  int  value ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								}  pa_atomic_t ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# define PA_ATOMIC_INIT(v) { .value = (v) } 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								static  inline  void  pa_memory_barrier ( void )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# ifdef ATOMIC_ARM_MEMORY_BARRIER_ENABLED 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    asm  volatile  ( " mcr  p15, 0, r0, c7, c10, 5  @ dmb " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# endif 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								static  inline  int  pa_atomic_load ( const  pa_atomic_t  * a )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_memory_barrier ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    return  a - > value ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								static  inline  void  pa_atomic_store ( pa_atomic_t  * a ,  int  i )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    a - > value  =  i ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_memory_barrier ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/* Returns the previously set value */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								static  inline  int  pa_atomic_add ( pa_atomic_t  * a ,  int  i )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    unsigned  long  not_exclusive ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    int  new_val ,  old_val ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_memory_barrier ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    do  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        asm  volatile  ( " ldrex    %0, [%3] \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                      " add      %2, %0, %4 \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                      " strex    %1, %2, [%3] \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                      :  " =&r "  ( old_val ) ,  " =&r "  ( not_exclusive ) ,  " =&r "  ( new_val ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                      :  " r "  ( & a - > value ) ,  " Ir "  ( i ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                      :  " cc " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    }  while ( not_exclusive ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_memory_barrier ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    return  old_val ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/* Returns the previously set value */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								static  inline  int  pa_atomic_sub ( pa_atomic_t  * a ,  int  i )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    unsigned  long  not_exclusive ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    int  new_val ,  old_val ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_memory_barrier ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    do  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        asm  volatile  ( " ldrex    %0, [%3] \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                      " sub      %2, %0, %4 \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                      " strex    %1, %2, [%3] \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                      :  " =&r "  ( old_val ) ,  " =&r "  ( not_exclusive ) ,  " =&r "  ( new_val ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                      :  " r "  ( & a - > value ) ,  " Ir "  ( i ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                      :  " cc " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    }  while ( not_exclusive ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_memory_barrier ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    return  old_val ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								static  inline  int  pa_atomic_inc ( pa_atomic_t  * a )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    return  pa_atomic_add ( a ,  1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								static  inline  int  pa_atomic_dec ( pa_atomic_t  * a )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    return  pa_atomic_sub ( a ,  1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-08-29 20:24:46 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								static  inline  pa_bool_t  pa_atomic_cmpxchg ( pa_atomic_t  * a ,  int  old_i ,  int  new_i )  { 
							 
						 
					
						
							
								
									
										
										
										
											2008-03-26 21:15:52 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    unsigned  long  not_equal ,  not_exclusive ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_memory_barrier ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    do  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        asm  volatile  ( " ldrex    %0, [%2] \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                      " subs     %0, %0, %3 \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                      " mov      %1, %0 \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                      " strexeq %0, %4, [%2] \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                      :  " =&r "  ( not_exclusive ) ,  " =&r "  ( not_equal ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                      :  " r "  ( & a - > value ) ,  " Ir "  ( old_i ) ,  " r "  ( new_i ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                      :  " cc " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    }  while ( not_exclusive  & &  ! not_equal ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_memory_barrier ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    return  ! not_equal ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								typedef  struct  pa_atomic_ptr  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    volatile  unsigned  long  value ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								}  pa_atomic_ptr_t ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# define PA_ATOMIC_PTR_INIT(v) { .value = (long) (v) } 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								static  inline  void *  pa_atomic_ptr_load ( const  pa_atomic_ptr_t  * a )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_memory_barrier ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    return  ( void * )  a - > value ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								static  inline  void  pa_atomic_ptr_store ( pa_atomic_ptr_t  * a ,  void  * p )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    a - > value  =  ( unsigned  long )  p ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_memory_barrier ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-08-29 20:24:46 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								static  inline  pa_bool_t  pa_atomic_ptr_cmpxchg ( pa_atomic_ptr_t  * a ,  void  * old_p ,  void *  new_p )  { 
							 
						 
					
						
							
								
									
										
										
										
											2008-03-26 21:15:52 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    unsigned  long  not_equal ,  not_exclusive ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_memory_barrier ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    do  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        asm  volatile  ( " ldrex    %0, [%2] \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                      " subs     %0, %0, %3 \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                      " mov      %1, %0 \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                      " strexeq %0, %4, [%2] \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                      :  " =&r "  ( not_exclusive ) ,  " =&r "  ( not_equal ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                      :  " r "  ( & a - > value ) ,  " Ir "  ( old_p ) ,  " r "  ( new_p ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                      :  " cc " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    }  while ( not_exclusive  & &  ! not_equal ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_memory_barrier ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    return  ! not_equal ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# elif defined(ATOMIC_ARM_LINUX_HELPERS) 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/* See file arch/arm/kernel/entry-armv.S in your kernel sources for more
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								   information  about  these  functions .  The  arm  kernel  helper  functions  first 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								   appeared  in  2.6 .16 . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								   Apply  - - disable - atomic - arm - linux - helpers  flag  to  confugure  if  you  prefere 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								   inline  asm  implementation  or  you  have  an  obsolete  Linux  kernel . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								*/ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/* Memory barrier */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								typedef  void  ( __kernel_dmb_t ) ( void ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# define __kernel_dmb (*(__kernel_dmb_t *)0xffff0fa0) 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								static  inline  void  pa_memory_barrier ( void )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# ifndef ATOMIC_ARM_MEMORY_BARRIER_ENABLED 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    __kernel_dmb ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# endif 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/* Atomic exchange (__kernel_cmpxchg_t contains memory barriers if needed) */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								typedef  int  ( __kernel_cmpxchg_t ) ( int  oldval ,  int  newval ,  volatile  int  * ptr ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# define __kernel_cmpxchg (*(__kernel_cmpxchg_t *)0xffff0fc0) 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/* This is just to get rid of all warnings */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								typedef  int  ( __kernel_cmpxchg_u_t ) ( unsigned  long  oldval ,  unsigned  long  newval ,  volatile  unsigned  long  * ptr ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# define __kernel_cmpxchg_u (*(__kernel_cmpxchg_u_t *)0xffff0fc0) 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								typedef  struct  pa_atomic  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    volatile  int  value ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								}  pa_atomic_t ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# define PA_ATOMIC_INIT(v) { .value = (v) } 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								static  inline  int  pa_atomic_load ( const  pa_atomic_t  * a )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_memory_barrier ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    return  a - > value ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								static  inline  void  pa_atomic_store ( pa_atomic_t  * a ,  int  i )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    a - > value  =  i ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_memory_barrier ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/* Returns the previously set value */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								static  inline  int  pa_atomic_add ( pa_atomic_t  * a ,  int  i )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    int  old_val ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    do  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        old_val  =  a - > value ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    }  while ( __kernel_cmpxchg ( old_val ,  old_val  +  i ,  & a - > value ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    return  old_val ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/* Returns the previously set value */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								static  inline  int  pa_atomic_sub ( pa_atomic_t  * a ,  int  i )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    int  old_val ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    do  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        old_val  =  a - > value ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    }  while ( __kernel_cmpxchg ( old_val ,  old_val  -  i ,  & a - > value ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    return  old_val ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/* Returns the previously set value */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								static  inline  int  pa_atomic_inc ( pa_atomic_t  * a )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    return  pa_atomic_add ( a ,  1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/* Returns the previously set value */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								static  inline  int  pa_atomic_dec ( pa_atomic_t  * a )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    return  pa_atomic_sub ( a ,  1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-08-29 20:24:46 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								/* Returns TRUE when the operation was successful. */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								static  inline  pa_bool_t  pa_atomic_cmpxchg ( pa_atomic_t  * a ,  int  old_i ,  int  new_i )  { 
							 
						 
					
						
							
								
									
										
										
										
											2008-06-03 08:40:30 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    pa_bool_t  failed ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-03-26 21:15:52 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    do  { 
							 
						 
					
						
							
								
									
										
										
										
											2008-06-03 08:40:30 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								      failed  =  ! ! __kernel_cmpxchg ( old_i ,  new_i ,  & a - > value ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-03-26 21:15:52 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    }  while ( failed  & &  a - > value  = =  old_i ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    return  ! failed ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								typedef  struct  pa_atomic_ptr  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    volatile  unsigned  long  value ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								}  pa_atomic_ptr_t ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# define PA_ATOMIC_PTR_INIT(v) { .value = (unsigned long) (v) } 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								static  inline  void *  pa_atomic_ptr_load ( const  pa_atomic_ptr_t  * a )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_memory_barrier ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    return  ( void * )  a - > value ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								static  inline  void  pa_atomic_ptr_store ( pa_atomic_ptr_t  * a ,  void  * p )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    a - > value  =  ( unsigned  long )  p ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    pa_memory_barrier ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-08-29 20:24:46 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								static  inline  pa_bool_t  pa_atomic_ptr_cmpxchg ( pa_atomic_ptr_t  * a ,  void  * old_p ,  void *  new_p )  { 
							 
						 
					
						
							
								
									
										
										
										
											2008-06-03 08:40:30 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    pa_bool_t  failed ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-03-26 21:15:52 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    do  { 
							 
						 
					
						
							
								
									
										
										
										
											2008-06-03 08:40:30 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        failed  =  ! ! __kernel_cmpxchg_u ( ( unsigned  long )  old_p ,  ( unsigned  long )  new_p ,  & a - > value ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    }  while ( failed  & &  a - > value  = =  ( unsigned  long )  old_p ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-03-26 21:15:52 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    return  ! failed ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-10-28 19:13:50 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								# else 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/* libatomic_ops based implementation */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# include  <atomic_ops.h> 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								typedef  struct  pa_atomic  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    volatile  AO_t  value ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								}  pa_atomic_t ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-08-20 03:33:06 +03:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								# define PA_ATOMIC_INIT(v) { .value = (AO_t) (v) } 
 
							 
						 
					
						
							
								
									
										
										
										
											2007-10-28 19:13:50 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								static  inline  int  pa_atomic_load ( const  pa_atomic_t  * a )  { 
							 
						 
					
						
							
								
									
										
										
										
											2006-09-08 15:43:44 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								    return  ( int )  AO_load_full ( ( AO_t * )  & a - > value ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-10-28 19:13:50 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								static  inline  void  pa_atomic_store ( pa_atomic_t  * a ,  int  i )  { 
							 
						 
					
						
							
								
									
										
										
										
											2006-09-08 15:43:44 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								    AO_store_full ( & a - > value ,  ( AO_t )  i ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-10-28 19:13:50 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								static  inline  int  pa_atomic_add ( pa_atomic_t  * a ,  int  i )  { 
							 
						 
					
						
							
								
									
										
										
										
											2008-08-20 03:33:06 +03:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    return  ( int )  AO_fetch_and_add_full ( & a - > value ,  ( AO_t )  i ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-09-08 15:43:44 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-10-28 19:13:50 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								static  inline  int  pa_atomic_sub ( pa_atomic_t  * a ,  int  i )  { 
							 
						 
					
						
							
								
									
										
										
										
											2008-08-20 03:33:06 +03:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    return  ( int )  AO_fetch_and_add_full ( & a - > value ,  ( AO_t )  - i ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-05-27 20:38:14 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-10-28 19:13:50 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								static  inline  int  pa_atomic_inc ( pa_atomic_t  * a )  { 
							 
						 
					
						
							
								
									
										
										
										
											2008-08-20 03:33:06 +03:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    return  ( int )  AO_fetch_and_add1_full ( & a - > value ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-09-08 15:43:44 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-10-28 19:13:50 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								static  inline  int  pa_atomic_dec ( pa_atomic_t  * a )  { 
							 
						 
					
						
							
								
									
										
										
										
											2008-08-20 03:33:06 +03:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    return  ( int )  AO_fetch_and_sub1_full ( & a - > value ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-09-08 15:43:44 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-08-29 20:24:46 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								static  inline  pa_bool_t  pa_atomic_cmpxchg ( pa_atomic_t  * a ,  int  old_i ,  int  new_i )  { 
							 
						 
					
						
							
								
									
										
										
										
											2008-08-20 03:33:06 +03:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    return  AO_compare_and_swap_full ( & a - > value ,  ( unsigned  long )  old_i ,  ( unsigned  long )  new_i ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-09-08 15:43:44 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								typedef  struct  pa_atomic_ptr  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    volatile  AO_t  value ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								}  pa_atomic_ptr_t ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-10-28 19:13:50 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								# define PA_ATOMIC_PTR_INIT(v) { .value = (AO_t) (v) } 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-09-08 15:43:44 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								static  inline  void *  pa_atomic_ptr_load ( const  pa_atomic_ptr_t  * a )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    return  ( void * )  AO_load_full ( ( AO_t * )  & a - > value ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								static  inline  void  pa_atomic_ptr_store ( pa_atomic_ptr_t  * a ,  void  * p )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    AO_store_full ( & a - > value ,  ( AO_t )  p ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-08-29 20:24:46 +02:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								static  inline  pa_bool_t  pa_atomic_ptr_cmpxchg ( pa_atomic_ptr_t  * a ,  void  * old_p ,  void *  new_p )  { 
							 
						 
					
						
							
								
									
										
										
										
											2006-09-08 15:43:44 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								    return  AO_compare_and_swap_full ( & a - > value ,  ( AO_t )  old_p ,  ( AO_t )  new_p ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# endif 
 
							 
						 
					
						
							
								
									
										
										
										
											2007-10-28 19:13:50 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# endif