Annotation of researchv9/cmd/cfront/libC/task/qhead.c, revision 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.