|
|
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.