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