8#define CAS(a_ptr, a_oldVal, a_newVal) __sync_bool_compare_and_swap(a_ptr, a_oldVal, a_newVal)
15 m_attr.mq_flags = O_NONBLOCK;
16 m_attr.mq_maxmsg = maxmsg;
17 m_attr.mq_msgsize = msgsize;
18 m_attr.mq_curmsgs = 0;
23 m_index =
new(std::nothrow) QueueNode[maxmsg];
24 m_data =
new(std::nothrow)
U8[maxmsg * msgsize];
28 for (
int i = 0, j = 1; i < maxmsg; i++, j++) {
29 m_index[i].data = &m_data[i * msgsize];
32 m_index[i].next = &m_index[j];
34 m_index[i].next =
nullptr;
41 m_first = &m_index[0];
43 m_last->next =
nullptr;
46 m_free_head = &m_index[1];
56 memcpy(&attr, &m_attr,
sizeof(mq_attr));
60 void LocklessQueue::PushFree(QueueNode * my_node) {
61 QueueNode * old_free_head;
67 old_free_head = m_free_head;
68 my_node->next = old_free_head;
69 }
while (!
CAS(&m_free_head, old_free_head, my_node));
72 bool LocklessQueue::PopFree(QueueNode ** free_node) {
77 my_node = m_free_head;
79 if (
nullptr == my_node) {
83 }
while (!
CAS(&m_free_head, my_node, my_node->next));
85 (*free_node) = my_node;
98 if (size > m_attr.mq_msgsize) {
103 if (!PopFree(&my_node)) {
108 memcpy(my_node->data, buffer, size);
109 my_node->size = size;
110 my_node->next =
nullptr;
117 }
while (!
CAS(&m_last, old_last, my_node));
119 old_last->next = my_node;
129 QueueNode * old_node;
132 if (capacity < m_attr.mq_msgsize) {
137 if (m_first == m_last) {
142 my_node = m_first->next;
144 if (my_node ==
nullptr) {
149 m_first = m_first->next;
153 memcpy(buffer, my_node->data, my_node->size);
154 size = my_node->size;
PlatformIntType NATIVE_INT_TYPE
uint8_t U8
8-bit unsigned integer
#define CAS(a_ptr, a_oldVal, a_newVal)
Os::Queue::QueueStatus Receive(U8 *buffer, NATIVE_INT_TYPE capacity, NATIVE_INT_TYPE &size)
LocklessQueue(NATIVE_INT_TYPE maxmsg, NATIVE_INT_TYPE msgsize)
void GetAttr(mq_attr &attr)
Os::Queue::QueueStatus Send(const U8 *buffer, NATIVE_INT_TYPE size)
@ QUEUE_SIZE_MISMATCH
attempted to send or receive with buffer too large, too small
@ QUEUE_NO_MORE_MSGS
If non-blocking, all the messages have been drained.
@ QUEUE_OK
message sent/received okay
@ QUEUE_FULL
queue was full when attempting to send a message