00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #ifndef AMINO_LIST_H
00018 #define AMINO_LIST_H
00019 #include <iostream>
00020 #include <stdexcept>
00021 #include <iterator>
00022 #include "smr.h"
00023
00024 namespace amino {
00025
00026
00027 using namespace internal;
00028
00029
00030
00031 #define NHPOINTER 3
00032
00033 #define POINTER(p) ((NodeType<KeyType>*)(((long)(p))&(~3)))
00034
00035 #define MARK(p) ((NodeType<KeyType>*)(((long)(p))|(1)))
00036
00037 #define MARKED(p) (((long)(p))&(1))
00038
00045 template<typename KeyType> class NodeType {
00046 public:
00047
00048 KeyType data;
00049
00050
00051 atomic<NodeType<KeyType>*> next;
00052
00056 NodeType() {
00057 next.store(NULL, memory_order_relaxed);
00058 }
00059
00065 NodeType(const KeyType& val) :
00066 data(val) {
00067 next.store(NULL);
00068 }
00069 };
00070
00078 template<typename KeyType> class FindStateHolder {
00079 public:
00080 atomic<NodeType<KeyType>*>* prev;
00081 NodeType<KeyType>* cur;
00082 NodeType<KeyType>* next;
00083 bool isFound;
00084
00085 FindStateHolder() :
00086 prev(NULL), cur(NULL), next(NULL), isFound(false) {
00087 }
00088 };
00089
00095 template<typename T> struct __list_iterator {
00096 typedef __list_iterator<T> _Self;
00097 typedef NodeType<T> _Node;
00098
00099 typedef ptrdiff_t difference_type;
00100 typedef std::forward_iterator_tag iterator_category;
00101 typedef T value_type;
00102 typedef T* pointer;
00103 typedef T& reference;
00104
00105 NodeType<T>* node;
00106
00107 __list_iterator(_Node* x) :
00108 node(x) {
00109 }
00110
00111 __list_iterator(const _Self& x) :
00112 node(x.node) {
00113 }
00114
00115 __list_iterator() {
00116 }
00117
00118 _Self& operator ++() {
00119 node = node->next.load(memory_order_relaxed);
00120 return *this;
00121 }
00122
00123 _Self operator ++(int) {
00124 _Self tmp = *this;
00125 ++*this;
00126 return tmp;
00127 }
00128
00129 bool operator ==(const _Self & x) const {
00130 return node == x.node;
00131 }
00132 bool operator !=(const _Self & x) const {
00133 return node != x.node;
00134 }
00135
00136 reference operator *() const {
00137 return node->data;
00138 }
00139
00140 pointer operator ->() const {
00141 return &(node->data);
00142 }
00143
00144 };
00145
00151 template<typename T> struct __list_const_iterator {
00152 typedef __list_const_iterator<T> _Self;
00153 typedef const NodeType<T> _Node;
00154 typedef __list_iterator<T> iterator;
00155
00156 typedef ptrdiff_t difference_type;
00157 typedef std::forward_iterator_tag iterator_category;
00158 typedef T value_type;
00159 typedef const T* pointer;
00160 typedef const T& reference;
00161
00162 const NodeType<T>* node;
00163
00164 __list_const_iterator(const _Node* x) :
00165 node(x) {
00166 }
00167
00168 __list_const_iterator(const _Self& x) :
00169 node(x.node) {
00170 }
00171
00172 __list_const_iterator(const iterator& x)
00173 : node(x.node) { }
00174
00175 __list_const_iterator() {
00176 }
00177
00178 _Self& operator ++() {
00179 node = node->next.load(memory_order_relaxed);
00180 return *this;
00181 }
00182
00183 _Self operator ++(int) {
00184 _Self tmp = *this;
00185 ++*this;
00186 return tmp;
00187 }
00188
00189 bool operator ==(const _Self & x) const {
00190 return node == x.node;
00191 }
00192 bool operator !=(const _Self & x) const {
00193 return node != x.node;
00194 }
00195
00196 reference operator *() const {
00197 return node->data;
00198 }
00199
00200 pointer operator ->() const {
00201 return &(node->data);
00202 }
00203
00204 };
00205
00206 template<typename T>
00207 inline bool operator==(const __list_iterator<T>& lhs,
00208 const __list_const_iterator<T>& rhs) {
00209 return lhs.node == rhs.node;
00210 }
00211
00212 template<typename T>
00213 inline bool operator!=(const __list_iterator<T>& lhs,
00214 const __list_const_iterator<T>& rhs) {
00215 return lhs.node != rhs.node;
00216 }
00217
00249 template<typename KeyType>
00250 class List {
00251 public:
00252 typedef __list_iterator<KeyType> iterator;
00253 typedef __list_const_iterator<KeyType> const_iterator;
00254
00255 protected:
00259 atomic<NodeType<KeyType>*> head;
00263 NodeType<KeyType>* dummy;
00264
00268 SMR<NodeType<KeyType>, NHPOINTER>* mm;
00269 typedef typename SMR<NodeType<KeyType>, NHPOINTER>::HP_Rec HazardP;
00270
00271
00272 List(const List& s) {
00273 }
00274
00275 List& operator=(const List& st) {
00276 }
00277
00278 public:
00282 List() {
00283 mm = getSMR<NodeType<KeyType> , NHPOINTER> ();
00284 dummy = new NodeType<KeyType> ();
00285 head.store(dummy->next.load(memory_order_relaxed), memory_order_relaxed);
00286 }
00287
00291 ~List() {
00292 NodeType<KeyType>* tmp = head.load();
00293 while (tmp != NULL) {
00294 NodeType<KeyType>*tmp_keep = tmp;
00295 tmp = tmp_keep->next.load(memory_order_relaxed);
00296 delete tmp_keep;
00297 }
00298
00299 delete dummy;
00300 }
00301
00311 bool front(KeyType& ret) {
00312 NodeType<KeyType>* first = head.load(memory_order_relaxed);
00313 if (first == NULL)
00314 return false;
00315 ret = first->data;
00316 return true;
00317 }
00318
00330 bool insert(int index, const KeyType& e) {
00331 return add(e);
00332 }
00333
00334 iterator begin() {
00335 return iterator(head.load(memory_order_relaxed));
00336 }
00337
00338 iterator end() {
00339 return iterator(NULL);
00340 }
00341
00342 const_iterator begin() const {
00343 return const_iterator(head.load(memory_order_relaxed));
00344 }
00345
00346 const_iterator end() const {
00347 return const_iterator(NULL);
00348 }
00349
00356 int size() {
00357 int ret = 0;
00358 NodeType<KeyType>* curr = head.load(memory_order_relaxed);
00359 while (curr != NULL) {
00360 ++ret;
00361 curr = curr->next.load(memory_order_relaxed);
00362 }
00363 return ret;
00364 }
00365
00374 bool push_front(const KeyType& e) {
00375 return add(e);
00376 }
00377
00384 bool empty() {
00385 return head.load(memory_order_relaxed) == NULL;
00386 }
00387
00396 bool remove(const KeyType& e) {
00397 return remove(e, &head);
00398 }
00399
00408 bool search(const KeyType& e) {
00409 return search(e, &head);
00410 }
00411
00412 private:
00421 bool add(const KeyType& e) {
00422 NodeType<KeyType>* node = new NodeType<KeyType> (e);
00423 bool result;
00424
00425 while (true) {
00426
00427
00428 NodeType<KeyType>* cur = POINTER(head.load(memory_order_relaxed));
00429
00430 node->next.store(cur, memory_order_relaxed);
00431
00437 if (head.compare_swap(cur, node)) {
00438 result = true;
00439 break;
00440 }
00441 }
00442 return result;
00443 }
00444
00455 bool search(const KeyType& e, atomic<NodeType<KeyType>*>* start) {
00456 FindStateHolder<KeyType> holder = FindStateHolder<KeyType> ();
00457 bool result = find(e, start, holder);
00458 retireAll();
00459 return result;
00460 }
00461
00472 bool remove(const KeyType& e, atomic<NodeType<KeyType>*>* start) {
00473 FindStateHolder<KeyType> holder = FindStateHolder<KeyType> ();
00474 bool result;
00475 HazardP * hp = mm->getHPRec();
00476
00477 while (true) {
00478 if (!find(e, start, holder)) {
00479 result = false;
00480 break;
00481 }
00482 atomic<NodeType<KeyType>*>* prev = holder.prev;
00483 NodeType<KeyType>* cur = holder.cur;
00484 NodeType<KeyType>* next = holder.next;
00485
00486
00487
00488
00489
00490
00491
00492 if (!cur->next.compare_swap(next, MARK(next))) {
00493 continue;
00494 }
00495
00496
00497
00498
00499
00500
00501
00502
00503 if (prev->compare_swap(cur, next)) {
00504 mm->delNode(hp, cur);
00505 } else {
00506 find(e, &head, holder);
00507 }
00508 result = true;
00509 break;
00510 }
00511 retireAll();
00512 return result;
00513 }
00514
00519 void retireAll() {
00520 HazardP * hp = mm->getHPRec();
00521 mm->retire(hp, 0);
00522 mm->retire(hp, 1);
00523 mm->retire(hp, 2);
00524 }
00525
00538 bool find(const KeyType& key, atomic<NodeType<KeyType>*>* start,
00539 FindStateHolder<KeyType>& holder) {
00540 HazardP * hp = mm->getHPRec();
00541
00542 try_again:
00543
00544 NodeType<KeyType>* next = NULL;
00545 atomic<NodeType<KeyType>*>* prev = start;
00546
00547 NodeType<KeyType>* cur = POINTER(prev->load());
00548 mm->employ(hp, 1, cur);
00549
00550 if (prev->load(memory_order_relaxed) != cur)
00551 goto try_again;
00552
00553 while (true) {
00554 if (NULL == cur) {
00555
00556 holder.isFound = false;
00557 holder.prev = prev;
00558 holder.cur = cur;
00559 holder.next = next;
00560 return false;
00561 }
00562
00563 NodeType<KeyType>* markedNext =
00564 cur->next.load(memory_order_relaxed);
00565 bool cmark = MARKED(markedNext);
00566 next = POINTER(markedNext);
00567
00568 mm->employ(hp, 0, next);
00569
00570 if (cur->next.load() != markedNext)
00571 goto try_again;
00572
00573 KeyType cKey = cur->data;
00574
00575 if (prev->load() != cur)
00576 goto try_again;
00577
00578 if (!cmark) {
00579 if (cKey == key) {
00580
00581 holder.isFound = true;
00582 holder.prev = prev;
00583 holder.cur = cur;
00584 holder.next = next;
00585 return true;
00586 }
00587 prev = &(cur->next);
00588 mm->employ(hp, 2, cur);
00589 } else {
00596 if (prev->compare_swap(cur, next)) {
00597 mm->delNode(hp, cur);
00598 } else {
00599 goto try_again;
00600 }
00601 }
00602
00603 cur = next;
00604 mm->employ(hp, 1, next);
00605 }
00606 }
00607
00608 };
00609
00610 }
00611 #endif