...
| Code Block | ||||
|---|---|---|---|---|
| ||||
#include <glib.h>
#include <glib-object.h>
void queue_enqueue(Queue *q, gpointer data) {
Node *node;
Node *tail;
Node *next;
node = g_slice_new(Node);
node->data = data;
node->next = NULL;
while (TRUE) {
tail = q->tail;
HAZARD_SET(0, tail); /* Mark tail as hazardous */
if (tail != q->tail) { /* Check tail hasn't changed */
continue;
}
next = tail->next;
if (tail != q->tail) {
continue;
}
if (next != NULL) {
CAS(&q->tail, tail, next);
continue;
}
if (CAS(&tail->next, null, node) {
break;
}
}
CAS(&q->tail, tail, node);
}
gpointer queue_dequeue(Queue *q) {
Node *node;
Node *head;
Node *tail;
Node *next;
while (TRUE) {
head = q->head;
LF_HAZARD_SET(0, head); /* Mark head as hazardous */
if (head != q->head) { /* Check head hasn't changed */
continue;
}
tail = q->tail;
next = head->next;
LF_HAZARD_SET(1, next); /* Mark next as hazardous */
if (head != q->head) {
continue;
}
if (next == NULL) {
return NULL; /* Empty */
}
if (head == tail) {
CAS(&q->tail, tail, next);
continue;
}
data = next->data;
if (CAS(&q->head, head, next)) {
break;
}
}
LF_HAZARD_UNSET(head); /*
* Retire head, and perform
* reclamation if needed.
*/
return data;
}
|
...
| Code Block | ||||
|---|---|---|---|---|
| ||||
#include <threads.h>
#include <glib-object.h>
typedef struct node_s {
void *data;
Node *next;
} Node;
typedef struct queue_s {
Node *head;
Node *tail;
mtx_t mutex;
} Queue;
Queue* queue_new(void) {
Queue *q = g_slice_new(sizeof(Queue));
q->head = q->tail = g_slice_new(sizeof(Node));
return q;
}
int queue_enqueue(Queue *q, gpointer data) {
Node *node;
Node *tail;
Node *next;
/*
* Lock the queue before accessing the contents and
* check the return code for success.
*/
if (thrd_success != mtx_lock(&(q->mutex))) {
return -1; /* Indicate failure */
} else {
node = g_slice_new(Node);
node->data = data;
node->next = NULL;
if(q->head == NULL) {
q->head = node;
q->tail = node;
} else {
q->tail->next = node;
q->tail = node;
}
/* Unlock the mutex and check the return code */
if (thrd_success != mtx_unlock(&(queue->mutex))) {
return -1; /* Indicate failure */
}
}
return 0;
}
gpointer queue_dequeue(Queue *q) {
Node *node;
Node *head;
Node *tail;
Node *next;
if (thrd_success != mtx_lock(&(q->mutex)) {
return NULL; /* Indicate failure */
} else {
head = q->head;
tail = q->tail;
next = head->next;
data = head->data;
q->head = next;
g_slice_free(Node, head);
if (thrd_success != mtx_unlock(&(queue->mutex))) {
return NULL; /* Indicate failure */
}
}
return data;
}
|
...