1 |
/* PEAK Library |
2 |
* @configure_input@ |
3 |
* |
4 |
* Intel IA-64 atomic operations for GCC |
5 |
* 32 bit version only (enough for libpeak) |
6 |
* |
7 |
* $Id: atomic.h.in,v 1.1 2007/05/24 12:46:41 mbuna Exp $ |
8 |
*/ |
9 |
#ifndef INCLUDED_PEAK_ATOMIC_H_ |
10 |
#define INCLUDED_PEAK_ATOMIC_H_ |
11 |
|
12 |
typedef __signed__ int __s32; |
13 |
typedef unsigned int __u32; |
14 |
|
15 |
typedef __signed__ long __s64; |
16 |
typedef unsigned long __u64; |
17 |
|
18 |
typedef struct { volatile __s32 counter; } peak_atomic_t; |
19 |
|
20 |
#define PEAK_ATOMIC_INIT(i) ((peak_atomic_t) { (i) }) |
21 |
|
22 |
#define peak_atomic_read(v) ((v)->counter) |
23 |
#define peak_atomic_set(v,i) (((v)->counter) = (i)) |
24 |
|
25 |
#define ia64_cmpxchg4_acq(ptr, new, old) \ |
26 |
({ \ |
27 |
__u64 ia64_intri_res; \ |
28 |
asm volatile ("mov ar.ccv=%0;;" :: "rO"(old)); \ |
29 |
asm volatile ("cmpxchg4.acq %0=[%1],%2,ar.ccv": \ |
30 |
"=r"(ia64_intri_res) : "r"(ptr), "r"(new) : "memory"); \ |
31 |
ia64_intri_res; \ |
32 |
}) |
33 |
|
34 |
|
35 |
/* PEAK calls */ |
36 |
|
37 |
static __inline__ void peak_atomic_add(int a, peak_atomic_t *v) |
38 |
{ |
39 |
__s32 old, new; |
40 |
|
41 |
do { |
42 |
old = peak_atomic_read(v); |
43 |
new = old + a; |
44 |
} while ((__s32)ia64_cmpxchg4_acq((__u32 *) (v), new, (__u32) (long) (old)) != old); |
45 |
} |
46 |
|
47 |
static __inline__ void peak_atomic_sub(int a, peak_atomic_t *v) |
48 |
{ |
49 |
__s32 old, new; |
50 |
|
51 |
do { |
52 |
old = peak_atomic_read(v); |
53 |
new = old - a; |
54 |
} while ((__s32)ia64_cmpxchg4_acq((__u32 *) (v), new, (__u32) (long) (old)) != old); |
55 |
} |
56 |
|
57 |
#define peak_atomic_inc(v) peak_atomic_add(1, (v)) |
58 |
#define peak_atomic_dec(v) peak_atomic_sub(1, (v)) |
59 |
|
60 |
#endif /* INCLUDED_PEAK_ATOMIC_H_ */ |