Go to the documentation of this file.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
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039 #ifndef __ORO_ARCH_I386__
00040 #define __ORO_ARCH_I386__
00041
00042 #ifndef CONFIG_FORCE_UP
00043 #define ORO_LOCK "lock ; "
00044 #else
00045 #define ORO_LOCK ""
00046 #endif
00047
00048 typedef struct
00049 {
00050 volatile int counter;
00051 } oro_atomic_t;
00052
00053 #define ORO_ATOMIC_SETUP oro_atomic_set
00054 #define ORO_ATOMIC_CLEANUP(v)
00055
00056 #define oro_atomic_read(v) ((v)->counter)
00057
00058 #define oro_atomic_set(v,i) (((v)->counter) = (i))
00059
00060 static __inline__ void oro_atomic_add(oro_atomic_t *v, int i)
00061 {
00062 __asm__ __volatile__(
00063 ORO_LOCK "addl %1,%0"
00064 :"=m" (v->counter)
00065 :"ir" (i), "m" (v->counter));
00066 }
00067
00068 static __inline__ void oro_atomic_sub(oro_atomic_t *v, int i)
00069 {
00070 __asm__ __volatile__(
00071 ORO_LOCK "subl %1,%0"
00072 :"=m" (v->counter)
00073 :"ir" (i), "m" (v->counter));
00074 }
00075
00076 static __inline__ void oro_atomic_inc(oro_atomic_t *v)
00077 {
00078 __asm__ __volatile__(
00079 ORO_LOCK "incl %0"
00080 :"=m" (v->counter)
00081 :"m" (v->counter));
00082 }
00083
00084 static __inline__ void oro_atomic_dec(oro_atomic_t *v)
00085 {
00086 __asm__ __volatile__(
00087 ORO_LOCK "decl %0"
00088 :"=m" (v->counter)
00089 :"m" (v->counter));
00090 }
00091
00092 static __inline__ int oro_atomic_dec_and_test(oro_atomic_t *v)
00093 {
00094 unsigned char c;
00095
00096 __asm__ __volatile__(
00097 ORO_LOCK "decl %0; sete %1"
00098 :"=m" (v->counter), "=qm" (c)
00099 :"m" (v->counter) : "memory");
00100 return c != 0;
00101 }
00102
00103 static __inline__ int oro_atomic_inc_and_test(oro_atomic_t *v)
00104 {
00105 unsigned char c;
00106
00107 __asm__ __volatile__(
00108 ORO_LOCK "incl %0; sete %1"
00109 :"=m" (v->counter), "=qm" (c)
00110 :"m" (v->counter) : "memory");
00111 return c != 0;
00112 }
00113
00114 #define smp_mb__before_oro_atomic_dec() barrier()
00115 #define smp_mb__after_oro_atomic_dec() barrier()
00116 #define smp_mb__before_oro_atomic_inc() barrier()
00117 #define smp_mb__after_oro_atomic_inc() barrier()
00118
00119 #ifndef CONFIG_FORCE_UP
00120 #define ORO_LOCK_PREFIX "lock ; "
00121 #else
00122 #define ORO_LOCK_PREFIX ""
00123 #endif
00124
00125 struct oro__xchg_dummy
00126 {
00127 unsigned long a[100];
00128 };
00129 #define oro__xg(x) ((struct oro__xchg_dummy *)(x))
00130
00131 static inline unsigned long __oro_cmpxchg(volatile void *ptr, unsigned long old, unsigned long _new, int size)
00132 {
00133 unsigned long prev;
00134 switch (size)
00135 {
00136 case 1:
00137 __asm__ __volatile__(ORO_LOCK_PREFIX "cmpxchgb %b1,%2"
00138 : "=a"(prev)
00139 : "q"(_new), "m"(*oro__xg(ptr)), "0"(old)
00140 : "memory");
00141 return prev;
00142 case 2:
00143 __asm__ __volatile__(ORO_LOCK_PREFIX "cmpxchgw %w1,%2"
00144 : "=a"(prev)
00145 : "q"(_new), "m"(*oro__xg(ptr)), "0"(old)
00146 : "memory");
00147 return prev;
00148 case 4:
00149 __asm__ __volatile__(ORO_LOCK_PREFIX "cmpxchgl %1,%2"
00150 : "=a"(prev)
00151 : "q"(_new), "m"(*oro__xg(ptr)), "0"(old)
00152 : "memory");
00153 return prev;
00154 }
00155 return old;
00156 }
00157
00158 #define oro_cmpxchg(ptr,o,n)\
00159 ((__typeof__(*(ptr)))__oro_cmpxchg((ptr),(unsigned long)(o),\
00160 (unsigned long)(n),sizeof(*(ptr))))
00161
00162 #undef ORO_LOCK
00163 #undef ORO_LOCK_PREFIX
00164 #endif