diff options
author | Patrick Williams <iawillia@us.ibm.com> | 2010-05-21 15:36:32 -0500 |
---|---|---|
committer | Patrick Williams <iawillia@us.ibm.com> | 2010-05-21 15:36:32 -0500 |
commit | 343cc75d83b7d71a23adb49e0d530eb59997a154 (patch) | |
tree | 682443404e9cec863db8d34dad9401c333b5a65e /src | |
parent | 8781b20afef41280e351d087bc05f6626e95cbda (diff) | |
download | talos-hostboot-343cc75d83b7d71a23adb49e0d530eb59997a154.tar.gz talos-hostboot-343cc75d83b7d71a23adb49e0d530eb59997a154.zip |
Add transaction counters to upper word of lockfree-stack head, to prevent ABA issues.
Diffstat (limited to 'src')
-rw-r--r-- | src/include/util/lockfree/stack.H | 24 |
1 files changed, 17 insertions, 7 deletions
diff --git a/src/include/util/lockfree/stack.H b/src/include/util/lockfree/stack.H index 8f884e072..a09c14ff9 100644 --- a/src/include/util/lockfree/stack.H +++ b/src/include/util/lockfree/stack.H @@ -23,11 +23,15 @@ namespace Util template <typename _T> _T* Stack<_T>::pop() { - _T * h = head; - if (NULL == h) return h; + _T * _head = head; + _T * h = (_T*) (((uint64_t)_head) & 0x00000000FFFFFFFF); + if (NULL == h) return h; + uint64_t token = ((uint64_t)_head) >> 32; + token++; + _T * h_next = (_T*) (((uint64_t)(h->next)) | (token << 32)); if (!__sync_bool_compare_and_swap(&head, - h, - h->next)) + _head, + h_next)) return pop(); return h; } @@ -35,10 +39,16 @@ namespace Util template <typename _T> void Stack<_T>::push(_T* p) { - p->next = head; + _T* _head = head; + p->next = (_T*) (((uint64_t)_head) & 0x00000000FFFFFFFF); + uint64_t token = ((uint64_t)_head) >> 32; + token++; + + _T* _p = (_T*) (((uint64_t)p) | (token << 32)); + if (!__sync_bool_compare_and_swap(&head, - p->next, - p)) + _head, + _p)) push(p); } } |