implement spinlock_t without atomic_t
authorAndrew Waterman <waterman@eecs.berkeley.edu>
Sat, 15 Dec 2012 05:18:58 +0000 (21:18 -0800)
committerAndrew Waterman <waterman@eecs.berkeley.edu>
Sat, 15 Dec 2012 05:18:58 +0000 (21:18 -0800)
on 64b architectures, there's no reason to use a 64b var for a 1b lock

user/parlib/include/spinlock.h
user/parlib/spinlock.c

index 6a80aa5..2bf061c 100644 (file)
 extern "C" {
 #endif
 
-#define SPINLOCK_LOCKED ((atomic_t)(1))
-#define SPINLOCK_UNLOCKED ((atomic_t)(0))
+#define SPINLOCK_INITIALIZER {0}
 
-typedef atomic_t spinlock_t;
+typedef struct {
+  int lock;
+} spinlock_t;
 
 void spinlock_init(spinlock_t *lock);
 int spinlock_trylock(spinlock_t *lock);
index 59ea0dc..9f9a455 100644 (file)
 void spinlock_init(spinlock_t *lock)
 {
   assert(lock);
-  *lock = SPINLOCK_UNLOCKED;
+  lock->lock = 0;
 }
 
-
 int spinlock_trylock(spinlock_t *lock) 
 {
   assert(lock);
-  if (*lock == SPINLOCK_LOCKED)
-    return EBUSY;
-
-  return (int)atomic_cas(lock, (long)SPINLOCK_LOCKED, (long)SPINLOCK_UNLOCKED);
+  return __sync_lock_test_and_set(&lock->lock, EBUSY);
 }
 
-
 void spinlock_lock(spinlock_t *lock) 
 {
   assert(lock);
-  while (spinlock_trylock(lock) != (int)SPINLOCK_UNLOCKED)
+  while (spinlock_trylock(lock))
     cpu_relax();
 }
 
@@ -52,5 +47,5 @@ void spinlock_lock(spinlock_t *lock)
 void spinlock_unlock(spinlock_t *lock) 
 {
   assert(lock);
-  *lock = SPINLOCK_UNLOCKED;
+  __sync_lock_release(&lock->lock, 0);
 }