aboutsummaryrefslogtreecommitdiffstats
path: root/mps/code
diff options
context:
space:
mode:
authorGareth Rees2013-05-20 20:40:16 +0100
committerGareth Rees2013-05-20 20:40:16 +0100
commitdf1a8a3807db2d085e668aa625a0734d79e46eec (patch)
treeab1dcfa387c85deb775b777df5963806460f9696 /mps/code
parent217831cc47e7b2a4c02513cd8f3dddf32604faa5 (diff)
downloademacs-df1a8a3807db2d085e668aa625a0734d79e46eec.tar.gz
emacs-df1a8a3807db2d085e668aa625a0734d79e46eec.zip
Make the abq module manage elements of arbitrary type (knowing only their address and size) instead of managing cbsblock only. (this is preparatory to removing cbsblock from the cbs public interface.)
Update abqtest to use the new interface. Add ABQ design. Copied from Perforce Change: 182013 ServerID: perforce.ravenbrook.com
Diffstat (limited to 'mps/code')
-rw-r--r--mps/code/abq.c199
-rw-r--r--mps/code/abq.h33
-rw-r--r--mps/code/abqtest.c57
3 files changed, 169 insertions, 120 deletions
diff --git a/mps/code/abq.c b/mps/code/abq.c
index e29a9786599..c327a721a54 100644
--- a/mps/code/abq.c
+++ b/mps/code/abq.c
@@ -1,18 +1,15 @@
1/* abq.c: AVAILABLE BLOCK QUEUE 1/* abq.c: QUEUE IMPLEMENTATION
2 * 2 *
3 * $Id$ 3 * $Id$
4 * Copyright (c) 2001 Ravenbrook Limited. See end of file for license. 4 * Copyright (c) 2001 Ravenbrook Limited. See end of file for license.
5 * 5 *
6 * .readership: Any MPS developer 6 * .purpose: A fixed-length FIFO queue.
7 * 7 *
8 * .purpose: A FIFO queue substrate for <code/poolmv2.c> 8 * .design: <design/abq/>
9 *
10 * .design: See <design/poolmvt/>
11 */ 9 */
12 10
13#include "meter.h" 11#include "meter.h"
14#include "abq.h" 12#include "abq.h"
15#include "cbs.h"
16#include "mpm.h" 13#include "mpm.h"
17 14
18SRCID(abq, "$Id$"); 15SRCID(abq, "$Id$");
@@ -20,37 +17,39 @@ SRCID(abq, "$Id$");
20 17
21/* Private prototypes */ 18/* Private prototypes */
22 19
23static Size ABQQueueSize(Count elements); 20static Size ABQQueueSize(Count elements, Size elementSize);
24static Index ABQNextIndex(ABQ abq, Index index); 21static Index ABQNextIndex(ABQ abq, Index index);
22static Addr ABQElement(ABQ abq, Index index);
25 23
26 24
27/* Methods */ 25/* Methods */
28 26
29/* ABQInit -- Initialize an ABQ 27/* ABQInit -- Initialize an ABQ
30 * 28 *
31 * items is the number of items the queue can hold 29 * elements is the number of elements the queue can hold
32 */ 30 */
33Res ABQInit(Arena arena, ABQ abq, void *owner, Count items) 31Res ABQInit(Arena arena, ABQ abq, void *owner, Count elements, Size elementSize)
34{ 32{
35 Count elements;
36 void *p; 33 void *p;
37 Res res; 34 Res res;
38 35
39 AVERT(Arena, arena); 36 AVERT(Arena, arena);
40 AVER(abq != NULL); 37 AVER(abq != NULL);
41 AVER(items > 0); 38 AVER(elements > 0);
42 39
43 elements = items + 1; 40 /* Necessary in order to be able to distinguish "empty" from "full" */
44 41 elements = elements + 1;
45 res = ControlAlloc(&p, arena, ABQQueueSize(elements), 42
43 res = ControlAlloc(&p, arena, ABQQueueSize(elements, elementSize),
46 /* withReservoirPermit */ FALSE); 44 /* withReservoirPermit */ FALSE);
47 if (res != ResOK) 45 if (res != ResOK)
48 return res; 46 return res;
49 47
50 abq->elements = elements; 48 abq->elements = elements;
49 abq->elementSize = elementSize;
51 abq->in = 0; 50 abq->in = 0;
52 abq->out = 0; 51 abq->out = 0;
53 abq->queue = (CBSBlock *)p; 52 abq->queue = p;
54 53
55 METER_INIT(abq->push, "push", owner); 54 METER_INIT(abq->push, "push", owner);
56 METER_INIT(abq->pop, "pop", owner); 55 METER_INIT(abq->pop, "pop", owner);
@@ -67,19 +66,12 @@ Res ABQInit(Arena arena, ABQ abq, void *owner, Count items)
67/* ABQCheck -- validate an ABQ */ 66/* ABQCheck -- validate an ABQ */
68Bool ABQCheck(ABQ abq) 67Bool ABQCheck(ABQ abq)
69{ 68{
70 Index index;
71
72 CHECKS(ABQ, abq); 69 CHECKS(ABQ, abq);
73 CHECKL(abq->elements > 0); 70 CHECKL(abq->elements > 0);
71 CHECKL(abq->elementSize > 0);
74 CHECKL(abq->in < abq->elements); 72 CHECKL(abq->in < abq->elements);
75 CHECKL(abq->out < abq->elements); 73 CHECKL(abq->out < abq->elements);
76 CHECKL(abq->queue != NULL); 74 CHECKL(abq->queue != NULL);
77 /* Is this really a local check? */
78 for (index = abq->out; index != abq->in; ) {
79 CHECKL(CBSBlockCheck(abq->queue[index]));
80 if (++index == abq->elements)
81 index = 0;
82 }
83 75
84 return TRUE; 76 return TRUE;
85} 77}
@@ -95,7 +87,7 @@ void ABQFinish(Arena arena, ABQ abq)
95 METER_EMIT(&abq->pop); 87 METER_EMIT(&abq->pop);
96 METER_EMIT(&abq->peek); 88 METER_EMIT(&abq->peek);
97 METER_EMIT(&abq->delete); 89 METER_EMIT(&abq->delete);
98 ControlFree(arena, abq->queue, ABQQueueSize(abq->elements)); 90 ControlFree(arena, abq->queue, ABQQueueSize(abq->elements, abq->elementSize));
99 91
100 abq->elements = 0; 92 abq->elements = 0;
101 abq->queue = NULL; 93 abq->queue = NULL;
@@ -104,18 +96,17 @@ void ABQFinish(Arena arena, ABQ abq)
104} 96}
105 97
106 98
107/* ABQPush -- push a block onto the tail of the ABQ */ 99/* ABQPush -- push an element onto the tail of the ABQ */
108Res ABQPush(ABQ abq, CBSBlock block) 100Res ABQPush(ABQ abq, Addr element)
109{ 101{
110 AVERT(ABQ, abq); 102 AVERT(ABQ, abq);
111 AVERT(CBSBlock, block);
112 103
113 METER_ACC(abq->push, ABQDepth(abq)); 104 METER_ACC(abq->push, ABQDepth(abq));
114 105
115 if (ABQIsFull(abq)) 106 if (ABQIsFull(abq))
116 return ResFAIL; 107 return ResFAIL;
117 108
118 abq->queue[abq->in] = block; 109 mps_lib_memcpy(ABQElement(abq, abq->in), element, abq->elementSize);
119 abq->in = ABQNextIndex(abq, abq->in); 110 abq->in = ABQNextIndex(abq, abq->in);
120 111
121 AVERT(ABQ, abq); 112 AVERT(ABQ, abq);
@@ -123,10 +114,10 @@ Res ABQPush(ABQ abq, CBSBlock block)
123} 114}
124 115
125 116
126/* ABQPop -- pop a block from the head of the ABQ */ 117/* ABQPop -- pop an element from the head of the ABQ */
127Res ABQPop(ABQ abq, CBSBlock *blockReturn) 118Res ABQPop(ABQ abq, Addr elementReturn)
128{ 119{
129 AVER(blockReturn != NULL); 120 AVER(elementReturn != NULL);
130 AVERT(ABQ, abq); 121 AVERT(ABQ, abq);
131 122
132 METER_ACC(abq->pop, ABQDepth(abq)); 123 METER_ACC(abq->pop, ABQDepth(abq));
@@ -134,8 +125,7 @@ Res ABQPop(ABQ abq, CBSBlock *blockReturn)
134 if (ABQIsEmpty(abq)) 125 if (ABQIsEmpty(abq))
135 return ResFAIL; 126 return ResFAIL;
136 127
137 *blockReturn = abq->queue[abq->out]; 128 mps_lib_memcpy(elementReturn, ABQElement(abq, abq->out), abq->elementSize);
138 AVERT(CBSBlock, *blockReturn);
139 129
140 abq->out = ABQNextIndex(abq, abq->out); 130 abq->out = ABQNextIndex(abq, abq->out);
141 131
@@ -145,9 +135,9 @@ Res ABQPop(ABQ abq, CBSBlock *blockReturn)
145 135
146 136
147/* ABQPeek -- peek at the head of the ABQ */ 137/* ABQPeek -- peek at the head of the ABQ */
148Res ABQPeek(ABQ abq, CBSBlock *blockReturn) 138Res ABQPeek(ABQ abq, Addr elementReturn)
149{ 139{
150 AVER(blockReturn != NULL); 140 AVER(elementReturn != NULL);
151 AVERT(ABQ, abq); 141 AVERT(ABQ, abq);
152 142
153 METER_ACC(abq->peek, ABQDepth(abq)); 143 METER_ACC(abq->peek, ABQDepth(abq));
@@ -155,8 +145,7 @@ Res ABQPeek(ABQ abq, CBSBlock *blockReturn)
155 if (ABQIsEmpty(abq)) 145 if (ABQIsEmpty(abq))
156 return ResFAIL; 146 return ResFAIL;
157 147
158 *blockReturn = abq->queue[abq->out]; 148 mps_lib_memcpy(elementReturn, ABQElement(abq, abq->out), abq->elementSize);
159 AVERT(CBSBlock, *blockReturn);
160 149
161 /* Identical to pop, but don't increment out */ 150 /* Identical to pop, but don't increment out */
162 151
@@ -165,46 +154,49 @@ Res ABQPeek(ABQ abq, CBSBlock *blockReturn)
165} 154}
166 155
167 156
168/* ABQDelete -- delete a block from the ABQ */ 157typedef struct ABQDeleteClosureStruct *ABQDeleteClosure;
169Res ABQDelete(ABQ abq, CBSBlock block) 158typedef struct ABQDeleteClosureStruct {
159 Addr element;
160 Size elementSize;
161 Res res;
162} ABQDeleteClosureStruct;
163
164
165static Res ABQDeleteCallback(ABQDisposition *dispositionReturn, Addr element,
166 void *closureP)
167{
168 ABQDeleteClosure closure = closureP;
169 if (mps_lib_memcmp(element, closure->element, closure->elementSize) == 0) {
170 *dispositionReturn = ABQDispositionDELETE;
171 closure->res = ResOK;
172 } else {
173 *dispositionReturn = ABQDispositionKEEP;
174 }
175 return ResOK;
176}
177
178
179/* ABQDelete -- delete an element from the ABQ */
180Res ABQDelete(ABQ abq, Addr element)
170{ 181{
171 Index index, next, in; 182 ABQDeleteClosureStruct closure;
172 CBSBlock *queue;
173 183
174 AVERT(ABQ, abq); 184 AVERT(ABQ, abq);
175 AVERT(CBSBlock, block);
176 185
177 METER_ACC(abq->delete, ABQDepth(abq)); 186 METER_ACC(abq->delete, ABQDepth(abq));
178 187
179 index = abq->out; 188 closure.element = element;
180 in = abq->in; 189 closure.elementSize = abq->elementSize;
181 queue = abq->queue; 190 closure.res = ResFAIL;
182
183 while (index != in) {
184 if (queue[index] == block) {
185 goto found;
186 }
187 index = ABQNextIndex(abq, index);
188 }
189
190 return ResFAIL;
191 191
192found: 192 ABQIterate(abq, ABQDeleteCallback, &closure);
193 /* index points to the node to be removed */ 193
194 next = ABQNextIndex(abq, index); 194 return closure.res;
195 while (next != in) {
196 queue[index] = queue[next];
197 index = next;
198 next = ABQNextIndex(abq, index);
199 }
200 abq->in = index;
201 AVERT(ABQ, abq);
202 return ResOK;
203} 195}
204 196
205 197
206/* ABQDescribe -- Describe an ABQ */ 198/* ABQDescribe -- Describe an ABQ */
207Res ABQDescribe(ABQ abq, mps_lib_FILE *stream) 199Res ABQDescribe(ABQ abq, ABQDescribeElement describeElement, mps_lib_FILE *stream)
208{ 200{
209 Res res; 201 Res res;
210 Index index; 202 Index index;
@@ -224,11 +216,10 @@ Res ABQDescribe(ABQ abq, mps_lib_FILE *stream)
224 return res; 216 return res;
225 217
226 for (index = abq->out; index != abq->in; ) { 218 for (index = abq->out; index != abq->in; ) {
227 res = CBSBlockDescribe(abq->queue[index], stream); 219 res = (*describeElement)(ABQElement(abq, index), stream);
228 if(res != ResOK) 220 if(res != ResOK)
229 return res; 221 return res;
230 if (++index == abq->elements) 222 index = ABQNextIndex(abq, index);
231 index = 0;
232 } 223 }
233 224
234 res = WriteF(stream, "\n", NULL); 225 res = WriteF(stream, "\n", NULL);
@@ -274,7 +265,7 @@ Bool ABQIsFull(ABQ abq)
274} 265}
275 266
276 267
277/* ABQDepth -- return the number of items in an ABQ */ 268/* ABQDepth -- return the number of elements in an ABQ */
278Count ABQDepth(ABQ abq) 269Count ABQDepth(ABQ abq)
279{ 270{
280 Index out, in; 271 Index out, in;
@@ -290,13 +281,65 @@ Count ABQDepth(ABQ abq)
290} 281}
291 282
292 283
284/* ABQDispositionCheck -- check method for an ABQDisposition value */
285static Bool ABQDispositionCheck(ABQDisposition disposition)
286{
287 CHECKL(disposition == ABQDispositionKEEP
288 || disposition == ABQDispositionDELETE);
289 UNUSED(disposition); /* <code/mpm.c#check.unused> */
290
291 return TRUE;
292}
293
294
295/* ABQIterate -- call 'iterate' for each element in an ABQ */
296void ABQIterate(ABQ abq, ABQIterateMethod iterate, void *closureP)
297{
298 Index copy, index, in;
299 Res res;
300
301 AVERT(ABQ, abq);
302 AVER(FUNCHECK(iterate));
303
304 copy = abq->out;
305 index = abq->out;
306 in = abq->in;
307
308 while (index != in) {
309 Addr element = ABQElement(abq, index);
310 ABQDisposition disposition = ABQDispositionNONE;
311 res = (*iterate)(&disposition, element, closureP);
312 AVERT(ABQDisposition, disposition);
313 if (disposition == ABQDispositionKEEP) {
314 if (copy != index)
315 mps_lib_memcpy(ABQElement(abq, copy), element, abq->elementSize);
316 copy = ABQNextIndex(abq, copy);
317 }
318 index = ABQNextIndex(abq, index);
319 if (res != ResOK)
320 break;
321 }
322
323 /* If any elements were deleted, need to copy remainder of queue. */
324 if (copy != index) {
325 while (index != in) {
326 mps_lib_memcpy(ABQElement(abq, copy), ABQElement(abq, index),
327 abq->elementSize);
328 copy = ABQNextIndex(abq, copy);
329 index = ABQNextIndex(abq, index);
330 }
331 abq->in = copy;
332 }
333
334 AVERT(ABQ, abq);
335}
336
337
293/* ABQQueueSize -- calculate the storage required for the vector to 338/* ABQQueueSize -- calculate the storage required for the vector to
294 store elements items */ 339 store the elements */
295static Size ABQQueueSize(Count elements) 340static Size ABQQueueSize(Count elements, Size elementSize)
296{ 341{
297 /* strange but true: the sizeof expression calculates the size of a 342 return (Size)(elements * elementSize);
298 single queue element */
299 return (Size)(sizeof(((ABQ)NULL)->queue[0]) * elements);
300} 343}
301 344
302 345
@@ -310,6 +353,12 @@ static Index ABQNextIndex(ABQ abq, Index index)
310 return next; 353 return next;
311} 354}
312 355
356/* ABQElement -- return pointer to the index'th element in the queue
357 vector. */
358static Addr ABQElement(ABQ abq, Index index) {
359 return AddrAdd(abq->queue, index * abq->elementSize);
360}
361
313 362
314/* C. COPYRIGHT AND LICENSE 363/* C. COPYRIGHT AND LICENSE
315 * 364 *
diff --git a/mps/code/abq.h b/mps/code/abq.h
index e39635dfcaa..085b1ed3d66 100644
--- a/mps/code/abq.h
+++ b/mps/code/abq.h
@@ -1,18 +1,17 @@
1/* abq.h: ABQ INTERFACE 1/* abq.h: QUEUE INTERFACE
2 * 2 *
3 * $Id$ 3 * $Id$
4 * Copyright (c) 2001 Ravenbrook Limited. See end of file for license. 4 * Copyright (c) 2001 Ravenbrook Limited. See end of file for license.
5 * 5 *
6 * .purpose: A FIFO queue substrate for <code/poolmv2.c> 6 * .purpose: A fixed-length FIFO queue.
7 * 7 *
8 * .source: <design/poolmvt/> 8 * .design: <design/abq/>
9 */ 9 */
10 10
11#ifndef abq_h 11#ifndef abq_h
12#define abq_h 12#define abq_h
13 13
14#include "meter.h" 14#include "meter.h"
15#include "cbs.h"
16#include "mpm.h" 15#include "mpm.h"
17 16
18 17
@@ -24,17 +23,22 @@
24/* Prototypes */ 23/* Prototypes */
25 24
26typedef struct ABQStruct *ABQ; 25typedef struct ABQStruct *ABQ;
27extern Res ABQInit(Arena arena, ABQ abq, void *owner, Count items); 26typedef Res (*ABQDescribeElement)(Addr element, mps_lib_FILE *stream);
27typedef unsigned ABQDisposition;
28typedef Res (*ABQIterateMethod)(ABQDisposition *dispositionReturn, Addr element, void *closureP);
29
30extern Res ABQInit(Arena arena, ABQ abq, void *owner, Count elements, Size elementSize);
28extern Bool ABQCheck(ABQ abq); 31extern Bool ABQCheck(ABQ abq);
29extern void ABQFinish(Arena arena, ABQ abq); 32extern void ABQFinish(Arena arena, ABQ abq);
30extern Res ABQPush(ABQ abq, CBSBlock block); 33extern Res ABQPush(ABQ abq, Addr element);
31extern Res ABQPop(ABQ abq, CBSBlock *blockReturn); 34extern Res ABQPop(ABQ abq, Addr elementReturn);
32extern Res ABQPeek(ABQ abq, CBSBlock *blockReturn); 35extern Res ABQPeek(ABQ abq, Addr elementReturn);
33extern Res ABQDelete(ABQ abq, CBSBlock block); 36extern Res ABQDelete(ABQ abq, Addr element);
34extern Res ABQDescribe(ABQ abq, mps_lib_FILE *stream); 37extern Res ABQDescribe(ABQ abq, ABQDescribeElement describeElement, mps_lib_FILE *stream);
35extern Bool ABQIsEmpty(ABQ abq); 38extern Bool ABQIsEmpty(ABQ abq);
36extern Bool ABQIsFull(ABQ abq); 39extern Bool ABQIsFull(ABQ abq);
37extern Count ABQDepth(ABQ abq); 40extern Count ABQDepth(ABQ abq);
41extern void ABQIterate(ABQ abq, ABQIterateMethod iterate, void *closureP);
38 42
39 43
40/* Types */ 44/* Types */
@@ -42,9 +46,10 @@ extern Count ABQDepth(ABQ abq);
42typedef struct ABQStruct 46typedef struct ABQStruct
43{ 47{
44 Count elements; 48 Count elements;
49 Size elementSize;
45 Index in; 50 Index in;
46 Index out; 51 Index out;
47 CBSBlock *queue; 52 Addr queue;
48 53
49 /* Meter queue depth at each operation */ 54 /* Meter queue depth at each operation */
50 METER_DECL(push); 55 METER_DECL(push);
@@ -55,6 +60,12 @@ typedef struct ABQStruct
55 Sig sig; 60 Sig sig;
56} ABQStruct; 61} ABQStruct;
57 62
63enum {
64 ABQDispositionKEEP = 1, /* keep item in queue */
65 ABQDispositionDELETE, /* delete element from queue */
66 ABQDispositionNONE /* no disposition (error) */
67};
68
58#endif /* abq_h */ 69#endif /* abq_h */
59 70
60 71
diff --git a/mps/code/abqtest.c b/mps/code/abqtest.c
index 7de0ee537a7..f1685cde4b7 100644
--- a/mps/code/abqtest.c
+++ b/mps/code/abqtest.c
@@ -41,54 +41,42 @@ static unsigned popee = 1;
41static unsigned deleted = 0; 41static unsigned deleted = 0;
42 42
43 43
44typedef struct TestStruct *Test; 44typedef struct TestBlockStruct *TestBlock;
45 45
46typedef struct TestStruct 46typedef struct TestBlockStruct
47{ 47{
48 Test next; 48 TestBlock next;
49 unsigned id; 49 unsigned id;
50 CBSBlockStruct cbsBlockStruct; 50 Addr base;
51} TestStruct; 51 Addr limit;
52} TestBlockStruct;
52 53
53 54
54static CBSBlock TestCBSBlock(Test t) 55static TestBlock testBlocks = NULL;
55{
56 return &t->cbsBlockStruct;
57}
58
59static Test CBSBlockTest(CBSBlock c)
60{
61 return PARENT(TestStruct, cbsBlockStruct, c);
62}
63
64 56
65static Test testBlocks = NULL;
66 57
67 58static TestBlock CreateTestBlock(unsigned no)
68static CBSBlock CreateCBSBlock(unsigned no)
69{ 59{
70 Test b = malloc(sizeof(TestStruct)); 60 TestBlock b = malloc(sizeof(TestBlockStruct));
71 cdie(b != NULL, "malloc"); 61 cdie(b != NULL, "malloc");
72 62
73 b->next = testBlocks; 63 b->next = testBlocks;
74 b->id = no; 64 b->id = no;
75 b->cbsBlockStruct.base = 0; 65 b->base = 0;
76 b->cbsBlockStruct.limit = 0; 66 b->limit = 0;
77 67
78 testBlocks = b; 68 testBlocks = b;
79 69
80 return TestCBSBlock(b); 70 return b;
81} 71}
82 72
83 73
84static void DestroyCBSBlock(CBSBlock c) 74static void DestroyTestBlock(TestBlock b)
85{ 75{
86 Test b = CBSBlockTest(c);
87
88 if (b == testBlocks) 76 if (b == testBlocks)
89 testBlocks = b->next; 77 testBlocks = b->next;
90 else { 78 else {
91 Test prev; 79 TestBlock prev;
92 80
93 for (prev = testBlocks; prev != 0; prev = prev->next) 81 for (prev = testBlocks; prev != 0; prev = prev->next)
94 if (prev->next == b) { 82 if (prev->next == b) {
@@ -104,12 +92,13 @@ static void DestroyCBSBlock(CBSBlock c)
104static void step(void) 92static void step(void)
105{ 93{
106 Res res; 94 Res res;
107 CBSBlock a; 95 TestBlock a;
108 96
109 switch (abqRnd(9)) { 97 switch (abqRnd(9)) {
110 case 0: case 1: case 2: case 3: 98 case 0: case 1: case 2: case 3:
111 push: 99 push:
112 res = ABQPush(&abq, CreateCBSBlock(pushee)); 100 a = CreateTestBlock(pushee);
101 res = ABQPush(&abq, (Addr)&a);
113 if (res != ResOK) { 102 if (res != ResOK) {
114 goto pop; 103 goto pop;
115 } 104 }
@@ -117,7 +106,7 @@ static void step(void)
117 break; 106 break;
118 case 5: case 6: case 7: case 8: 107 case 5: case 6: case 7: case 8:
119 pop: 108 pop:
120 res = ABQPop(&abq, &a); 109 res = ABQPop(&abq, (Addr)&a);
121 if (res != ResOK){ 110 if (res != ResOK){
122 goto push; 111 goto push;
123 } 112 }
@@ -125,20 +114,20 @@ static void step(void)
125 popee++; 114 popee++;
126 deleted = 0; 115 deleted = 0;
127 } 116 }
128 cdie(CBSBlockTest(a)->id == popee, "pop"); 117 cdie(a->id == popee, "pop");
129 popee++; 118 popee++;
130 DestroyCBSBlock(a); 119 DestroyTestBlock(a);
131 break; 120 break;
132 default: 121 default:
133 if (!deleted & (pushee > popee)) { 122 if (!deleted & (pushee > popee)) {
134 Test b; 123 TestBlock b;
135 124
136 deleted = (unsigned)abqRnd (pushee - popee) + popee; 125 deleted = (unsigned)abqRnd (pushee - popee) + popee;
137 for (b = testBlocks; b != NULL; b = b->next) 126 for (b = testBlocks; b != NULL; b = b->next)
138 if (b->id == deleted) 127 if (b->id == deleted)
139 break; 128 break;
140 cdie(b != NULL, "found to delete"); 129 cdie(b != NULL, "found to delete");
141 res = ABQDelete(&abq, TestCBSBlock(b)); 130 res = ABQDelete(&abq, (Addr)&b);
142 cdie(res == ResOK, "ABQDelete"); 131 cdie(res == ResOK, "ABQDelete");
143 } 132 }
144 } 133 }
@@ -159,7 +148,7 @@ extern int main(int argc, char *argv[])
159 die(mps_arena_create(&arena, mps_arena_class_vm(), testArenaSIZE), 148 die(mps_arena_create(&arena, mps_arena_class_vm(), testArenaSIZE),
160 "mps_arena_create"); 149 "mps_arena_create");
161 150
162 die(ABQInit((Arena)arena, &abq, NULL, ABQ_SIZE), 151 die(ABQInit((Arena)arena, &abq, NULL, ABQ_SIZE, sizeof(TestBlock)),
163 "ABQInit"); 152 "ABQInit");
164 153
165 abqSize = ABQ_SIZE; 154 abqSize = ABQ_SIZE;