|
|
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.