diff options
author | Glenn Elliott <gelliott@cs.unc.edu> | 2014-06-05 13:42:09 -0400 |
---|---|---|
committer | Glenn Elliott <gelliott@cs.unc.edu> | 2014-06-05 13:55:46 -0400 |
commit | 5fc66f0da674fcfd927378884cee8048c70fdf4a (patch) | |
tree | 38e4b037e16984e2ecd93ab26df08576be4ac4b3 | |
parent | 2d9a2d4839d0358aeb4f4787c34664cb92b25bdb (diff) |
Replace x86 membarriers with GCC built-ins
This patch replaces the x86 asm memory barriers with
mostly platform-independent GCC built-ins. Beware though:
I've once seen __sync_synchronize() fail to generate
a barrier on MacOS X (Darwin)---maybe it could happen
again on another platform.
-rw-r--r-- | include/atomic.h | 13 | ||||
-rw-r--r-- | include/ticketlock.h | 16 |
2 files changed, 22 insertions, 7 deletions
diff --git a/include/atomic.h b/include/atomic.h new file mode 100644 index 0000000..ec5c09c --- /dev/null +++ b/include/atomic.h | |||
@@ -0,0 +1,13 @@ | |||
1 | // Copyright (c) 2014, Glenn Elliott | ||
2 | // All rights reserved. | ||
3 | |||
4 | #pragma once | ||
5 | |||
6 | static inline void __sync_pause() | ||
7 | { | ||
8 | #if (ARCH == x86_64) || (ARCH == i386) || (ARCH == i686) | ||
9 | asm volatile("pause": : :"memory"); | ||
10 | #else | ||
11 | __sync_synchronize(); | ||
12 | #endif | ||
13 | } | ||
diff --git a/include/ticketlock.h b/include/ticketlock.h index 17e5000..4c1035c 100644 --- a/include/ticketlock.h +++ b/include/ticketlock.h | |||
@@ -13,6 +13,8 @@ | |||
13 | #include "litmus.h" | 13 | #include "litmus.h" |
14 | #endif | 14 | #endif |
15 | 15 | ||
16 | #include "atomic.h" | ||
17 | |||
16 | #if ULONG_MAX == 0xffffffffffffffffUL | 18 | #if ULONG_MAX == 0xffffffffffffffffUL |
17 | typedef unsigned long long ticketdata_t; | 19 | typedef unsigned long long ticketdata_t; |
18 | typedef uint32_t ticketid_t; | 20 | typedef uint32_t ticketid_t; |
@@ -45,8 +47,8 @@ static inline void __tl_lock(ticketlock_t* t) | |||
45 | ticketlock_t updated = { __sync_fetch_and_add(&t->data, TL_INC) }; | 47 | ticketlock_t updated = { __sync_fetch_and_add(&t->data, TL_INC) }; |
46 | if(updated.next != updated.owner) | 48 | if(updated.next != updated.owner) |
47 | while(updated.next != t->owner) | 49 | while(updated.next != t->owner) |
48 | asm volatile("pause": : :"memory"); | 50 | __sync_pause(); |
49 | asm volatile("mfence": : :"memory"); | 51 | __sync_synchronize(); |
50 | } | 52 | } |
51 | 53 | ||
52 | static inline void tl_lock(ticketlock_t* t) | 54 | static inline void tl_lock(ticketlock_t* t) |
@@ -56,7 +58,7 @@ static inline void tl_lock(ticketlock_t* t) | |||
56 | 58 | ||
57 | static inline void __tl_unlock(ticketlock_t* t) | 59 | static inline void __tl_unlock(ticketlock_t* t) |
58 | { | 60 | { |
59 | asm volatile("mfence": : :"memory"); | 61 | __sync_synchronize(); |
60 | __sync_fetch_and_add(&t->owner, (ticketid_t)1); | 62 | __sync_fetch_and_add(&t->owner, (ticketid_t)1); |
61 | } | 63 | } |
62 | 64 | ||
@@ -95,9 +97,9 @@ static inline void tl_lock_np(ticketlock_t* t, unsigned long* flags) | |||
95 | asm volatile("cli": : :"memory"); | 97 | asm volatile("cli": : :"memory"); |
96 | #elif defined(PGM_NP_LITMUS) | 98 | #elif defined(PGM_NP_LITMUS) |
97 | /* start non-preemption */ | 99 | /* start non-preemption */ |
98 | asm volatile("mfence": : :"memory"); | 100 | __sync_synchronize(); |
99 | enter_np(); | 101 | enter_np(); |
100 | asm volatile("mfence": : :"memory"); | 102 | __sync_synchronize(); |
101 | #endif | 103 | #endif |
102 | 104 | ||
103 | __tl_lock(t); | 105 | __tl_lock(t); |
@@ -112,9 +114,9 @@ static inline void tl_unlock_np(ticketlock_t* t, unsigned long flags) | |||
112 | restore_flags(flags); | 114 | restore_flags(flags); |
113 | #elif defined(PGM_NP_LITMUS) | 115 | #elif defined(PGM_NP_LITMUS) |
114 | /* end non-preemption */ | 116 | /* end non-preemption */ |
115 | asm volatile("mfence": : :"memory"); | 117 | __sync_synchronize(); |
116 | exit_np(); | 118 | exit_np(); |
117 | asm volatile("mfence": : :"memory"); | 119 | __sync_synchronize(); |
118 | #endif | 120 | #endif |
119 | } | 121 | } |
120 | #endif | 122 | #endif |