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