Exemple #1
0
	void push(stored_ptr &&new_data) {
		counted_node_ptr new_next{ 1, allocate_node() };
		counted_node_ptr old_tail = tail.load();
		for (;;) {
			increase_external_count(tail, old_tail);
			T* old_data = nullptr;
			if (old_tail.get()->data.compare_exchange_strong(old_data, new_data.get())) {
				counted_node_ptr old_next = { 0, nullptr };
				if (!old_tail.get()->next.compare_exchange_strong(old_next, new_next)) {
					deallocate_node(new_next.get());
					new_next = old_next;
				}
				set_new_tail(old_tail, new_next);
				new_data.release();
				break;
			}
			else {
				counted_node_ptr old_next = { 0, nullptr };
				if (old_tail.get()->next.compare_exchange_strong(old_next, new_next)) {
					old_next = new_next;
					new_next.set(allocate_node());
				}
				set_new_tail(old_tail, old_next);
			}
		}
	}
Exemple #2
0
	stored_ptr pop() {
		counted_node_ptr old_head = head.load(std::memory_order_relaxed);
		for (;;) {
			increase_external_count(head, old_head);
			node * const ptr = old_head.get();
			if (ptr == tail.load().get())
				return nullptr;

			counted_node_ptr next = ptr->next.load();
			if (head.compare_exchange_strong(old_head, next)) {
				T * const res = ptr->data.exchange(nullptr);
				free_external_counter(old_head);
				return stored_ptr(res);
			}

			if (!ptr->release_ref())
				deallocate_node(ptr);
		}
	}
Exemple #3
0
 std::unique_ptr<T> pop()
 {
     counted_node_ptr old_head=head.load(std::memory_order_relaxed);
     for(;;)
     {
         increase_external_count(head,old_head);
         node* const ptr=old_head.ptr;
         if(ptr==tail.load().ptr)
         {
             return std::unique_ptr<T>();
         }
         counted_node_ptr next=ptr->next.load();
         if(head.compare_exchange_strong(old_head,next))
         {
             T* const res=ptr->data.exchange(nullptr);
             free_external_counter(old_head);
             return std::unique_ptr<T>(res);
         }
         ptr->release_ref();
     }
 }