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