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