/*多线程安全的队列*/
#ifndef FREELOCK_QUEUE_H_
#define FREELOCK_QUEUE_H_
#include <string.h>
template<class T,int NODELEN>
class freelock_queue {
struct queue_node {
T _queues[NODELEN];
char _states[NODELEN];
queue_node* _next;
int _head;
int _tail;
int _used;
};
public:
freelock_queue() {
_free_head = create_node();
_head = _free_head;
_tail = _free_head;
_count = 0;
}
~freelock_queue() {
queue_node* node;
while(_free_head) {
node = _free_head;
_free_head = _free_head->_next;
delete node;
}
}
inline void push(T vl) {
queue_node* ptr;
int index;
do { //try to get one position,and set the value at there.
ptr = _tail;
index = LOCK_ADD(ptr->_tail,1);
if(index < NODELEN-1) {
ptr->_queues[index] = vl;
ptr->_states[index] = 1;
} else if (index == NODELEN-1) {
ptr->_queues[index] = vl;
ptr->_states[index] = 1;
_tail->_next = create_node();
_tail = _tail->_next;
}
}while(index >= NODELEN);
LOCK_ADD(_count,1);
}
//return: 0 is OK
inline int pop(T& t) {
if(_count <= 0) {
return -1;
}
int index = LOCK_SUB(_count,1);
if(index <= 0) {
LOCK_ADD(_count,1);
return -1;
}
queue_node* ptr;
int index;
do { //try pop one value
ptr = _head;
index = LOCK_ADD(ptr->_head,1);
if(index < NODELEN)
{
while(ptr->_states[index] == 0) {}
t = ptr->_queues[index];
}
if(index == NODELEN-1)
{
while (_free_head->_used >= NODELEN && _free_head != _head )
{
T p = _free_head;
_free_head = _free_head->_next;
delete p;
}
if(index >= 0 && index < NODELEN){
LOCK_ADD(ptr->_used,1);
}
_head = _head->_next;
}
}while(index >= NODELEN);
return 0;
}
inline int size(){int n = _count; return n<0?0:n;}
private:
inline queue_node* create_node()
{
queue_node* node = new queue_node;
memset(node->_states,0,sizeof(node->_states));
node->_next = NULL;
node->_head = 0;
node->_tail = 0;
node->_used= 0;
return node;
}
private:
queue_node* _free_head;
queue_node* _head;
queue_node* _tail;
int _count;
};
#endif
//
class datavalue
{
public:
datavalue& operator = (datavalue& d)
{
_d1 = d._d1;
_d2 = d._d2;
return *this;
}
private:
int _d1;
char _d2;
};
int main()
{
freelock_queue<int,1024> intqueue;
intqueue.push(1);
int d1= 0;
intqueue.pop(inttest1);
printf("%d \n",d1 );
//
freelock_queue<datavalue,32> mystructqueue;
mystructqueue.push(d2);
if(mystructqueue.pop(d3) != 0)
{
printf("pop error\n");
}
return 0;
}