00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00031
00032 #ifndef __ATOMIC_H__
00033 #define __ATOMIC_H__
00034
00035 typedef struct { volatile int x; } mt_atomic_t;
00036
00037
00038 static inline void atomic_set(mt_atomic_t *at, int val)
00039 {
00040 at->x = val;
00041 }
00042
00043 static inline int atomic_get(mt_atomic_t *at)
00044 {
00045 return (at->x);
00046 }
00047
00048 #undef ATOMIC_DEFINED
00049
00050 #ifdef ATOMIC_X86_SMP
00051 #ifdef ATOMIC_X86
00052 #error ATOMIC_X86_SMP and ATOMIC_X86 are defined at the same time!
00053 #endif
00054 #define ASM_LOCK "lock; "
00055 #endif
00056
00057 #ifdef ATOMIC_X86
00058 #define ASM_LOCK
00059 #endif
00060
00061 #if defined(ATOMIC_X86_SMP) || defined(ATOMIC_X86)
00062 #define ATOMIC_DEFINED
00063 static inline void atomic_inc(mt_atomic_t *at)
00064 {
00065 __asm__ __volatile__(
00066 ASM_LOCK "incl %0"
00067 :"=m" (at->x)
00068 :"m" (at->x)
00069 :"cc"
00070 );
00071 }
00072
00073 static inline bool atomic_dec(mt_atomic_t *at)
00074 {
00075 unsigned char c;
00076 __asm__ __volatile__(
00077 ASM_LOCK "decl %0; sete %1"
00078 :"=m" (at->x), "=g" (c)
00079 :"m" (at->x)
00080 :"cc"
00081 );
00082 return (c!=0);
00083 }
00084 #endif
00085
00086 #ifdef ATOMIC_TORTURE
00087 #ifdef ATOMIC_DEFINED
00088 #error ATOMIC_X86(_SMP) and ATOMIC_TORTURE are defined at the same time!
00089 #else
00090 #define ATOMIC_DEFINED
00091 #endif
00092
00093
00094 static inline void atomic_inc(mt_atomic_t *at)
00095 {
00096 at->x++;
00097 }
00098
00099 static inline bool atomic_dec(mt_atomic_t *at)
00100 {
00101 return ((--at->x) == 0);
00102 }
00103 #endif
00104
00105 #ifndef ATOMIC_DEFINED
00106 #include <pthread.h>
00107 #define ATOMIC_NEED_MUTEX
00108 static inline void atomic_inc(mt_atomic_t *at, pthread_mutex_t *mutex)
00109 {
00110 pthread_mutex_lock(mutex);
00111 at->x++;
00112 pthread_mutex_unlock(mutex);
00113 }
00114 static inline bool atomic_dec(mt_atomic_t *at, pthread_mutex_t *mutex)
00115 {
00116 pthread_mutex_lock(mutex);
00117 int newval = (--at->x);
00118 pthread_mutex_unlock(mutex);
00119 return (newval == 0);
00120 }
00121 #else
00122 #undef ATOMIC_DEFINED
00123 #endif
00124
00125 #endif // __ATOMIC_H__