1*368c31abSDavid du Colombier #include <u.h> 2*368c31abSDavid du Colombier #include <libc.h> 3*368c31abSDavid du Colombier #include <venti.h> 4*368c31abSDavid du Colombier #include "queue.h" 5*368c31abSDavid du Colombier 6*368c31abSDavid du Colombier typedef struct Qel Qel; 7*368c31abSDavid du Colombier struct Qel 8*368c31abSDavid du Colombier { 9*368c31abSDavid du Colombier Qel *next; 10*368c31abSDavid du Colombier void *p; 11*368c31abSDavid du Colombier }; 12*368c31abSDavid du Colombier 13*368c31abSDavid du Colombier struct Queue 14*368c31abSDavid du Colombier { 15*368c31abSDavid du Colombier int ref; 16*368c31abSDavid du Colombier int hungup; 17*368c31abSDavid du Colombier QLock lk; 18*368c31abSDavid du Colombier Rendez r; 19*368c31abSDavid du Colombier Qel *head; 20*368c31abSDavid du Colombier Qel *tail; 21*368c31abSDavid du Colombier }; 22*368c31abSDavid du Colombier 23*368c31abSDavid du Colombier Queue* _vtqalloc(void)24*368c31abSDavid du Colombier_vtqalloc(void) 25*368c31abSDavid du Colombier { 26*368c31abSDavid du Colombier Queue *q; 27*368c31abSDavid du Colombier 28*368c31abSDavid du Colombier q = vtmallocz(sizeof(Queue)); 29*368c31abSDavid du Colombier q->r.l = &q->lk; 30*368c31abSDavid du Colombier q->ref = 1; 31*368c31abSDavid du Colombier return q; 32*368c31abSDavid du Colombier } 33*368c31abSDavid du Colombier 34*368c31abSDavid du Colombier Queue* _vtqincref(Queue * q)35*368c31abSDavid du Colombier_vtqincref(Queue *q) 36*368c31abSDavid du Colombier { 37*368c31abSDavid du Colombier qlock(&q->lk); 38*368c31abSDavid du Colombier q->ref++; 39*368c31abSDavid du Colombier qunlock(&q->lk); 40*368c31abSDavid du Colombier return q; 41*368c31abSDavid du Colombier } 42*368c31abSDavid du Colombier 43*368c31abSDavid du Colombier void _vtqdecref(Queue * q)44*368c31abSDavid du Colombier_vtqdecref(Queue *q) 45*368c31abSDavid du Colombier { 46*368c31abSDavid du Colombier Qel *e; 47*368c31abSDavid du Colombier 48*368c31abSDavid du Colombier qlock(&q->lk); 49*368c31abSDavid du Colombier if(--q->ref > 0){ 50*368c31abSDavid du Colombier qunlock(&q->lk); 51*368c31abSDavid du Colombier return; 52*368c31abSDavid du Colombier } 53*368c31abSDavid du Colombier assert(q->ref == 0); 54*368c31abSDavid du Colombier qunlock(&q->lk); 55*368c31abSDavid du Colombier 56*368c31abSDavid du Colombier /* Leaks the pointers e->p! */ 57*368c31abSDavid du Colombier while(q->head){ 58*368c31abSDavid du Colombier e = q->head; 59*368c31abSDavid du Colombier q->head = e->next; 60*368c31abSDavid du Colombier free(e); 61*368c31abSDavid du Colombier } 62*368c31abSDavid du Colombier free(q); 63*368c31abSDavid du Colombier } 64*368c31abSDavid du Colombier 65*368c31abSDavid du Colombier int _vtqsend(Queue * q,void * p)66*368c31abSDavid du Colombier_vtqsend(Queue *q, void *p) 67*368c31abSDavid du Colombier { 68*368c31abSDavid du Colombier Qel *e; 69*368c31abSDavid du Colombier 70*368c31abSDavid du Colombier e = vtmalloc(sizeof(Qel)); 71*368c31abSDavid du Colombier qlock(&q->lk); 72*368c31abSDavid du Colombier if(q->hungup){ 73*368c31abSDavid du Colombier werrstr("hungup queue"); 74*368c31abSDavid du Colombier qunlock(&q->lk); 75*368c31abSDavid du Colombier return -1; 76*368c31abSDavid du Colombier } 77*368c31abSDavid du Colombier e->p = p; 78*368c31abSDavid du Colombier e->next = nil; 79*368c31abSDavid du Colombier if(q->head == nil) 80*368c31abSDavid du Colombier q->head = e; 81*368c31abSDavid du Colombier else 82*368c31abSDavid du Colombier q->tail->next = e; 83*368c31abSDavid du Colombier q->tail = e; 84*368c31abSDavid du Colombier rwakeup(&q->r); 85*368c31abSDavid du Colombier qunlock(&q->lk); 86*368c31abSDavid du Colombier return 0; 87*368c31abSDavid du Colombier } 88*368c31abSDavid du Colombier 89*368c31abSDavid du Colombier void* _vtqrecv(Queue * q)90*368c31abSDavid du Colombier_vtqrecv(Queue *q) 91*368c31abSDavid du Colombier { 92*368c31abSDavid du Colombier void *p; 93*368c31abSDavid du Colombier Qel *e; 94*368c31abSDavid du Colombier 95*368c31abSDavid du Colombier qlock(&q->lk); 96*368c31abSDavid du Colombier while(q->head == nil && !q->hungup) 97*368c31abSDavid du Colombier rsleep(&q->r); 98*368c31abSDavid du Colombier if(q->hungup){ 99*368c31abSDavid du Colombier qunlock(&q->lk); 100*368c31abSDavid du Colombier return nil; 101*368c31abSDavid du Colombier } 102*368c31abSDavid du Colombier e = q->head; 103*368c31abSDavid du Colombier q->head = e->next; 104*368c31abSDavid du Colombier qunlock(&q->lk); 105*368c31abSDavid du Colombier p = e->p; 106*368c31abSDavid du Colombier vtfree(e); 107*368c31abSDavid du Colombier return p; 108*368c31abSDavid du Colombier } 109*368c31abSDavid du Colombier 110*368c31abSDavid du Colombier void* _vtnbqrecv(Queue * q)111*368c31abSDavid du Colombier_vtnbqrecv(Queue *q) 112*368c31abSDavid du Colombier { 113*368c31abSDavid du Colombier void *p; 114*368c31abSDavid du Colombier Qel *e; 115*368c31abSDavid du Colombier 116*368c31abSDavid du Colombier qlock(&q->lk); 117*368c31abSDavid du Colombier if(q->head == nil){ 118*368c31abSDavid du Colombier qunlock(&q->lk); 119*368c31abSDavid du Colombier return nil; 120*368c31abSDavid du Colombier } 121*368c31abSDavid du Colombier e = q->head; 122*368c31abSDavid du Colombier q->head = e->next; 123*368c31abSDavid du Colombier qunlock(&q->lk); 124*368c31abSDavid du Colombier p = e->p; 125*368c31abSDavid du Colombier vtfree(e); 126*368c31abSDavid du Colombier return p; 127*368c31abSDavid du Colombier } 128*368c31abSDavid du Colombier 129*368c31abSDavid du Colombier void _vtqhangup(Queue * q)130*368c31abSDavid du Colombier_vtqhangup(Queue *q) 131*368c31abSDavid du Colombier { 132*368c31abSDavid du Colombier qlock(&q->lk); 133*368c31abSDavid du Colombier q->hungup = 1; 134*368c31abSDavid du Colombier rwakeupall(&q->r); 135*368c31abSDavid du Colombier qunlock(&q->lk); 136*368c31abSDavid du Colombier } 137