bugfix: cas in gmq pop

This commit is contained in:
云风
2012-10-11 21:06:34 +08:00
parent aed83ea5e8
commit 837e79949d

View File

@@ -41,11 +41,13 @@ static struct global_queue *Q = NULL;
static void static void
skynet_globalmq_push(struct message_queue * queue) { skynet_globalmq_push(struct message_queue * queue) {
struct global_queue *q= Q; struct global_queue *q= Q;
uint32_t tail = __sync_fetch_and_add(&q->tail,1);
assert(GP(tail+1) != GP(q->head)); uint32_t head = q->head;
tail = GP(tail); __sync_synchronize();
uint32_t tail = q->tail;
assert(GP(tail+1) != GP(head));
tail = GP(__sync_fetch_and_add(&q->tail,1));
q->queue[tail] = queue; q->queue[tail] = queue;
__sync_synchronize(); __sync_synchronize();
q->flag[tail] = true; q->flag[tail] = true;
@@ -54,10 +56,18 @@ skynet_globalmq_push(struct message_queue * queue) {
struct message_queue * struct message_queue *
skynet_globalmq_pop() { skynet_globalmq_pop() {
struct global_queue *q = Q; struct global_queue *q = Q;
if (GP(q->head) == GP(q->tail)) { uint32_t head = 0;
return NULL; for(;;) {
} head = q->head;
uint32_t head = __sync_add_and_fetch(&q->head,1); if (GP(head) == GP(q->tail)) {
return NULL;
}
assert(head < q->tail);
if (__sync_bool_compare_and_swap(&q->head, head, head+1)) {
break;
}
}
head = GP(head); head = GP(head);
while(!q->flag[head]) { while(!q->flag[head]) {