Annotation of researchv10no/cmd/cfront/libC/otask/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)
        !            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*
        !            41: qhead::get()
        !            42: {
        !            43:        register oqueue* q = qh_queue;
        !            44: ll:
        !            45:        if (q->q_count) {
        !            46:                register object* oo = q->q_ptr;
        !            47:                register object* p = oo->o_next;
        !            48:                oo->o_next = p->o_next;
        !            49:                p->o_next = 0;
        !            50:                if (q->q_count-- == q->q_max) {
        !            51:                        qtail* t = q->q_tail;
        !            52:                        if (t) t->alert();
        !            53:                };
        !            54:                return p;
        !            55:        }
        !            56: 
        !            57:        switch (qh_mode) {
        !            58:        case WMODE:
        !            59:                this_task()->sleep(this);
        !            60:                goto ll;
        !            61:        case EMODE:
        !            62:                task_error(E_GETEMPTY);
        !            63:                goto ll;
        !            64:        case ZMODE:
        !            65:                return 0;
        !            66:        }
        !            67: }
        !            68: 
        !            69: /* create a tail for this queue */
        !            70: qtail*
        !            71: 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*
        !            89: qhead::cut()
        !            90: {
        !            91:        oqueue* oldq = qh_queue;
        !            92:        qhead* h = new qhead(qh_mode,oldq->q_max);
        !            93:        oqueue* newq = h->qh_queue;
        !            94: 
        !            95:        oldq->q_head = h;
        !            96:        h->qh_queue = oldq;
        !            97: 
        !            98:        qh_queue = newq;
        !            99:        newq->q_head = this;
        !           100: 
        !           101:        return h;
        !           102: }
        !           103: 
        !           104: 
        !           105: /* this qhead is supposed to be upstream to the qtail t
        !           106:    add the contents of this's queue to t's queue
        !           107:    destroy this, t, and this's queue
        !           108:    alert the spliced qhead and qtail if a significant state change happened
        !           109: */
        !           110: void
        !           111: qhead::splice(qtail* t)
        !           112: {
        !           113:        oqueue* qt = t->qt_queue;
        !           114:        oqueue* qh = qh_queue;
        !           115: 
        !           116:        int qtcount = qt->q_count;
        !           117:        int qhcount = qh->q_count;
        !           118:        int halert = (qtcount==0 && qhcount);   /* becomes non-empty */
        !           119:        int talert = (qh->q_max <= qhcount && qhcount+qtcount<qt->q_max);
        !           120:                                                /* becomes non-full */  
        !           121:        if (qhcount) {
        !           122:                object* ooh = qh->q_ptr;
        !           123:                object* oot = qt->q_ptr;
        !           124:                qt->q_ptr = ooh;
        !           125:                if (qtcount) {                  /* add the contents of qh to qt */
        !           126:                        object* tf = oot->o_next;
        !           127:                        oot->o_next = ooh->o_next;
        !           128:                        ooh->o_next = tf;
        !           129:                }
        !           130:                qt->q_count = qhcount + qtcount;
        !           131:                qh->q_count = 0;
        !           132:        }
        !           133: 
        !           134:        (qh->q_tail)->qt_queue = qt;
        !           135:        qt->q_tail = qh->q_tail;
        !           136:        qh->q_tail = 0;
        !           137: 
        !           138:        delete t;
        !           139:        delete this;
        !           140: 
        !           141:        if (halert) qt->q_head->alert();
        !           142:        if (talert) qt->q_tail->alert();
        !           143: }
        !           144: 
        !           145: 
        !           146: /* insert new object at head of queue (after queue->q_ptr) */
        !           147: int
        !           148: qhead::putback(object* p)
        !           149: {
        !           150:        oqueue* q = qh_queue;
        !           151: 
        !           152:        if (p->o_next) task_error(E_BACKOBJ);
        !           153: ll:
        !           154:        if (q->q_count++ < q->q_max) {
        !           155:                if (q->q_count == 1) {
        !           156:                        q->q_ptr = p;
        !           157:                        p->o_next = p;
        !           158:                }
        !           159:                else {
        !           160:                        object* oo = q->q_ptr;
        !           161:                        p->o_next = oo->o_next;
        !           162:                        oo->o_next = p;
        !           163:                }
        !           164:                return 1;
        !           165:        }
        !           166: 
        !           167:        switch (qh_mode) {
        !           168:        case WMODE:
        !           169:        case EMODE:
        !           170:                task_error(E_BACKFULL);
        !           171:                goto ll;
        !           172:        case ZMODE:
        !           173:                return 0;
        !           174:        }
        !           175: }
        !           176: 
        !           177: int
        !           178: qhead::pending()
        !           179: {
        !           180:        return rdcount() == 0;
        !           181: }
        !           182: 
        !           183: void
        !           184: qhead::print(int n, int baseClass)
        !           185: {
        !           186:        if (!baseClass)
        !           187:                printf("qhead ");
        !           188: 
        !           189:        oqueue* q = qh_queue;
        !           190: 
        !           191:        printf("mode=%d, max=%d, count=%d, tail=%d\n",
        !           192:                qh_mode, q->q_max, q->q_count, q->q_tail);
        !           193: 
        !           194:        if (n&VERBOSE) {
        !           195:                int m = n & ~(CHAIN|VERBOSE);
        !           196:                if (q->q_tail) {
        !           197:                        printf("\ttail of queue:\n");
        !           198:                        q->q_tail->print(m);
        !           199:                } else printf("\tno tail\n");
        !           200:                q->print(m);
        !           201:        }
        !           202: 
        !           203:        object::print(n, 1);
        !           204: }
        !           205: 
        !           206: 
        !           207: void
        !           208: oqueue::print(int n)
        !           209: {
        !           210:        object* p = q_ptr;
        !           211: 
        !           212:        if (q_count == 0) return;
        !           213: 
        !           214:        printf("\tobjectects on queue:\n");
        !           215: 
        !           216:        do {
        !           217:                p->print(n);
        !           218:                p = p->o_next;
        !           219:        } while (p != q_ptr);
        !           220: 
        !           221:        printf("\n");
        !           222: }
        !           223: 
        !           224: int qhead::o_type()
        !           225: {
        !           226:        return QHEAD;
        !           227: }
        !           228: 

unix.superglobalmegacorp.com

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