diff --git a/skynet-src/skynet_mq.c b/skynet-src/skynet_mq.c index aa0d7ff4..9d682a41 100644 --- a/skynet-src/skynet_mq.c +++ b/skynet-src/skynet_mq.c @@ -43,11 +43,8 @@ static void skynet_globalmq_push(struct message_queue * queue) { struct global_queue *q= Q; - uint32_t head = q->head; - __sync_synchronize(); - uint32_t tail = q->tail; - assert(GP(tail+1) != GP(head)); - tail = GP(__sync_fetch_and_add(&q->tail,1)); + uint32_t tail = GP(__sync_fetch_and_add(&q->tail,1)); + assert(!q->flag[tail]); q->queue[tail] = queue; __sync_synchronize(); q->flag[tail] = true; @@ -56,27 +53,23 @@ skynet_globalmq_push(struct message_queue * queue) { struct message_queue * skynet_globalmq_pop() { struct global_queue *q = Q; - uint32_t head = 0; - for(;;) { - head = q->head; - if (GP(head) == GP(q->tail)) { - return NULL; - } - assert(head < q->tail); - if (__sync_bool_compare_and_swap(&q->head, head, head+1)) { - break; - } + uint32_t head = q->head; + uint32_t head_ptr = GP(head); + if (head_ptr == GP(q->tail)) { + return NULL; } - - head = GP(head); - - while(!q->flag[head]) { - __sync_synchronize(); + + if(!q->flag[head_ptr]) { + return NULL; } - q->flag[head] = false; + struct message_queue * mq = q->queue[head_ptr]; + if (!__sync_bool_compare_and_swap(&q->head, head, head+1)) { + return NULL; + } + q->flag[head_ptr] = false; - return q->queue[head]; + return mq; } struct message_queue *