Orocos Real-Time Toolkit  2.9.0
oro_arch.h
Go to the documentation of this file.
1 /***************************************************************************
2  tag: Peter Soetens Mon Jan 10 15:59:15 CET 2005 oro_atomic.h
3 
4  oro_atomic.h - description
5  -------------------
6  begin : Mon January 10 2005
7  copyright : (C) 2005 Peter Soetens
8  email : peter.soetens@mech.kuleuven.ac.be
9 
10  ***************************************************************************
11  * This library is free software; you can redistribute it and/or *
12  * modify it under the terms of the GNU General Public *
13  * License as published by the Free Software Foundation; *
14  * version 2 of the License. *
15  * *
16  * As a special exception, you may use this file as part of a free *
17  * software library without restriction. Specifically, if other files *
18  * instantiate templates or use macros or inline functions from this *
19  * file, or you compile this file and link it with other files to *
20  * produce an executable, this file does not by itself cause the *
21  * resulting executable to be covered by the GNU General Public *
22  * License. This exception does not however invalidate any other *
23  * reasons why the executable file might be covered by the GNU General *
24  * Public License. *
25  * *
26  * This library is distributed in the hope that it will be useful, *
27  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
28  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
29  * Lesser General Public License for more details. *
30  * *
31  * You should have received a copy of the GNU General Public *
32  * License along with this library; if not, write to the Free Software *
33  * Foundation, Inc., 59 Temple Place, *
34  * Suite 330, Boston, MA 02111-1307 USA *
35  * *
36  ***************************************************************************/
37 
38 
39 
40 #include "../../rtt-config.h"
41 #ifndef __ORO_ARCH_x86_64__
42 #define __ORO_ARCH_x86_64__
43 
44 #ifndef CONFIG_FORCE_UP
45 #define ORO_LOCK "lock ; "
46 #else
47 #define ORO_LOCK ""
48 #endif
49 
50 typedef struct { volatile int counter; } oro_atomic_t;
51 
52 #define ORO_ATOMIC_SETUP oro_atomic_set
53 #define ORO_ATOMIC_CLEANUP(v)
54 
55 #define oro_atomic_read(v) ((v)->counter)
56 
57 #define oro_atomic_set(v,i) (((v)->counter) = (i))
58 
59 static __inline__ void oro_atomic_add(oro_atomic_t *v, int i)
60 {
61  __asm__ __volatile__(
62  ORO_LOCK "addl %1,%0"
63  :"=m" (v->counter)
64  :"ir" (i), "m" (v->counter));
65 }
66 
67 static __inline__ int oro_atomic_add_return(oro_atomic_t *v, int i)
68 {
69  int __i = i;
70  __asm__ __volatile__(
71  ORO_LOCK "xaddl %0, %1"
72  : "+r" (i), "+m" (v->counter)
73  : : "memory");
74  return i + __i;
75 }
76 
77 static __inline__ void oro_atomic_sub(oro_atomic_t *v, int i)
78 {
79  __asm__ __volatile__(
80  ORO_LOCK "subl %1,%0"
81  :"=m" (v->counter)
82  :"ir" (i), "m" (v->counter));
83 }
84 
85 static __inline__ int oro_atomic_sub_return(oro_atomic_t *v, int i)
86 {
87  return oro_atomic_add_return(v, -i);
88 }
89 
91 {
92  unsigned char c;
93 
94  __asm__ __volatile__(
95  ORO_LOCK "subl %2,%0; sete %1"
96  :"=m" (v->counter), "=qm" (c)
97  :"ir" (i), "m" (v->counter) : "memory");
98  return c;
99 }
100 
101 static __inline__ void oro_atomic_inc(oro_atomic_t *v)
102 {
103  __asm__ __volatile__(
104  ORO_LOCK "incl %0"
105  :"=m" (v->counter)
106  :"m" (v->counter));
107 }
108 
109 static __inline__ void oro_atomic_dec(oro_atomic_t *v)
110 {
111  __asm__ __volatile__(
112  ORO_LOCK "decl %0"
113  :"=m" (v->counter)
114  :"m" (v->counter));
115 }
116 
117 #define oro_atomic_inc_return(v) (oro_atomic_add_return(v, 1))
118 #define oro_atomic_dec_return(v) (oro_atomic_sub_return(v, 1))
119 
121 {
122  unsigned char c;
123 
124  __asm__ __volatile__(
125  ORO_LOCK "decl %0; sete %1"
126  :"=m" (v->counter), "=qm" (c)
127  :"m" (v->counter) : "memory");
128  return c != 0;
129 }
130 
132 {
133  unsigned char c;
134 
135  __asm__ __volatile__(
136  ORO_LOCK "incl %0; sete %1"
137  :"=m" (v->counter), "=qm" (c)
138  :"m" (v->counter) : "memory");
139  return c != 0;
140 }
141 
142 static __inline__ int oro_atomic_add_negative(int i, oro_atomic_t *v)
143 {
144  unsigned char c;
145 
146  __asm__ __volatile__(
147  ORO_LOCK "addl %2,%0; sets %1"
148  :"=m" (v->counter), "=qm" (c)
149  :"ir" (i), "m" (v->counter) : "memory");
150  return c;
151 }
152 
153 #ifndef CONFIG_FORCE_UP
154 #define ORO_LOCK_PREFIX "lock ; "
155 #else
156 #define ORO_LOCK_PREFIX ""
157 #endif
158 
159 struct oro__xchg_dummy { unsigned long a[100]; };
160 #define oro__xg(x) ((struct oro__xchg_dummy *)(x))
161 
162 static inline unsigned long __oro_cmpxchg(volatile void *ptr, unsigned long old,
163  unsigned long _new, int size)
164 {
165  unsigned long prev;
166  switch (size) {
167  case 1:
168  __asm__ __volatile__(ORO_LOCK_PREFIX "cmpxchgb %b1,%2"
169  : "=a"(prev)
170  : "q"(_new), "m"(*oro__xg(ptr)), "0"(old)
171  : "memory");
172  return prev;
173  case 2:
174  __asm__ __volatile__(ORO_LOCK_PREFIX "cmpxchgw %w1,%2"
175  : "=a"(prev)
176  : "q"(_new), "m"(*oro__xg(ptr)), "0"(old)
177  : "memory");
178  return prev;
179  case 4:
180  __asm__ __volatile__(ORO_LOCK_PREFIX "cmpxchgl %k1,%2"
181  : "=a"(prev)
182  : "q"(_new), "m"(*oro__xg(ptr)), "0"(old)
183  : "memory");
184  return prev;
185  case 8:
186  __asm__ __volatile__(ORO_LOCK_PREFIX "cmpxchgq %1,%2"
187  : "=a"(prev)
188  : "q"(_new), "m"(*oro__xg(ptr)), "0"(old)
189  : "memory");
190  return prev;
191 
192  }
193  return old;
194 }
195 
196 #define oro_cmpxchg(ptr,o,n)\
197  ((__typeof__(*(ptr)))__oro_cmpxchg((ptr),(unsigned long)(o),\
198  (unsigned long)(n),sizeof(*(ptr))))
199 
200 #undef ORO_LOCK_PREFIX
201 #undef ORO_LOCK
202 #endif
#define oro__xg(x)
Definition: oro_arch.h:160
unsigned long a[100]
Definition: oro_arch.h:143
int oro_atomic_inc_and_test(oro_atomic_t *a)
Increment a atomically and test for zero.
int oro_atomic_sub_return(int n, oro_atomic_t *a, int n)
Subtract n from a and return the new value.
volatile int counter
Definition: oro_arch.h:50
#define ORO_LOCK_PREFIX
Definition: oro_arch.h:154
void oro_atomic_inc(oro_atomic_t *a)
Increment a atomically.
#define __inline__
Definition: oro_arch.h:52
volatile long oro_atomic_t
Definition: oro_arch.h:9
void oro_atomic_sub(int n, oro_atomic_t *a, int n)
Subtract n from a.
int oro_atomic_dec_and_test(oro_atomic_t *a)
Decrement a atomically and test for zero.
int oro_atomic_sub_and_test(oro_atomic_t *a, int n)
Subtract n from a and test for zero.
#define oro_atomic_add_negative(a, v)
Definition: oro_atomic.h:160
#define ORO_LOCK
Definition: oro_arch.h:45
void oro_atomic_dec(oro_atomic_t *a)
Decrement a atomically.
Structure that contains an int for atomic operations.
Definition: oro_arch.h:10
int oro_atomic_add_return(oro_atomic_t *a, int n)
Add n to a and return the new value.
void oro_atomic_add(oro_atomic_t *a, int n)
Add n to a.