7fd822aeecc1871bd4666e2d90b95aecb68ddcaf
[IRC.git] / Robust / src / Runtime / bamboo / pmc_queue.c
1 #include <stdlib.h>
2 #include "pmc_queue.h"
3 #include "mem.h"
4
5 void pmc_queueinit(struct pmc_queue *queue) {
6   queue->head=queue->tail=RUNMALLOC(sizeof(struct pmc_queue_segment));
7   queue->headindex=queue->tailindex=0;
8 }
9
10 void * pmc_dequeue(struct pmc_queue *queue) {
11   void *value=NULL;
12   tmc_spin_mutex_lock(&queue->lock);
13   //do-while loop allows sharing cleanup code
14   do {
15     //check for possible rollover
16     if (queue->tailindex==NUM_PMC_QUEUE_OBJECTS) {
17       if (queue->tail!=queue->head) {
18         struct pmc_queue_segment *oldtail=queue->tail;
19         queue->tail=oldtail->next;
20         queue->tailindex=0;
21         RUNFREE(oldtail);
22       } else break;
23     }
24     //now try to decrement
25     if (queue->tailindex!=queue->headindex) {
26       value=queue->tail->objects[queue->tailindex];
27       queue->tailindex++;
28     }
29   } while(false);
30   tmc_spin_mutex_unlock(&queue->lock);
31   return value;
32 }
33
34 void pmc_enqueue(struct pmc_queue* queue, void *ptr) {
35   if (queue->headindex<NUM_PMC_QUEUE_OBJECTS) {
36     queue->head->objects[queue->headindex]=ptr;
37     //need fence to prevent reordering
38     __insn_mf();
39     queue->headindex++;
40     return;
41   } else {
42     struct pmc_queue_segment * seg=RUNMALLOC(sizeof(struct pmc_queue_segment));
43     seg->objects[0]=ptr;
44     //simplify everything by grabbing a lock on segment change
45     tmc_spin_mutex_lock(&queue->lock);
46     queue->headindex=1;
47     queue->head->next=seg;
48     queue->head=seg;
49     tmc_spin_mutex_unlock(&queue->lock);
50   }
51 }
52
53 bool pmc_isEmpty(struct pmc_queue *queue) {
54   tmc_spin_mutex_lock(&queue->lock);
55   bool status=(queue->head==queue->tail)&&(queue->headindex==queue->tailindex);
56   tmc_spin_mutex_unlock(&queue->lock);
57   return status;
58 }