/*
* umpsc_que.h, a modification version to Dmitriy's unbounded MPSC
queue
*
* Created on: 2011-12-12
* Author: xia...@gmail.com
*/
struct que_node
{
que_node* _next;
};
struct umpsc_que
{
public:
typedef que_node node_type;
umpsc_que() : _writer(&_header)
{
}
void push_back(node_type* node) // always succ
{
node->_next = 0;
node_type* prev = (node_type*)XCHG(&_writer, node);
prev->_next = node;
}
node_type* pop_front()
{
if(empty()) { return 0; }
node_type* r = _header._next;
if(r == _writer) {
_header._next = 0;
if(CAS(&_writer, r, &_header)) { return r; }
}
if(r->_next) {
_header._next = r->_next;
return r;
} else { // in-consistant state
_header._next = r;
return 0;
}
}
bool empty() const { return _header._next == 0; }
node_type* front() const { return _header._next; }
protected:
node_type* _writer;
char _pad[128 - sizeof(node_type*)];
node_type _header;
};
Update the soruce code, and now the pop() operation is quite simple: