oro_atomic.h

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 __ARCH_I386_ORO_ATOMIC__
00042 #define __ARCH_I386_ORO_ATOMIC__
00043 
00044 /*
00045  * Atomic operations that C can't guarantee us.  Useful for
00046  * resource counting etc..
00047  */
00048 
00049 #ifndef CONFIG_FORCE_UP
00050 #define ORO_LOCK "lock ; "
00051 #else
00052 #define ORO_LOCK ""
00053 #endif
00054 
00055 /*
00056  * Make sure gcc doesn't try to be clever and move things around
00057  * on us. We need to use _exactly_ the address the user gave us,
00058  * not some alias that contains the same information.
00059  */
00060 typedef struct { volatile int counter; } oro_atomic_t;
00061 
00062 #define ORO_ATOMIC_INIT(i)  { (i) }
00063 #define ORO_ATOMIC_SETUP    oro_atomic_set
00064 #define ORO_ATOMIC_CLEANUP(v)   
00065 
00073 #define oro_atomic_read(v)      ((v)->counter)
00074 
00083 #define oro_atomic_set(v,i)     (((v)->counter) = (i))
00084 
00093 static __inline__ void oro_atomic_add(int i, oro_atomic_t *v)
00094 {
00095     __asm__ __volatile__(
00096         ORO_LOCK "addl %1,%0"
00097         :"=m" (v->counter)
00098         :"ir" (i), "m" (v->counter));
00099 }
00100 
00109 static __inline__ void oro_atomic_sub(int i, oro_atomic_t *v)
00110 {
00111     __asm__ __volatile__(
00112         ORO_LOCK "subl %1,%0"
00113         :"=m" (v->counter)
00114         :"ir" (i), "m" (v->counter));
00115 }
00116 
00127 static __inline__ int oro_atomic_sub_and_test(int i, oro_atomic_t *v)
00128 {
00129     unsigned char c;
00130 
00131     __asm__ __volatile__(
00132         ORO_LOCK "subl %2,%0; sete %1"
00133         :"=m" (v->counter), "=qm" (c)
00134         :"ir" (i), "m" (v->counter) : "memory");
00135     return c;
00136 }
00137 
00145 static __inline__ void oro_atomic_inc(oro_atomic_t *v)
00146 {
00147     __asm__ __volatile__(
00148         ORO_LOCK "incl %0"
00149         :"=m" (v->counter)
00150         :"m" (v->counter));
00151 }
00152 
00160 static __inline__ void oro_atomic_dec(oro_atomic_t *v)
00161 {
00162     __asm__ __volatile__(
00163         ORO_LOCK "decl %0"
00164         :"=m" (v->counter)
00165         :"m" (v->counter));
00166 }
00167 
00177 static __inline__ int oro_atomic_dec_and_test(oro_atomic_t *v)
00178 {
00179     unsigned char c;
00180 
00181     __asm__ __volatile__(
00182         ORO_LOCK "decl %0; sete %1"
00183         :"=m" (v->counter), "=qm" (c)
00184         :"m" (v->counter) : "memory");
00185     return c != 0;
00186 }
00187 
00197 static __inline__ int oro_atomic_inc_and_test(oro_atomic_t *v)
00198 {
00199     unsigned char c;
00200 
00201     __asm__ __volatile__(
00202         ORO_LOCK "incl %0; sete %1"
00203         :"=m" (v->counter), "=qm" (c)
00204         :"m" (v->counter) : "memory");
00205     return c != 0;
00206 }
00207 
00218 static __inline__ int oro_atomic_add_negative(int i, oro_atomic_t *v)
00219 {
00220     unsigned char c;
00221 
00222     __asm__ __volatile__(
00223         ORO_LOCK "addl %2,%0; sets %1"
00224         :"=m" (v->counter), "=qm" (c)
00225         :"ir" (i), "m" (v->counter) : "memory");
00226     return c;
00227 }
00228 
00229 /* These are x86-specific, used by some header files */
00230 #define oro_atomic_clear_mask(mask, addr) \
00231 __asm__ __volatile__(ORO_LOCK "andl %0,%1" \
00232 : : "r" (~(mask)),"m" (*addr) : "memory")
00233 
00234 #define oro_atomic_set_mask(mask, addr) \
00235 __asm__ __volatile__(ORO_LOCK "orl %0,%1" \
00236 : : "r" (mask),"m" (*(addr)) : "memory")
00237 
00238 /* Atomic operations are already serializing on x86 */
00239 #define smp_mb__before_oro_atomic_dec() barrier()
00240 #define smp_mb__after_oro_atomic_dec()  barrier()
00241 #define smp_mb__before_oro_atomic_inc() barrier()
00242 #define smp_mb__after_oro_atomic_inc()  barrier()
00243 
00244 #undef ORO_LOCK
00245 #endif
Generated on Thu Dec 23 13:22:38 2010 for Orocos Real-Time Toolkit by  doxygen 1.6.3