aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGlenn Elliott <gelliott@cs.unc.edu>2014-06-05 13:42:09 -0400
committerGlenn Elliott <gelliott@cs.unc.edu>2014-06-05 13:55:46 -0400
commit5fc66f0da674fcfd927378884cee8048c70fdf4a (patch)
tree38e4b037e16984e2ecd93ab26df08576be4ac4b3
parent2d9a2d4839d0358aeb4f4787c34664cb92b25bdb (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.h13
-rw-r--r--include/ticketlock.h16
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
6static 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
17typedef unsigned long long ticketdata_t; 19typedef unsigned long long ticketdata_t;
18typedef uint32_t ticketid_t; 20typedef 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
52static inline void tl_lock(ticketlock_t* t) 54static inline void tl_lock(ticketlock_t* t)
@@ -56,7 +58,7 @@ static inline void tl_lock(ticketlock_t* t)
56 58
57static inline void __tl_unlock(ticketlock_t* t) 59static 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