aboutsummaryrefslogtreecommitdiffstats
path: root/mps/code/eventrep.c
diff options
context:
space:
mode:
authorNick Barnes2001-10-31 14:40:56 +0000
committerNick Barnes2001-10-31 14:40:56 +0000
commit7acfca905d76140f4cc0b09c9a12de237de364cd (patch)
tree3ed8babfa3a73d30f29e08ca5d5adcda4ca4e826 /mps/code/eventrep.c
parentb7ce4893f9902d57cd67ac9a92fa6c3d5a8fc833 (diff)
downloademacs-7acfca905d76140f4cc0b09c9a12de237de364cd.tar.gz
emacs-7acfca905d76140f4cc0b09c9a12de237de364cd.zip
Branch imports for masters.
Copied from Perforce Change: 23678 ServerID: perforce.ravenbrook.com
Diffstat (limited to 'mps/code/eventrep.c')
-rw-r--r--mps/code/eventrep.c736
1 files changed, 736 insertions, 0 deletions
diff --git a/mps/code/eventrep.c b/mps/code/eventrep.c
new file mode 100644
index 00000000000..0d2738e5f45
--- /dev/null
+++ b/mps/code/eventrep.c
@@ -0,0 +1,736 @@
1/* impl.c.eventrep: Allocation replayer routines
2 * Copyright (C) 2000 Harlequin Limited. All rights reserved.
3 *
4 * $HopeName: MMsrc!eventrep.c(trunk.2) $
5 */
6
7#include "config.h"
8/* override variety setting for EVENT */
9#define EVENT
10
11#include "eventcom.h"
12#include "eventrep.h"
13#include "eventpro.h"
14#include "mpmtypes.h"
15
16#include "mps.h"
17#include "mpsavm.h"
18#include "mpsacl.h"
19#include "mpscmv.h"
20#include "mpscmvff.h"
21#include "mpscepvm.h"
22#include "fmtpstst.h"
23#include "mpscepdl.h"
24
25#include "table.h"
26
27#include <stddef.h> /* for size_t */
28#include <stdarg.h> /* for va_list */
29#include <stdlib.h> /* for EXIT_FAILURE */
30#include <stdio.h> /* for printf */
31#include "mpstd.h"
32#ifdef MPS_OS_SU
33#include "ossu.h"
34#endif
35
36
37typedef unsigned long ulong;
38
39
40/* Globals */
41
42static ulong totalEvents; /* count of events */
43static ulong discardedEvents; /* count of ignored events */
44static ulong unknownEvents; /* count of unknown events */
45
46static Bool partialLog;
47static Word eventTime;
48
49/* Dictionaries for translating from log to replay values */
50static Table arenaTable; /* dictionary of arenas */
51static Table poolTable; /* dictionary of poolReps */
52static Table apTable; /* dictionary of apReps */
53
54
55/* poolSupport -- describes pool support for explicit deallocation */
56
57enum {supportTruncate = 1, supportFree, supportNothing};
58typedef int poolSupport;
59
60
61/* objectTable -- object address mapping structure
62 *
63 * .obj-mapping.truncate: Pools that support truncate need to keep track
64 * of object end points as well. .obj-mapping.partial-free: Arbitrary
65 * partial free is not supported.
66 */
67
68typedef struct objectTableStruct {
69 Table startTable;
70 Table endTable;
71} objectTableStruct;
72typedef struct objectTableStruct *objectTable;
73
74
75/* poolRep -- pool tracking structure
76 *
77 * .pool.object-addr: Pools that support explicit free (or truncate)
78 * need to maintain a mapping from the addresses in the log to those in
79 * the replay.
80 *
81 * .bufclass: In order to create APs with the correct arguments, the
82 * replayer has to pick the right BufferInit event to use, as there's
83 * one for each superclass. The pool determines the buffer class, so
84 * we store its subclass level in the pool representation.
85 */
86
87typedef struct poolRepStruct {
88 mps_pool_t pool; /* the replay pool */
89 objectTable objects;
90 int bufferClassLevel; /* subclass level of the buffer class */
91} poolRepStruct;
92typedef struct poolRepStruct *poolRep;
93
94
95/* apRep -- ap tracking structure */
96
97typedef struct apRepStruct {
98 mps_ap_t ap; /* the replay ap */
99 objectTable objects; /* object mapping for the pool of this ap */
100} apRepStruct;
101typedef struct apRepStruct *apRep;
102
103
104/* PointerAdd -- add offset to pointer */
105
106#define PointerAdd(p, s) ((void *)((char *)(p) + (s)))
107#define PointerSub(p, s) ((void *)((char *)(p) - (s)))
108
109
110/* error -- error signalling */
111
112static void error(const char *format, ...)
113{
114 va_list args;
115
116 fflush(stdout); /* sync */
117 fprintf(stderr, "Failed @%lu ", (ulong)eventTime);
118 va_start(args, format);
119 vfprintf(stderr, format, args);
120 fprintf(stderr, "\n");
121 va_end(args);
122 exit(EXIT_FAILURE);
123}
124
125
126/* verify, verifyMPS -- check return values
127 *
128 * We don't use assert for this, because we want it in release as well.
129 */
130
131#define verifyMPS(res) \
132 MPS_BEGIN if ((res) != MPS_RES_OK) error("line %d MPS", __LINE__); MPS_END
133
134#define verify(cond) \
135 MPS_BEGIN if (!(cond)) error("line %d " #cond, __LINE__); MPS_END
136
137
138#ifdef MPS_PROD_EPCORE
139
140
141/* ensurePSFormat -- return the PS format, creating it, if necessary */
142
143static mps_fmt_t psFormat = NULL;
144
145static void ensurePSFormat(mps_fmt_t *fmtOut, mps_arena_t arena)
146{
147 mps_res_t eres;
148
149 if (psFormat == NULL) {
150 eres = mps_fmt_create_A(&psFormat, arena, ps_fmt_A());
151 verifyMPS(eres);
152 }
153 *fmtOut = psFormat;
154}
155
156
157/* finishPSFormat -- finish the PS format, if necessary */
158
159static void finishPSFormat(void)
160{
161 if (psFormat != NULL)
162 mps_fmt_destroy(psFormat);
163}
164
165
166#endif
167
168
169/* objectTableCreate -- create an objectTable */
170
171static objectTable objectTableCreate(poolSupport support)
172{
173 if (support != supportNothing) {
174 Res ires;
175 objectTable table;
176
177 table = malloc(sizeof(objectTableStruct));
178 verify(table != NULL);
179 ires = TableCreate(&table->startTable, (size_t)1<<12);
180 verify(ires == ResOK);
181 if (support == supportTruncate) {
182 ires = TableCreate(&table->endTable, (size_t)1<<12);
183 verify(ires == ResOK);
184 } else {
185 table->endTable = NULL;
186 }
187 return table;
188 } else {
189 return NULL;
190 }
191}
192
193
194/* objectTableDestroy -- destroy an objectTable */
195
196static void objectTableDestroy(objectTable table)
197{
198 if (table != NULL) {
199 TableDestroy(table->startTable);
200 if (table->endTable != NULL)
201 TableDestroy(table->endTable);
202 free(table);
203 }
204}
205
206
207/* objDefine -- add a new mapping to an objectTable */
208
209static void objDefine(objectTable table,
210 void *logObj, void *obj, size_t size)
211{
212 if (table != NULL) {
213 Res ires;
214
215 ires = TableDefine(table->startTable, (Word)logObj, obj);
216 verify(ires == ResOK);
217 if (table->endTable != NULL) {
218 ires = TableDefine(table->endTable,
219 (Word)PointerAdd(logObj, size),
220 PointerAdd(obj, size));
221 verify(ires == ResOK);
222 }
223 }
224}
225
226
227/* objRemove -- look up and remove a mapping in an objectTable */
228
229static void objRemove(void **objReturn, objectTable table,
230 void *logObj, size_t size)
231{
232 Bool found;
233 Res ires;
234 void *obj;
235 void *end;
236 void *logEnd;
237
238 found = TableLookup(&obj, table->startTable, (Word)logObj);
239 if (found) {
240 ires = TableRemove(table->startTable, (Word)logObj);
241 verify(ires == ResOK);
242 if (table->endTable != NULL) {
243 ires = TableRemove(table->endTable,
244 (Word)PointerAdd(logObj, size));
245 verify(ires == ResOK);
246 }
247 *objReturn = obj;
248 return;
249 }
250 /* Must be a truncation. */
251 verify(table->endTable != NULL);
252 logEnd = PointerAdd(logObj, size);
253 found = TableLookup(&end, table->endTable, (Word)logEnd);
254 verify(found);
255 obj = PointerSub(end, size);
256 /* Remove the old end and insert the new one. */
257 ires = TableRemove(table->endTable, (Word)logEnd);
258 verify(ires == ResOK);
259 ires = TableDefine(table->endTable, (Word)logObj, obj);
260 verify(ires == ResOK);
261 *objReturn = obj;
262 return;
263}
264
265
266/* poolRecreate -- create and record a pool */
267
268static void poolRecreate(void *logPool, void *logArena, mps_class_t class,
269 poolSupport support, int bufferClassLevel, ...)
270{
271 va_list args;
272 mps_pool_t pool;
273 mps_res_t eres;
274 poolRep rep;
275 Res ires;
276 void *entry;
277 Bool found;
278
279 found = TableLookup(&entry, arenaTable, (Word)logArena);
280 verify(found);
281 va_start(args, bufferClassLevel);
282 eres = mps_pool_create_v(&pool, (mps_arena_t)entry, class, args);
283 verifyMPS(eres);
284 va_end(args);
285 rep = malloc(sizeof(poolRepStruct));
286 verify(rep != NULL);
287 rep->pool = pool;
288 rep->objects = objectTableCreate(support);
289 rep->bufferClassLevel = bufferClassLevel;
290 ires = TableDefine(poolTable, (Word)logPool, (void *)rep);
291 verify(ires == ResOK);
292}
293
294
295/* poolRedestroy -- destroy and derecord a pool */
296
297static void poolRedestroy(void *logPool)
298{
299 Res ires;
300 void *entry;
301 Bool found;
302 poolRep rep;
303
304 found = TableLookup(&entry, poolTable, (Word)logPool);
305 verify(found);
306 rep = (poolRep)entry;
307 mps_pool_destroy(rep->pool);
308 ires = TableRemove(poolTable, (Word)logPool);
309 verify(ires == ResOK);
310 objectTableDestroy(rep->objects);
311 free(rep);
312}
313
314
315/* apRecreate -- create and record an ap */
316
317static void apRecreate(void *logAp, void *logPool, ...)
318{
319 va_list args;
320 mps_ap_t ap;
321 poolRep pRep;
322 apRep aRep;
323 mps_res_t eres;
324 Res ires;
325 void *entry;
326 Bool found;
327
328 found = TableLookup(&entry, poolTable, (Word)logPool);
329 verify(found);
330 pRep = (poolRep)entry;
331 va_start(args, logPool);
332 eres = mps_ap_create_v(&ap, pRep->pool, args);
333 verifyMPS(eres);
334 va_end(args);
335 aRep = malloc(sizeof(apRepStruct));
336 verify(aRep != NULL);
337 aRep->ap = ap;
338 aRep->objects = pRep->objects;
339 ires = TableDefine(apTable, (Word)logAp, (void *)aRep);
340 verify(ires == ResOK);
341}
342
343
344/* apRedestroy -- destroy and derecord an ap */
345
346static void apRedestroy(void *logAp)
347{
348 Res ires;
349 void *entry;
350 Bool found;
351 apRep rep;
352
353 found = TableLookup(&entry, apTable, (Word)logAp);
354 verify(found);
355 rep = (apRep)entry;
356 mps_ap_destroy(rep->ap);
357 ires = TableRemove(apTable, (Word)logAp);
358 verify(ires == ResOK);
359 free(rep);
360}
361
362
363/* EventReplay -- replay event */
364
365static arenaJustCreated = FALSE;
366
367void EventReplay(Event event, Word etime)
368{
369 mps_res_t eres;
370 Res ires;
371 Bool found;
372 void *entry;
373
374 ++totalEvents;
375 eventTime = etime;
376 switch(event->any.code) {
377 case EventArenaCreateVM: { /* arena, userSize, chunkSize */
378 mps_arena_t arena;
379
380 eres = mps_arena_create(&arena, mps_arena_class_vm(),
381 event->pww.w1);
382 verifyMPS(eres);
383 ires = TableDefine(arenaTable, (Word)event->pww.p0, (void *)arena);
384 verify(ires == ResOK);
385 arenaJustCreated = TRUE;
386 } break;
387 case EventArenaCreateVMNZ: { /* arena, userSize, chunkSize */
388 mps_arena_t arena;
389
390 eres = mps_arena_create(&arena, mps_arena_class_vmnz(),
391 event->pww.w1);
392 verifyMPS(eres);
393 ires = TableDefine(arenaTable, (Word)event->pww.p0, (void *)arena);
394 verify(ires == ResOK);
395 arenaJustCreated = TRUE;
396 } break;
397 case EventArenaCreateCL: { /* arena, size, base */
398 mps_arena_t arena;
399 void *base;
400
401 base = malloc((size_t)event->pwa.w1);
402 verify(base != NULL);
403 eres = mps_arena_create(&arena, mps_arena_class_cl(),
404 (Size)event->pwa.w1, base);
405 verifyMPS(eres);
406 ires = TableDefine(arenaTable, (Word)event->pw.p0, (void *)arena);
407 verify(ires == ResOK);
408 arenaJustCreated = TRUE;
409 } break;
410 case EventArenaDestroy: { /* arena */
411 found = TableLookup(&entry, arenaTable, (Word)event->p.p0);
412 verify(found);
413#ifdef MPS_PROD_EPCORE
414 /* @@@@ assuming there's only one arena at a time */
415 finishPSFormat();
416#endif
417 mps_arena_destroy((mps_arena_t)entry);
418 ires = TableRemove(arenaTable, (Word)event->pw.p0);
419 verify(ires == ResOK);
420 } break;
421 case EventPoolInitMVFF: {
422 /* pool, arena, extendBy, avgSize, align, slotHigh, arenaHigh, firstFit */
423 poolRecreate(event->ppwwwuuu.p0, event->ppwwwuuu.p1,
424 mps_class_mvff(), supportFree, 0,
425 (size_t)event->ppwwwuuu.w2,
426 (size_t)event->ppwwwuuu.w3,
427 (size_t)event->ppwwwuuu.w4,
428 (mps_bool_t)event->ppwwwuuu.u5,
429 (mps_bool_t)event->ppwwwuuu.u6,
430 (mps_bool_t)event->ppwwwuuu.u7);
431 } break;
432 case EventPoolInitMV: { /* pool, arena, extendBy, avgSize, maxSize */
433 /* .pool.control: The control pool will get created just after */
434 /* its arena; ignore it. */
435 if (!arenaJustCreated) {
436 poolRecreate(event->ppwww.p0, event->ppwww.p1,
437 mps_class_mv(), supportFree, 0, (size_t)event->ppwww.w2,
438 (size_t)event->ppwww.w3, (size_t)event->ppwww.w4);
439 } else {
440 arenaJustCreated = FALSE;
441 }
442 } break;
443 case EventPoolInitMFS: { /* pool, arena, extendBy, unitSize */
444 /* internal only */
445 ++discardedEvents;
446 } break;
447 case EventPoolInit: { /* pool, arena, class */
448 /* all internal only */
449 ++discardedEvents;
450 } break;
451#ifdef MPS_PROD_EPCORE
452 case EventPoolInitEPVM: {
453 /* pool, arena, format, maxSaveLevel, saveLevel */
454 mps_arena_t arena;
455 mps_fmt_t format;
456
457 found = TableLookup(&entry, arenaTable, (Word)event->pppuu.p1);
458 verify(found);
459 arena = (mps_arena_t)entry;
460 ensurePSFormat(&format, arena); /* We know what the format is. */
461 poolRecreate(event->pppuu.p0, event->pppuu.p1,
462 mps_class_epvm(), supportNothing, 2, format,
463 (mps_epvm_save_level_t)event->pppuu.u3,
464 (mps_epvm_save_level_t)event->pppuu.u4);
465 } break;
466 case EventPoolInitEPDL: {
467 /* pool, arena, isEPDL, extendBy, avgSize, align */
468 poolRecreate(event->ppuwww.p0, event->ppuwww.p1,
469 event->ppuwww.u2 ? mps_class_epdl() : mps_class_epdr(),
470 event->ppuwww.u2 ? supportTruncate : supportFree, 0,
471 (size_t)event->ppuwww.w3, (size_t)event->ppuwww.w4,
472 (size_t)event->ppuwww.w5);
473 } break;
474#endif
475 case EventPoolFinish: { /* pool */
476 found = TableLookup(&entry, poolTable, (Word)event->p.p0);
477 if (found) {
478 poolRedestroy(event->p.p0);
479 } else {
480 ++discardedEvents;
481 }
482 } break;
483 case EventBufferInit: { /* buffer, pool, isMutator */
484 if ((Bool)event->ppu.u2) {
485 found = TableLookup(&entry, poolTable, (Word)event->ppu.p1);
486 if (found) {
487 poolRep rep = (poolRep)entry;
488
489 if(rep->bufferClassLevel == 0) { /* see .bufclass */
490 apRecreate(event->ppu.p0, event->ppu.p1);
491 } else {
492 ++discardedEvents;
493 }
494 } else {
495 ++discardedEvents;
496 }
497 } else {
498 ++discardedEvents;
499 }
500 } break;
501 case EventBufferInitSeg: { /* buffer, pool, isMutator */
502 if ((Bool)event->ppu.u2) {
503 found = TableLookup(&entry, poolTable, (Word)event->ppu.p1);
504 if (found) {
505 poolRep rep = (poolRep)entry;
506
507 if(rep->bufferClassLevel == 1) { /* see .bufclass */
508 apRecreate(event->ppu.p0, event->ppu.p1);
509 } else {
510 ++discardedEvents;
511 }
512 } else {
513 ++discardedEvents;
514 }
515 } else {
516 ++discardedEvents;
517 }
518 } break;
519 case EventBufferInitRank: { /* buffer, pool, isMutator, rank */
520 if ((Bool)event->ppuu.u2) {
521 found = TableLookup(&entry, poolTable, (Word)event->ppuu.p1);
522 if (found) {
523 poolRep rep = (poolRep)entry;
524
525 if(rep->bufferClassLevel == 2) { /* see .bufclass */
526 apRecreate(event->ppuu.p0, event->ppuu.p1, event->ppuu.u3);
527 } else {
528 ++discardedEvents;
529 }
530 } else {
531 ++discardedEvents;
532 }
533 } else {
534 ++discardedEvents;
535 }
536 } break;
537#ifdef MPS_PROD_EPCORE
538 case EventBufferInitEPVM: { /* buffer, pool, isObj */
539 found = TableLookup(&entry, poolTable, (Word)event->ppu.p1);
540 if (found) {
541 poolRep rep = (poolRep)entry;
542
543 if(rep->bufferClassLevel == 2) { /* see .bufclass */
544 apRecreate(event->ppu.p0, event->ppu.p1, (mps_bool_t)event->ppu.u2);
545 } else {
546 ++discardedEvents;
547 }
548 } else {
549 ++discardedEvents;
550 }
551 } break;
552#endif
553 case EventBufferFinish: { /* buffer */
554 found = TableLookup(&entry, apTable, (Word)event->p.p0);
555 if (found) {
556 apRedestroy(event->p.p0);
557 } else {
558 ++discardedEvents;
559 }
560 } break;
561 case EventBufferReserve: { /* buffer, init, size */
562 found = TableLookup(&entry, apTable, (Word)event->paw.p0);
563 if (found) {
564 apRep rep = (apRep)entry;
565 mps_addr_t p;
566
567 eres = mps_reserve(&p, rep->ap, (size_t)event->paw.w2);
568 verifyMPS(eres);
569 } else {
570 ++discardedEvents;
571 }
572 } break;
573 case EventBufferCommit: { /* buffer, p, size, clientClass */
574 found = TableLookup(&entry, apTable, (Word)event->pawa.p0);
575 if (found) {
576 apRep rep = (apRep)entry;
577 mps_addr_t obj = rep->ap->init;
578 mps_bool_t committed;
579 size_t size = (size_t)event->pawa.w2;
580
581 committed = mps_commit(rep->ap, obj, size);
582 verifyMPS(committed ? MPS_RES_OK : MPS_RES_FAIL);
583 objDefine(rep->objects, event->pawa.a1, obj, size);
584 } else {
585 ++discardedEvents;
586 }
587 } break;
588 case EventPoolAlloc: { /* pool, obj, size */
589 found = TableLookup(&entry, poolTable, (Word)event->paw.p0);
590 if (found) {
591 poolRep rep = (poolRep)entry;
592 void *obj;
593 size_t size = (size_t)event->paw.w2;
594
595 eres = mps_alloc(&obj, rep->pool, size);
596 verifyMPS(eres);
597 objDefine(rep->objects, event->paw.a1, obj, size);
598 } else {
599 ++discardedEvents;
600 }
601 } break;
602 case EventPoolFree: { /* pool, obj, size */
603 found = TableLookup(&entry, poolTable, (Word)event->paw.p0);
604 if (found) {
605 poolRep rep = (poolRep)entry;
606 void *obj;
607 size_t size = (size_t)event->paw.w2;
608
609 objRemove(&obj, rep->objects, event->paw.a1, size);
610 mps_free(rep->pool, obj, size);
611 } else {
612 ++discardedEvents;
613 }
614 } break;
615#ifdef MPS_PROD_EPCORE
616 case EventPoolPush: { /* pool */
617 found = TableLookup(&entry, poolTable, (Word)event->p.p0);
618 if (found) {
619 poolRep rep = (poolRep)entry;
620
621 /* It must be EPVM. */
622 mps_epvm_save(rep->pool);
623 }
624 } break;
625 case EventPoolPop: { /* pool, level */
626 found = TableLookup(&entry, poolTable, (Word)event->pu.p0);
627 if (found) {
628 poolRep rep = (poolRep)entry;
629
630 /* It must be EPVM. */
631 mps_epvm_restore(rep->pool, (mps_epvm_save_level_t)event->pu.u1);
632 }
633 } break;
634#endif
635 case EventCommitLimitSet: { /* arena, limit, succeeded */
636 found = TableLookup(&entry, arenaTable, (Word)event->pwu.p0);
637 verify(found);
638 eres = mps_arena_commit_limit_set((mps_arena_t)entry,
639 (size_t)event->pwu.w1);
640 verifyMPS(((Bool)event->pwu.u2 == (eres == MPS_RES_OK))
641 ? MPS_RES_OK : MPS_RES_FAIL);
642 } break;
643 case EventSpareCommitLimitSet: { /* arena, limit */
644 found = TableLookup(&entry, arenaTable, (Word)event->pw.p0);
645 verify(found);
646 (void)mps_arena_spare_commit_limit_set((mps_arena_t)entry,
647 (size_t)event->pw.w1);
648 } break;
649 case EventReservoirLimitSet: { /* arena, limit */
650 found = TableLookup(&entry, arenaTable, (Word)event->pw.p0);
651 verify(found);
652 mps_reservoir_limit_set((mps_arena_t)entry, (size_t)event->pw.w1);
653 } break;
654 case EventVMMap: case EventVMUnmap:
655 case EventVMCreate: case EventVMDestroy:
656 case EventArenaWriteFaults:
657 case EventArenaAlloc: case EventArenaAllocFail: case EventArenaFree:
658 case EventSegAlloc: case EventSegAllocFail: case EventSegFree:
659 case EventSegMerge: case EventSegSplit:
660 case EventBufferFill: case EventBufferEmpty:
661 case EventCBSInit: case EventMeterInit: case EventMeterValues:
662 case EventIntern: case EventLabel: {
663 ++discardedEvents;
664 } break;
665 default: {
666 ++unknownEvents;
667 if (unknownEvents < 12) /* don't output too much */
668 printf("Unknown event @%ld: %s.\n", etime,
669 EventCode2Name(EventGetCode(event)));
670 } break;
671 }
672}
673
674
675/* Checking macros, copied from check.h */
676
677#define CHECKLVALUE(lv1, lv2) \
678 ((void)sizeof((lv1) = (lv2)), (void)sizeof((lv2) = (lv1)), TRUE)
679
680#define CHECKTYPE(t1, t2) \
681 (sizeof(t1) == sizeof(t2) && \
682 CHECKLVALUE(*((t1 *)0), *((t2 *)0)))
683
684
685/* CHECKCONV -- check t2 can be cast to t1 without loss */
686
687#define CHECKCONV(t1, t2) \
688 (sizeof(t1) >= sizeof(t2))
689
690
691/* EventRepInit -- initialize the module */
692
693Res EventRepInit(Bool partial)
694{
695 Res res;
696
697 /* Check using pointers as keys in the tables. */
698 verify(CHECKCONV(Word, void *));
699 /* Check storage of MPS opaque handles in the tables. */
700 verify(CHECKTYPE(mps_arena_t, void *));
701 verify(CHECKTYPE(mps_ap_t, void *));
702 /* .event-conv: Conversion of event fields into the types required */
703 /* by the MPS functions is justified by the reverse conversion */
704 /* being acceptable (which is upto the event log generator). */
705
706 partialLog = partial;
707 totalEvents = 0; discardedEvents = 0; unknownEvents = 0;
708
709 res = TableCreate(&arenaTable, (size_t)1);
710 if (res != ResOK) goto failArena;
711 res = TableCreate(&poolTable, (size_t)1<<4);
712 if (res != ResOK) goto failPool;
713 res = TableCreate(&apTable, (size_t)1<<6);
714 if (res != ResOK) goto failAp;
715
716 return ResOK;
717
718failAp:
719 TableDestroy(poolTable);
720failPool:
721 TableDestroy(arenaTable);
722failArena:
723 return res;
724}
725
726
727/* EventRepFinish -- finish the module */
728
729void EventRepFinish(void)
730{
731 /* @@@@ add listing of remaining objects? */
732 /* No point in cleaning up the tables, since we're quitting. */
733 printf("Replayed %lu and discarded %lu events (%lu unknown).\n",
734 totalEvents - discardedEvents - unknownEvents,
735 discardedEvents + unknownEvents, unknownEvents);
736}