INTERFACE: template class stack_t; template class stack_top_t { private: friend class stack_t; // Dont change the layout !!, comp_and_swap2 expects // version and _next next to each other, in that order int _version; T *_next; }; template class stack_t { private: stack_top_t _head; }; IMPLEMENTATION: // // atomic-manipulation functions // // typesafe variants template inline bool compare_and_swap(I *ptr, I oldval, I newval) { return compare_and_swap(reinterpret_cast(ptr), *reinterpret_cast(&oldval), *reinterpret_cast(&newval)); } template inline bool test_and_set(I *l) { return test_and_set(reinterpret_cast(l)); } // // stack_top_t // // template // stack_top_t & // stack_top_t::operator=(const stack_top_t& _copy){ // _version = _copy._version; // _next = _copy._next; // return *this; // } PUBLIC inline template stack_top_t::stack_top_t (int version, T *next) : _version (version), _next (next) {} PUBLIC inline template stack_top_t::stack_top_t () : _version (0), _next (0) {} // // stack_t // PUBLIC template stack_t::stack_t() : _head (0, 0) {} PUBLIC template int stack_t::insert(T *e) { stack_top_t old_head, new_head; do { e->set_next(_head._next); old_head = _head; new_head._version = _head._version+1; new_head._next = e; } while (! compare_and_swap2((int *) &_head, (int *) &old_head, (int *) &new_head)); return new_head._version; } PUBLIC template T* stack_t::dequeue() { stack_top_t old_head, new_head; T *first; do { old_head = _head; first = _head._next; if(! first){ break; } new_head._next = first->get_next(); new_head._version = _head._version + 1; } while (! compare_and_swap2((int *) &_head, (int *) &old_head, (int *) &new_head)); // XXX Why did the old implementation test on e ? // while (e && ! compare_and_swap(&_first, e, e->list_property.next)); // This is necessary to handle the case of a empty stack. // return old_head._next; return first; } // This version of dequeue only returns a value // if it is equal to the one passed as top PUBLIC template T* stack_t::dequeue(T *top) { stack_top_t old_head, new_head; // stack_elem_t *first; old_head._version = _head._version; // version doesnt matter old_head._next = top; // cas will fail, if top aint at top if(!_head._next){ // empty stack return 0; } new_head._version = _head._version + 1; new_head._next = top->get_next(); if(! compare_and_swap2((int *) &_head, (int *) &old_head, (int *) &new_head)) // we didnt succeed return 0; else // top was on top , so we dequeued it return top; } PUBLIC template T* stack_t::first() { return _head._next; } PUBLIC template void stack_t::reset() { _head._version = 0; _head._next = 0; } template stack_t* create_stack() { return new stack_t(); } template <> stack_t* create_stack() { return new stack(); } template <> inline stack_t* create_stack() { return new stack(); } // // Member templates // class Foo { template T* goo(T* t); }; template class TFoo { }; PUBLIC template T* Foo::bar (T* t) { } IMPLEMENT template T* Foo::goo (T* t) { } PUBLIC template template T* TFoo::baz (T* t) { }