7 #define CAS(a_ptr, a_oldVal, a_newVal) __sync_bool_compare_and_swap(a_ptr, a_oldVal, a_newVal)
14 m_attr.mq_flags = O_NONBLOCK;
15 m_attr.mq_maxmsg = maxmsg;
16 m_attr.mq_msgsize = msgsize;
17 m_attr.mq_curmsgs = 0;
22 m_index =
new QueueNode[maxmsg];
23 m_data =
new U8[maxmsg * msgsize];
26 for (
int i = 0, j = 1; i < maxmsg; i++, j++) {
27 m_index[i].data = &m_data[i * msgsize];
30 m_index[i].next = &m_index[j];
32 m_index[i].next =
NULL;
39 m_first = &m_index[0];
44 m_free_head = &m_index[1];
54 memcpy(&attr, &m_attr,
sizeof(mq_attr));
58 void LocklessQueue::PushFree(QueueNode * my_node) {
59 QueueNode * old_free_head;
65 old_free_head = m_free_head;
66 my_node->next = old_free_head;
67 }
while (!
CAS(&m_free_head, old_free_head, my_node));
70 bool LocklessQueue::PopFree(QueueNode ** free_node) {
75 my_node = m_free_head;
77 if (
NULL == my_node) {
81 }
while (!
CAS(&m_free_head, my_node, my_node->next));
83 (*free_node) = my_node;
96 if (size > m_attr.mq_msgsize) {
101 if (!PopFree(&my_node)) {
106 memcpy(my_node->data, buffer, size);
107 my_node->size = size;
108 my_node->next =
NULL;
115 }
while (!
CAS(&m_last, old_last, my_node));
117 old_last->next = my_node;
127 QueueNode * old_node;
130 if (capacity < m_attr.mq_msgsize) {
135 if (m_first == m_last) {
140 my_node = m_first->next;
142 if (my_node ==
NULL) {
147 m_first = m_first->next;
151 memcpy(buffer, my_node->data, my_node->size);
152 size = my_node->size;