]> rtime.felk.cvut.cz Git - l4.git/blob - kernel/fiasco/src/lib/libk/ia32/atomic-ia32-smp.cpp
20b5a56b78e69a6c445bc22b3d1741ad42b9f981
[l4.git] / kernel / fiasco / src / lib / libk / ia32 / atomic-ia32-smp.cpp
1 IMPLEMENTATION [ia32]:
2
3 // ``unsafe'' stands for no safety according to the size of the given type.
4 // There are type safe versions of the cas operations in the architecture
5 // independent part of atomic that use the unsafe versions and make a type
6 // check.
7
8 inline 
9 bool
10 cas_unsafe (Mword *ptr, Mword oldval, Mword newval)
11 {
12   Mword tmp;
13
14   asm volatile
15     ("lock; cmpxchgl %1,%2"
16      : "=a" (tmp)
17      : "r" (newval), "m" (*ptr), "0" (oldval)
18      : "memory");
19
20   return tmp == oldval;
21 }
22
23 inline 
24 bool
25 cas2_unsafe (Mword *ptr, Mword *oldval, Mword *newval)
26 {
27   char ret;
28   asm volatile
29     ("lock; cmpxchg8b %3 ; sete %%cl"
30      : "=c" (ret),
31        "=a" (* oldval),
32        "=d" (*(oldval+1))
33      : "m" (*ptr) ,
34        "1" (* oldval),
35        "2" (*(oldval+1)), 
36        "b" (* newval),
37        "0" (*(newval+1))
38      : "memory");
39
40   return ret;
41 }
42
43 inline 
44 bool
45 tas (Mword *l)
46 {
47   Mword tmp;
48   asm volatile
49     ("xchg %0,%1" : "=r" (tmp) : "m" (*l), "0" (1) : "memory");
50
51   return tmp;
52 }
53
54 template <typename T> inline
55 atomic_and (Mword *l, Mword bits)
56 {
57   T old;
58   do { old = *p; }
59   while (!cas (p, old, old & value));
60 }
61
62 template <typename T> inline
63 atomic_or (Mword *l, Mword bits)
64 {
65   T old;
66   do { old = *p; }
67   while (!cas (p, old, old | value));      
68 }
69
70 template <typename T> inline
71 void atomic_change(T *p, T mask, T bits)
72 {
73   T old;
74   do { old = *p; }
75   while (!cas (p, old, (old & mask) | bits));
76 }
77