Annotation of researchv10no/cmd/cfront/libC/task/qhead.c, revision 1.1

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

unix.superglobalmegacorp.com

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