Annotation of researchv10no/cmd/cfront/libC/otask/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)
                     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.