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