Annotation of researchv9/cmd/cfront/libC/task/qhead.c, revision 1.1.1.1

1.1       root        1: #include "task.h"
                      2: 
                      3: /*     a qhead's qh_queue has its pointer q_ptr pointing the last
                      4:        element of a circular list, so that q_ptr->o_next is the
                      5:        first element of that list.
                      6: 
                      7:    STRUCTURE:
                      8:        qhead <--> oqueue <--> qtail    (qhead and qtail are independent)
                      9:        oqueue --> circular queue of objects
                     10: 
                     11:        "pen and paper is recommended when trying to understand
                     12:        the list manipulations."
                     13: */
                     14: 
                     15: /* construct qhead <--> (possible)oqueue --> 0 */
                     16: qhead.qhead(int mode, int max) : (QHEAD)
                     17: {
                     18:        if (0 < max) {
                     19:                qh_queue = new oqueue(max);
                     20:                qh_queue->q_head = this;
                     21:        };
                     22:        qh_mode = mode;
                     23: }
                     24: 
                     25: 
                     26: /* destroy q if not pointed to by a qtail */
                     27: qhead.~qhead()
                     28: {
                     29:        oqueue* q = qh_queue;
                     30: 
                     31:        if (q->q_tail)
                     32:                q->q_head = 0;
                     33:        else 
                     34:                delete q;
                     35:        
                     36: }
                     37: 
                     38: 
                     39: /* remove and return object from head of q */
                     40: object* qhead.get()
                     41: {
                     42:        register oqueue* q = qh_queue;
                     43: ll:
                     44:        if (q->q_count) {
                     45:                register object* oo = q->q_ptr;
                     46:                register object* p = oo->o_next;
                     47:                oo->o_next = p->o_next;
                     48:                p->o_next = 0;
                     49:                if (q->q_count-- == q->q_max) {
                     50:                        qtail* t = q->q_tail;
                     51:                        if (t) t->alert();
                     52:                };
                     53:                return p;
                     54:        }
                     55: 
                     56:        switch (qh_mode) {
                     57:        case WMODE:
                     58:                remember(thistask);
                     59:                thistask->sleep();
                     60:                forget(thistask);
                     61:                goto ll;
                     62:        case EMODE:
                     63:                task_error(E_GETEMPTY,this);
                     64:                goto ll;
                     65:        case ZMODE:
                     66:                return 0;
                     67:        }
                     68: }
                     69: 
                     70: /* create a tail for this queue */
                     71: qtail* qhead.tail()
                     72: {
                     73:        oqueue* q = qh_queue;
                     74:        register qtail* t = q->q_tail;
                     75: 
                     76:        if (t == 0) {
                     77:                t = new qtail(qh_mode,0);
                     78:                q->q_tail = t;
                     79:                t->qt_queue = q;
                     80:        }
                     81: 
                     82:        return t;
                     83: }
                     84: 
                     85: 
                     86: /* make room for a filter upstream from this qhead */
                     87: /* result:  (this)qhead<-->newq    (new)qhead<-->oldq ?<-->qtail? */
                     88: qhead* qhead.cut()
                     89: {
                     90:        oqueue* oldq = qh_queue;
                     91:        qhead* h = new qhead(qh_mode,oldq->q_max);
                     92:        oqueue* newq = h->qh_queue;
                     93: 
                     94:        oldq->q_head = h;
                     95:        h->qh_queue = oldq;
                     96: 
                     97:        qh_queue = newq;
                     98:        newq->q_head = this;
                     99: 
                    100:        return h;
                    101: }
                    102: 
                    103: 
                    104: /* this qhead is supposed to be upstream to the qtail t
                    105:    add the contents of this's queue to t's queue
                    106:    destroy this, t, and this's queue
                    107:    alert the spliced qhead and qtail if a significant state change happened
                    108: */
                    109: void qhead.splice(qtail* t)
                    110: {
                    111:        oqueue* qt = t->qt_queue;
                    112:        oqueue* qh = qh_queue;
                    113: 
                    114:        int qtcount = qt->q_count;
                    115:        int qhcount = qh->q_count;
                    116:        int halert = (qtcount==0 && qhcount);   /* becomes non-empty */
                    117:        int talert = (qh->q_max <= qhcount && qhcount+qtcount<qt->q_max);
                    118:                                                /* becomes non-full */  
                    119:        if (qhcount) {
                    120:                object* ooh = qh->q_ptr;
                    121:                object* oot = qt->q_ptr;
                    122:                qt->q_ptr = ooh;
                    123:                if (qtcount) {                  /* add the contents of qh to qt */
                    124:                        object* tf = oot->o_next;
                    125:                        oot->o_next = ooh->o_next;
                    126:                        ooh->o_next = tf;
                    127:                }
                    128:                qt->q_count = qhcount + qtcount;
                    129:                qh->q_count = 0;
                    130:        }
                    131: 
                    132:        (qh->q_tail)->qt_queue = qt;
                    133:        qt->q_tail = qh->q_tail;
                    134:        qh->q_tail = 0;
                    135: 
                    136:        delete t;
                    137:        delete this;
                    138: 
                    139:        if (halert) qt->q_head->alert();
                    140:        if (talert) qt->q_tail->alert();
                    141: }
                    142: 
                    143: 
                    144: /* insert new object at head of queue (after queue->q_ptr) */
                    145: int qhead.putback(object* p)
                    146: {
                    147:        oqueue* q = qh_queue;
                    148: 
                    149:        if (p->o_next) task_error(E_BACKOBJ,this);
                    150: ll:
                    151:        if (q->q_count++ < q->q_max) {
                    152:                if (q->q_count == 1) {
                    153:                        q->q_ptr = p;
                    154:                        p->o_next = p;
                    155:                }
                    156:                else {
                    157:                        object* oo = q->q_ptr;
                    158:                        p->o_next = oo->o_next;
                    159:                        oo->o_next = p;
                    160:                }
                    161:                return 1;
                    162:        }
                    163: 
                    164:        switch (qh_mode) {
                    165:        case WMODE:
                    166:        case EMODE:
                    167:                task_error(E_BACKFULL,this);
                    168:                goto ll;
                    169:        case ZMODE:
                    170:                return 0;
                    171:        }
                    172: }
                    173: 
                    174: 
                    175: void qhead.print(int n)
                    176: {
                    177:        oqueue* q = qh_queue;
                    178: 
                    179:        printf("qhead (%d): mode=%d, max=%d, count=%d, tail=%d\n",
                    180:                this,qh_mode,q->q_max,q->q_count,q->q_tail);
                    181: 
                    182:        if (n&VERBOSE) {
                    183:                int m = n & ~(CHAIN|VERBOSE);
                    184:                if (q->q_tail) {
                    185:                        printf("\ttail of queue:\n");
                    186:                        q->q_tail->print(m);
                    187:                }
                    188:                q->print(m);
                    189:        }
                    190: }
                    191: 
                    192: 
                    193: void oqueue.print(int n)
                    194: {
                    195:        object* p = q_ptr;
                    196: 
                    197:        if (q_count == 0) return;
                    198: 
                    199:        printf("\tobjectects on queue:\n");
                    200: 
                    201:        do {
                    202:                p->print(n);
                    203:                p = p->o_next;
                    204:        } while (p != q_ptr);
                    205: 
                    206:        printf("\n");
                    207: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.