00001
00032 #ifndef GALOIS_RUNTIME_LL_SIMPLE_LOCK_H
00033 #define GALOIS_RUNTIME_LL_SIMPLE_LOCK_H
00034
00035 #include <cassert>
00036
00037 #include "CompilerSpecific.h"
00038
00039 namespace GaloisRuntime {
00040 namespace LL {
00041
00044 template<bool isALock>
00045 class SimpleLock;
00046
00047 template<>
00048 class SimpleLock<true> {
00049 volatile mutable int _lock;
00050 public:
00051 SimpleLock() : _lock() { }
00052
00053 inline void lock() const {
00054 int oldval;
00055 do {
00056 while (_lock != 0) {
00057 asmPause();
00058 }
00059 oldval = __sync_fetch_and_or(&_lock, 1);
00060 } while (oldval & 1);
00061 }
00062
00063 inline void unlock() const {
00064 assert(_lock);
00065 compilerBarrier();
00066 _lock = 0;
00067 }
00068
00069 inline bool try_lock() const {
00070 if (_lock != 0)
00071 return false;
00072 int oldval = __sync_fetch_and_or(&_lock, 1);
00073 return !(oldval & 1);
00074 }
00075 };
00076
00077 template<>
00078 class SimpleLock<false> {
00079 public:
00080 inline void lock() const {}
00081 inline void unlock() const {}
00082 inline bool try_lock() const { return true; }
00083 };
00084
00085
00086 void LockPairOrdered(SimpleLock<true>& L1, SimpleLock<true>& L2);
00087 bool TryLockPairOrdered(SimpleLock<true>& L1, SimpleLock<true>& L2);
00088 void UnLockPairOrdered(SimpleLock<true>& L1, SimpleLock<true>& L2);
00089 void LockPairOrdered(SimpleLock<false>& L1, SimpleLock<false>& L2);
00090 bool TryLockPairOrdered(SimpleLock<false>& L1, SimpleLock<false>& L2);
00091 void UnLockPairOrdered(SimpleLock<false>& L1, SimpleLock<false>& L2);
00092
00093 }
00094 }
00095
00096 #endif