Orocos Real-Time Toolkit
2.6.0
|
00001 /*************************************************************************** 00002 tag: Peter Soetens Mon Jan 10 15:59:15 CET 2005 oro_atomic.h 00003 00004 oro_atomic.h - description 00005 ------------------- 00006 begin : Mon January 10 2005 00007 copyright : (C) 2005 Peter Soetens 00008 email : peter.soetens@mech.kuleuven.ac.be 00009 00010 *************************************************************************** 00011 * This library is free software; you can redistribute it and/or * 00012 * modify it under the terms of the GNU General Public * 00013 * License as published by the Free Software Foundation; * 00014 * version 2 of the License. * 00015 * * 00016 * As a special exception, you may use this file as part of a free * 00017 * software library without restriction. Specifically, if other files * 00018 * instantiate templates or use macros or inline functions from this * 00019 * file, or you compile this file and link it with other files to * 00020 * produce an executable, this file does not by itself cause the * 00021 * resulting executable to be covered by the GNU General Public * 00022 * License. This exception does not however invalidate any other * 00023 * reasons why the executable file might be covered by the GNU General * 00024 * Public License. * 00025 * * 00026 * This library is distributed in the hope that it will be useful, * 00027 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 00028 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * 00029 * Lesser General Public License for more details. * 00030 * * 00031 * You should have received a copy of the GNU General Public * 00032 * License along with this library; if not, write to the Free Software * 00033 * Foundation, Inc., 59 Temple Place, * 00034 * Suite 330, Boston, MA 02111-1307 USA * 00035 * * 00036 ***************************************************************************/ 00037 00038 00039 00040 #include "../../rtt-config.h" 00041 #ifndef __ORO_ARCH_I386__ 00042 #define __ORO_ARCH_I386__ 00043 00044 #ifndef CONFIG_FORCE_UP 00045 #define ORO_LOCK "lock ; " 00046 #else 00047 #define ORO_LOCK "" 00048 #endif 00049 00050 typedef struct { volatile int counter; } oro_atomic_t; 00051 00052 #define ORO_ATOMIC_SETUP oro_atomic_set 00053 #define ORO_ATOMIC_CLEANUP(v) 00054 00055 #define oro_atomic_read(v) ((v)->counter) 00056 00057 #define oro_atomic_set(v,i) (((v)->counter) = (i)) 00058 00059 static __inline__ void oro_atomic_add( oro_atomic_t *v, int i) 00060 { 00061 __asm__ __volatile__( 00062 ORO_LOCK "addl %1,%0" 00063 :"=m" (v->counter) 00064 :"ir" (i), "m" (v->counter)); 00065 } 00066 00067 static __inline__ void oro_atomic_sub( oro_atomic_t *v, int i) 00068 { 00069 __asm__ __volatile__( 00070 ORO_LOCK "subl %1,%0" 00071 :"=m" (v->counter) 00072 :"ir" (i), "m" (v->counter)); 00073 } 00074 00075 static __inline__ void oro_atomic_inc(oro_atomic_t *v) 00076 { 00077 __asm__ __volatile__( 00078 ORO_LOCK "incl %0" 00079 :"=m" (v->counter) 00080 :"m" (v->counter)); 00081 } 00082 00083 static __inline__ void oro_atomic_dec(oro_atomic_t *v) 00084 { 00085 __asm__ __volatile__( 00086 ORO_LOCK "decl %0" 00087 :"=m" (v->counter) 00088 :"m" (v->counter)); 00089 } 00090 00091 static __inline__ int oro_atomic_dec_and_test(oro_atomic_t *v) 00092 { 00093 unsigned char c; 00094 00095 __asm__ __volatile__( 00096 ORO_LOCK "decl %0; sete %1" 00097 :"=m" (v->counter), "=qm" (c) 00098 :"m" (v->counter) : "memory"); 00099 return c != 0; 00100 } 00101 00102 static __inline__ int oro_atomic_inc_and_test(oro_atomic_t *v) 00103 { 00104 unsigned char c; 00105 00106 __asm__ __volatile__( 00107 ORO_LOCK "incl %0; sete %1" 00108 :"=m" (v->counter), "=qm" (c) 00109 :"m" (v->counter) : "memory"); 00110 return c != 0; 00111 } 00112 00113 #define smp_mb__before_oro_atomic_dec() barrier() 00114 #define smp_mb__after_oro_atomic_dec() barrier() 00115 #define smp_mb__before_oro_atomic_inc() barrier() 00116 #define smp_mb__after_oro_atomic_inc() barrier() 00117 00118 #ifndef CONFIG_FORCE_UP 00119 #define ORO_LOCK_PREFIX "lock ; " 00120 #else 00121 #define ORO_LOCK_PREFIX "" 00122 #endif 00123 00124 struct oro__xchg_dummy { unsigned long a[100]; }; 00125 #define oro__xg(x) ((struct oro__xchg_dummy *)(x)) 00126 00127 static inline unsigned long __oro_cmpxchg(volatile void *ptr, unsigned long old, 00128 unsigned long _new, int size) 00129 { 00130 unsigned long prev; 00131 switch (size) { 00132 case 1: 00133 __asm__ __volatile__(ORO_LOCK_PREFIX "cmpxchgb %b1,%2" 00134 : "=a"(prev) 00135 : "q"(_new), "m"(*oro__xg(ptr)), "0"(old) 00136 : "memory"); 00137 return prev; 00138 case 2: 00139 __asm__ __volatile__(ORO_LOCK_PREFIX "cmpxchgw %w1,%2" 00140 : "=a"(prev) 00141 : "q"(_new), "m"(*oro__xg(ptr)), "0"(old) 00142 : "memory"); 00143 return prev; 00144 case 4: 00145 __asm__ __volatile__(ORO_LOCK_PREFIX "cmpxchgl %1,%2" 00146 : "=a"(prev) 00147 : "q"(_new), "m"(*oro__xg(ptr)), "0"(old) 00148 : "memory"); 00149 return prev; 00150 } 00151 return old; 00152 } 00153 00154 #define oro_cmpxchg(ptr,o,n)\ 00155 ((__typeof__(*(ptr)))__oro_cmpxchg((ptr),(unsigned long)(o),\ 00156 (unsigned long)(n),sizeof(*(ptr)))) 00157 00158 #undef ORO_LOCK 00159 #undef ORO_LOCK_PREFIX 00160 #endif