main() { int nitems; char cline[MAXLINE]; char qchar, *malloc(); Queue *qcreate(); queue = qcreate( CHAR, 5 ); printf("ready\n"); while ( gets(cline) != NULL ) { if ( !strcmp( cline, "remove" )) { if ( qremove( &qchar, queue ) == FAILURE ) { printf("queue empty\n"); continue; } else { printf("%c\n", qchar); } } else if ( !strcmp( cline, "read" )) { if ( qread( &qchar, queue ) == FAILURE ) { printf("queue exhausted\n"); continue; } else { printf("%c\n", qchar); } } else if ( !strcmp( cline, "reset" )) { qreset( queue ); } else if ( !strcmp( cline, "clear" )) { qclear( queue ); } else if ( !strncmp( cline, "delete ", 7 )) { if ( sscanf( cline, "delete %d", &nitems ) != 1 ) { printf("What?\n"); continue; } if ( qdelete( nitems, queue ) == FAILURE ) printf("too many items\n"); } else { qchar = cline[0]; if ( qadd( &qchar, queue ) == FAILURE ) printf("queue full\n"); } } while ( qremove( &qchar, queue ) == SUCCESS ) printf("%c\n"); printf("queue empty\n"); }
void init(const char *s) { int i, freq[128] = {0}; char c[16]; while (*s) freq[(int)*s++]++; for (i = 0; i < 128; i++) if (freq[i]) qinsert(new_node(freq[i], i, 0, 0)); while (qend > 2) qinsert(new_node(0, 0, qremove(), qremove())); build_code(q[1], c, 0); }
/* remove n from q1 and put it in q2 if nid not in q2 */ int lqremoveputifn(void *q1p, void *q2p, int (*searchfn1)(void* elementp,void* skeyp1), void* skeyp1, int (*searchfn2)(void* elementp,void* skeyp2), void * skeyp2){ if(NULL != q1p && NULL != q2p){ void * node; int ret = -1; pthread_mutex_t *q1_lock = &(((lqtype *)q1p)->q_lock); pthread_mutex_t *q2_lock = &(((lqtype *)q2p)->q_lock); int rc = pthread_mutex_lock(q1_lock); rc = pthread_mutex_lock(q2_lock); if(NULL == searchfn2 || qsearch(((lqtype *)q2p)->queue, searchfn2, skeyp2) == NULL){ node = qremove(((lqtype *)q1p)->queue, searchfn1, skeyp1); if(NULL != node){ qput(((lqtype *)q2p)->queue, node); ret = 0; } } rc = pthread_mutex_unlock(q2_lock); rc = pthread_mutex_unlock(q1_lock); return ret; } else { printf("should open queues before using it\n"); return -1; } }
BQUEUE *qdchain(BQUEUE *qitem) { #define qi ((BQUEUE *)qitem) ASSERT(qi->qprev->qnext == qi); ASSERT(qi->qnext->qprev == qi); return qremove(qi->qprev); #undef qi }
void init(const char *s) { int i, freq[128] = {0}; char c[16]; while (*s) { //printf("haha:%c, %d\n", *s, (int)*s); freq[(int)*s]++; s++; } for (i = 0; i < 128; i++) if (freq[i]) qinsert(new_node(freq[i], i, 0, 0)); while (qend > 2) qinsert(new_node(0, 0, qremove(), qremove())); build_code(q[1], c, 0); }
struct segwrap * seghash_remove (struct segwrap **hash_table, size_t table_size, seq_t key) { struct segwrap *selected; selected = seghash_get (hash_table, table_size, key); if (selected != NULL) { int i; i = hash_fun (key, table_size); qremove (&hash_table[i], selected); } return selected; }
void* lqgetrm(void *qp){ if(NULL != qp){ pthread_mutex_t *q_lock = &(((lqtype *)qp)->q_lock); int rc = pthread_mutex_lock(q_lock); void * ret = qget(((lqtype *)qp)->queue); qremove(((lqtype *)qp)->queue, match_item, ret); rc = pthread_mutex_unlock(q_lock); return ret; } else { printf("should open queue before using it\n"); return NULL; } }
/* * get next block from a queue (up to a limit) */ Block* qbread(Queue *q, int len) { Block *b, *nb; int n; qlock(&q->rlock); if(waserror()){ qunlock(&q->rlock); nexterror(); } ilock(q); switch(qwait(q)){ case 0: /* queue closed */ iunlock(q); qunlock(&q->rlock); poperror(); return nil; case -1: /* multiple reads on a closed queue */ iunlock(q); error(q->err); } /* if we get here, there's at least one block in the queue */ b = qremove(q); n = BLEN(b); /* split block if it's too big and this is not a message queue */ nb = b; if(n > len){ if((q->state&Qmsg) == 0){ n -= len; b = allocb(n); memmove(b->wp, nb->rp+len, n); b->wp += n; qputback(q, b); } nb->wp = nb->rp + len; } /* restart producer */ qwakeup_iunlock(q); poperror(); qunlock(&q->rlock); return nb; }
/* removes first matching element */ void* lqremove(void *qp, int (*searchfn)(void* elementp,void* keyp), void* skeyp){ if(NULL != qp){ pthread_mutex_t *q_lock = &(((lqtype *)qp)->q_lock); int rc = pthread_mutex_lock(q_lock); void * ret = qremove(((lqtype *)qp)->queue, searchfn, skeyp); rc = pthread_mutex_unlock(q_lock); return ret; } else { printf("should open queue before using it\n"); return NULL; } }
/* * get next block from a queue (up to a limit) */ struct block *qbread(struct queue *q, int len) { ERRSTACK(1); struct block *b, *nb; int n; qlock(&q->rlock); if (waserror()) { qunlock(&q->rlock); nexterror(); } spin_lock_irqsave(&q->lock); if (!qwait(q)) { /* queue closed */ spin_unlock_irqsave(&q->lock); qunlock(&q->rlock); poperror(); return NULL; } /* if we get here, there's at least one block in the queue */ b = qremove(q); n = BLEN(b); /* split block if it's too big and this is not a message queue */ nb = b; if (n > len) { PANIC_EXTRA(b); if ((q->state & Qmsg) == 0) { n -= len; b = allocb(n); memmove(b->wp, nb->rp + len, n); b->wp += n; qputback(q, b); } nb->wp = nb->rp + len; } /* restart producer */ qwakeup_iunlock(q); poperror(); qunlock(&q->rlock); return nb; }
int main(void) { /* Create two empty queues */ void *q1; void *q2; void *pt; int a,b,c,d,e,f,g,h,i,j,k; int x; int ii; a = 1; b = 4; c = 65; d = 34; f = 6; e = 9; g = 11; h = 23; i = 999; j = 234; k = 94; q1 = qopen(); q2 = qopen(); /* Fill both */ qput(q1, &a); qput(q1, &b); qput(q1, &c); qput(q1, &d); qput(q1, &e); qput(q1, &f); qput(q2, &g); qput(q2, &h); qput(q2, &i); qput(q2, &j); qput(q2, &k); /* Get an item out of q1 */ pt = qget(q1); if (*((int *)pt) != 1) { printf("Fail on qget; returned %d.\n", *((int *)pt)); return -1; } /* Catenate */ qconcat(q1, q2); /* Remove until null is returned, count number of iterations */ for (ii = 0; pt != NULL; ii++) { pt = qget(q1); } if (ii != 11) { printf("Fail on catenate; queue was of size %d.\n", ii); return -1; } /* Use remove to take out a specified value */ qput(q1, &a); qput(q1, &b); qput(q1, &c); qput(q1, &d); qput(q1, &e); qput(q1, &f); qput(q1, &g); qput(q1, &h); qput(q1, &i); qput(q1, &j); qput(q1, &k); x = 999; pt = qremove(q1, searchfn, &x); if (pt == NULL || *((int *)pt) != 999) { if (pt == NULL) { printf("Fail on qsearch; value not found.\n"); } else { printf("Fail on qremove / qsearch; removed value was %d.\n", *((int *)pt)); } } /* Use qapply to print out remaining list */ qapply(q1, printfn); return 1; }
/* * read a queue. if no data is queued, post a Block * and wait on its Rendez. */ long qread(Queue *q, void *vp, int len) { Block *b, *first, **l; int m, n; qlock(&q->rlock); if(waserror()){ qunlock(&q->rlock); nexterror(); } ilock(q); again: switch(qwait(q)){ case 0: /* queue closed */ iunlock(q); qunlock(&q->rlock); poperror(); return 0; case -1: /* multiple reads on a closed queue */ iunlock(q); error(q->err); } /* if we get here, there's at least one block in the queue */ if(q->state & Qcoalesce){ /* when coalescing, 0 length blocks just go away */ b = q->bfirst; if(BLEN(b) <= 0){ freeb(qremove(q)); goto again; } /* grab the first block plus as many * following blocks as will completely * fit in the read. */ n = 0; l = &first; m = BLEN(b); for(;;) { *l = qremove(q); l = &b->next; n += m; b = q->bfirst; if(b == nil) break; m = BLEN(b); if(n+m > len) break; } } else { first = qremove(q); n = BLEN(first); } /* copy to user space outside of the ilock */ iunlock(q); b = bl2mem(vp, first, len); ilock(q); /* take care of any left over partial block */ if(b != nil){ n -= BLEN(b); if(q->state & Qmsg) freeb(b); else qputback(q, b); } /* restart producer */ qwakeup_iunlock(q); poperror(); qunlock(&q->rlock); return n; }
/* * read a queue. if no data is queued, post a struct block * and wait on its Rendez. */ long qread(struct queue *q, void *vp, int len) { ERRSTACK(1); struct block *b, *first, **l; int m, n; qlock(&q->rlock); if (waserror()) { qunlock(&q->rlock); nexterror(); } spin_lock_irqsave(&q->lock); again: if (!qwait(q)) { /* queue closed */ spin_unlock_irqsave(&q->lock); qunlock(&q->rlock); poperror(); return 0; } /* if we get here, there's at least one block in the queue */ // TODO: Consider removing the Qcoalesce flag and force a coalescing // strategy by default. if (q->state & Qcoalesce) { /* when coalescing, 0 length blocks just go away */ b = q->bfirst; if (BLEN(b) <= 0) { freeb(qremove(q)); goto again; } /* grab the first block plus as many * following blocks as will completely * fit in the read. */ n = 0; l = &first; m = BLEN(b); for (;;) { *l = qremove(q); l = &b->next; n += m; b = q->bfirst; if (b == NULL) break; m = BLEN(b); if (n + m > len) break; } } else { first = qremove(q); n = BLEN(first); } /* copy to user space outside of the ilock */ spin_unlock_irqsave(&q->lock); b = bl2mem(vp, first, len); spin_lock_irqsave(&q->lock); /* take care of any left over partial block */ if (b != NULL) { n -= BLEN(b); if (q->state & Qmsg) freeb(b); else qputback(q, b); } /* restart producer */ qwakeup_iunlock(q); poperror(); qunlock(&q->rlock); return n; }