aboutsummaryrefslogtreecommitdiffstats
path: root/mps/code
diff options
context:
space:
mode:
authorRichard Kistruck2008-12-16 17:46:45 +0000
committerRichard Kistruck2008-12-16 17:46:45 +0000
commitcbe281b73c1dbaac456237d96f2396e8323d04c2 (patch)
treef4c3a350825b8484159b1e0beea8f06e35f62e40 /mps/code
parentcd8f0ed2ad9c3580594d260a7e7aa64d11fa47cf (diff)
downloademacs-cbe281b73c1dbaac456237d96f2396e8323d04c2.tar.gz
emacs-cbe281b73c1dbaac456237d96f2396e8323d04c2.zip
Mps br/timing z001989a.c: "!" means get but don't discarrd messages,
to check MPS copes okay. See .discard. Also: improve comments. Copied from Perforce Change: 166953 ServerID: perforce.ravenbrook.com
Diffstat (limited to 'mps/code')
-rw-r--r--mps/code/z001989a.c106
1 files changed, 83 insertions, 23 deletions
diff --git a/mps/code/z001989a.c b/mps/code/z001989a.c
index 1e26c563eb0..3c5c82f1473 100644
--- a/mps/code/z001989a.c
+++ b/mps/code/z001989a.c
@@ -30,20 +30,24 @@
30 * The actions, messages to check for, and get times, are scripted 30 * The actions, messages to check for, and get times, are scripted
31 * using a simple text code: 31 * using a simple text code:
32 * C - action: request garbage-collection; 32 * C - action: request garbage-collection;
33 * F - action: make a (registered)finalized object unreachable; 33 * F - action: make a (registered)finalized object unreachable
34 * (note: this drops the myroot ref, but some objects are
35 * deliberately kept alive by additional references; see
36 * .keep-alive)
34 * b - message produced: collection begin (mps_message_type_gc_start); 37 * b - message produced: collection begin (mps_message_type_gc_start);
35 * e - message produced: collection end (mps_message_type_gc); 38 * e - message produced: collection end (mps_message_type_gc);
36 * f - message produced: finalization (mps_message_type_finalization); 39 * f - message produced: finalization (mps_message_type_finalization);
37 * . - get messages. 40 * . - get messages.
41 * ! - get messages without discarding (see .discard).
38 * 42 *
39 * Example: 43 * Example:
40 * script "Cbe.FFCbffe.Cbe" 44 * script "Cbe.FFCbffe.Cbe"
41 * means: 45 * means:
42 * Requests a collection and checks for _gc_start and _gc messages 46 * Request a collection and check for _gc_start and _gc messages
43 * (in that order, and no other messages). Then drops refs to two 47 * (in that order, and no other messages). Then drop refs to two
44 * objects, requests another collection, and checks for _gc_start, 48 * objects, request another collection, and check for _gc_start,
45 * the two finalization messages (in either order), and _gc. Then 49 * the two finalization messages (in either order), and _gc. Then
46 * Requests a third collection and ends the test WITHOUT GETTING 50 * request a third collection and end the test WITHOUT GETTING
47 * the last two messages (note: no "."), to test that 51 * the last two messages (note: no "."), to test that
48 * mps_arena_destroy copes with ungot messages. 52 * mps_arena_destroy copes with ungot messages.
49 * 53 *
@@ -118,8 +122,17 @@ enum {
118 * Get messages, report what was got, check they are the expected 122 * Get messages, report what was got, check they are the expected
119 * messages, and (for finalization messages) check that these objects 123 * messages, and (for finalization messages) check that these objects
120 * should have been finalized (because we made them unreachable). 124 * should have been finalized (because we made them unreachable).
125 *
126 * .discard: The client should always call mps_message_discard when
127 * it has finished with the message. But calling with the "discard"
128 * parameter set to false lets us check how the MPS handles naughty
129 * clients. The undiscarded messages should be cleared up by
130 * ArenaDestroy. In a diagnostic variety (eg .variety.di) the
131 * ArenaDestroy diag shows the contents of the control pool, and you
132 * can clearly see the undiscarded messages (just before the control
133 * pool is destroyed).
121 */ 134 */
122static void report(mps_arena_t arena, const char *pm) 135static void report(mps_arena_t arena, const char *pm, Bool discard)
123{ 136{
124 int found = 0; 137 int found = 0;
125 char mFound = '\0'; 138 char mFound = '\0';
@@ -139,13 +152,11 @@ static void report(mps_arena_t arena, const char *pm)
139 switch(type) { 152 switch(type) {
140 case mps_message_type_gc_start(): { 153 case mps_message_type_gc_start(): {
141 printf(" Begin Collection\n"); 154 printf(" Begin Collection\n");
142 mps_message_discard(arena, message);
143 mFound = 'b'; 155 mFound = 'b';
144 break; 156 break;
145 } 157 }
146 case mps_message_type_gc(): { 158 case mps_message_type_gc(): {
147 printf(" End Collection\n"); 159 printf(" End Collection\n");
148 mps_message_discard(arena, message);
149 mFound = 'e'; 160 mFound = 'e';
150 break; 161 break;
151 } 162 }
@@ -157,7 +168,6 @@ static void report(mps_arena_t arena, const char *pm)
157 cdie(myroot[objind] == NULL, "finalized live"); 168 cdie(myroot[objind] == NULL, "finalized live");
158 cdie(state[objind] == finalizableSTATE, "not finalizable"); 169 cdie(state[objind] == finalizableSTATE, "not finalizable");
159 state[objind] = finalizedSTATE; 170 state[objind] = finalizedSTATE;
160 mps_message_discard(arena, message);
161 mFound = 'f'; 171 mFound = 'f';
162 break; 172 break;
163 } 173 }
@@ -167,6 +177,10 @@ static void report(mps_arena_t arena, const char *pm)
167 } 177 }
168 } 178 }
169 179
180 if(discard) {
181 mps_message_discard(arena, message); /* .discard */
182 }
183
170 cdie('\0' != *pm, "Found message, but did not expect any"); 184 cdie('\0' != *pm, "Found message, but did not expect any");
171 cdie(mFound == *pm, "Found message type != Expected message type"); 185 cdie(mFound == *pm, "Found message type != Expected message type");
172 pm++; 186 pm++;
@@ -187,7 +201,7 @@ static void testscriptC(mps_arena_t arena, const char *script)
187 unsigned hiNext = myrootCOUNT - 1; 201 unsigned hiNext = myrootCOUNT - 1;
188 unsigned i; 202 unsigned i;
189 const char *scriptAll = script; 203 const char *scriptAll = script;
190 char am[10]; /* Array of Messages (expected but not yet got) */ 204 char am[100]; /* Array of Messages (expected but not yet got) */
191 char *pmNext = am; /* Pointer to where Next Message will be stored */ 205 char *pmNext = am; /* Pointer to where Next Message will be stored */
192 206
193 while(*script != '\0') { 207 while(*script != '\0') {
@@ -195,11 +209,22 @@ static void testscriptC(mps_arena_t arena, const char *script)
195 case '.': { 209 case '.': {
196 *pmNext = '\0'; 210 *pmNext = '\0';
197 printf(" Getting messages (expecting \"%s\")...\n", am); 211 printf(" Getting messages (expecting \"%s\")...\n", am);
198 report(arena, am); 212 report(arena, am, TRUE);
199 printf(" ...done.\n"); 213 printf(" ...done.\n");
200 pmNext = am; 214 pmNext = am;
201 break; 215 break;
202 } 216 }
217 case '!': {
218 *pmNext = '\0';
219 printf(" Getting messages (expecting \"%s\")...\n", am);
220 /* FALSE: see .discard */
221 report(arena, am, FALSE);
222 printf(" ...done.\n");
223 printf(" NOTE: DELIBERATELY FAILING TO DISCARD MESSAGES, "
224 "TO SEE HOW MPS COPES.\n"); /* .discard */
225 pmNext = am;
226 break;
227 }
203 case 'C': { 228 case 'C': {
204 printf(" Collect\n"); 229 printf(" Collect\n");
205 mps_arena_collect(arena); 230 mps_arena_collect(arena);
@@ -210,8 +235,10 @@ static void testscriptC(mps_arena_t arena, const char *script)
210 i = isLoNext ? loNext++ : hiNext--; 235 i = isLoNext ? loNext++ : hiNext--;
211 isLoNext = 1 - isLoNext; 236 isLoNext = 1 - isLoNext;
212 237
213 printf(" drop ref to make object %u Finalizable\n", i); 238 printf(" Drop myroot ref to object %u -- "
214 /* make i finalizable */ 239 "this might make it Finalizable\n", i);
240 /* drop myroot ref, to perhaps make i finalizable */
241 /* (but see .keep-alive) */
215 myroot[i] = NULL; 242 myroot[i] = NULL;
216 state[i] = finalizableSTATE; 243 state[i] = finalizableSTATE;
217 break; 244 break;
@@ -302,17 +329,30 @@ static void *testscriptB(void *arg, size_t s)
302 state[i] = rootSTATE; 329 state[i] = rootSTATE;
303 } 330 }
304 331
305 /* leave 0 and N containing NULL refs */ 332 /* .keep-alive: Create some additional inter-object references.
333 *
334 * 1 and N-1 don't die until myroot refs to both have been nulled.
335 *
336 * 2 and 3 don't die until myroot refs to both have been nulled.
337 *
338 * We do this to check that reachability via non-root refs prevents
339 * finalization.
340 */
341
342 /* Leave 0 and N containing NULL refs */
306 343
307 /* make 1 and N-1 refer to each other */ 344 /* Make 1 and N-1 refer to each other */
308 DYLAN_VECTOR_SLOT(myroot[1] , 1) = (mps_word_t)myroot[N-1]; 345 DYLAN_VECTOR_SLOT(myroot[1] , 1) = (mps_word_t)myroot[N-1];
309 DYLAN_VECTOR_SLOT(myroot[N-1], 1) = (mps_word_t)myroot[1]; 346 DYLAN_VECTOR_SLOT(myroot[N-1], 1) = (mps_word_t)myroot[1];
310 347
311 /* make 2 and 3 refer to each other */ 348 /* Make 2 and 3 refer to each other */
312 DYLAN_VECTOR_SLOT(myroot[2], 1) = (mps_word_t)myroot[3]; 349 DYLAN_VECTOR_SLOT(myroot[2], 1) = (mps_word_t)myroot[3];
313 DYLAN_VECTOR_SLOT(myroot[3], 1) = (mps_word_t)myroot[2]; 350 DYLAN_VECTOR_SLOT(myroot[3], 1) = (mps_word_t)myroot[2];
314 351
315 /* stop stack scanning, to prevent unwanted object retention */ 352 /* Stop stack scanning, otherwise stack or register dross from */
353 /* these setup functions can cause unwanted object retention, */
354 /* which would mean we don't get the finalization messages we */
355 /* expect. */
316 mps_root_destroy(root_stackreg); 356 mps_root_destroy(root_stackreg);
317 357
318 mps_message_type_enable(arena, mps_message_type_gc_start()); 358 mps_message_type_enable(arena, mps_message_type_gc_start());
@@ -374,18 +414,38 @@ int main(int argc, char **argv)
374 414
375 randomize(argc, argv); 415 randomize(argc, argv);
376 416
377 /* really basic scripts */ 417 /* Scripts that should fail (uncomment to show failure is detected) */
418 /*testscriptA("C.");*/
419 /*testscriptA("b.");*/
420
421 /* The most basic scripts */
422 testscriptA(".");
378 testscriptA("Cbe."); 423 testscriptA("Cbe.");
424 testscriptA("Cbe.Cbe.");
425
426 /* Get messages, but not promptly */
379 testscriptA(".Cbe.CbeCbeCbe."); 427 testscriptA(".Cbe.CbeCbeCbe.");
380 testscriptA(".Cbe.CbeCbeCbe");
381 428
382 /* simple finalization */ 429 /* Ungot messages at ArenaDestroy */
430 testscriptA("Cbe");
431 testscriptA("Cbe.CbeCbeCbe");
432
433 /* Fail to call mps_message_discard */
434 testscriptA("Cbe!");
435 testscriptA("Cbe!CbeCbeCbe!");
436
437 /* Simple finalization
438 *
439 * These tests rely on the particular order in which the "F" command
440 * nulls-out references. Not every "F" makes an object finalizable.
441 * See .keep-alive.
442 */
383 testscriptA("FFCbffe."); 443 testscriptA("FFCbffe.");
384 testscriptA("FFCbffe.FFCbffe."); 444 testscriptA("FFCbffe.FFCbffe.");
385 testscriptA("FFCbffe.FCbe.F.Cbffe.FFCbfe.FF.Cbfffe."); 445 testscriptA("FFCbffe.FCbe.F.Cbffe.FFCbfe.FF.Cbfffe.");
386 446
387 /* test failure: */ 447 /* Various other scripts */
388 /*testscriptA("FC.");*/ 448 testscriptA("Cbe.FFCbffe.Cbe");
389 449
390 fflush(stdout); /* synchronize */ 450 fflush(stdout); /* synchronize */
391 fprintf(stderr, "\nConclusion: Failed to find any defects.\n"); 451 fprintf(stderr, "\nConclusion: Failed to find any defects.\n");