diff --git a/mps/src/event.c b/mps/src/event.c index e69de29bb2d..83f556e6a0c 100644 --- a/mps/src/event.c +++ b/mps/src/event.c @@ -0,0 +1,139 @@ +/* impl.c.event: EVENT LOGGING + * + * $HopeName: MMsrc!event.c(MMdevel_event.6) $ + * Copyright (C) 1996 Harlequin Group, all rights reserved. + * + * .readership: MPS developers. + * .sources: mps.design.event + * + * TRANSGRESSIONS (rule.impl.trans) + * + * .trans.ref: The reference counting used to destroy the mps_io object + * isn't right. + * + * .trans.log: The log file will be re-created if the lifetimes of + * spaces don't overlap, but shared if they do. mps_io_create cannot + * be called twice, but EventInit avoids this anyway. + * + * .trans.ifdef: This file should logically be split into two, event.c + * (which contains NOOP definitions, for general use) and eventdl.c, which + * is specific to the logging variety and actually does logging (maybe). + * Unfortunately, the build system doesn't really cope, and so this file + * consists of two versions which are conditional on the EVENT symbol. + */ + +#include "mpm.h" +#include "event.h" +#include "mpsio.h" + +SRCID(event, "$HopeName: MMsrc!event.c(MMdevel_event.6) $"); + +#ifdef EVENT /* .trans.ifdef */ + +static Bool eventInited = FALSE; +static mps_io_t eventIO; +static Word eventBuffer[EVENT_BUFFER_SIZE]; +static Count eventUserCount; + +Word *EventNext, *EventLimit; /* Used by macros in impl.h.event */ + +static Res EventFlush(void) +{ + Res res; + + AVER(eventInited); + + res = (Res)mps_io_write(eventIO, + (void *)eventBuffer, + (char *)EventNext - (char *)eventBuffer); + if(res != ResOK) return res; + + EventNext = eventBuffer; + + return ResOK; +} + +Res (EventInit)(void) +{ + Res res; + + /* Initialize the event system if this is the first call. */ + if(!eventInited) { /* See .trans.log */ + AVER(EventNext == 0); + AVER(EventLimit == 0); + res = (Res)mps_io_create(&eventIO); + if(res != ResOK) return res; + EventNext = eventBuffer; + EventLimit = &eventBuffer[EVENT_BUFFER_SIZE]; + eventUserCount = 0; + eventInited = TRUE; + } + + ++eventUserCount; + + return ResOK; +} + +void (EventFinish)(void) +{ + AVER(eventInited); + AVER(eventUserCount > 0); + + (void)EventFlush(); + (void)mps_io_flush(eventIO); + + --eventUserCount; +} + +Res EventEnter(EventType type, Count length, ...) +{ + Res res; + va_list args; + Word *alloc; + Count i=0, size; + + AVER(eventInited); + + size = length + EVENT_HEADER_SIZE; /* Include header. */ + + AVER(size < EVENT_BUFFER_SIZE); /* Events must fit in buffer. */ + + alloc = EventNext + size; + + if(alloc > EventLimit) { + res = EventFlush(); + if(res != ResOK) return res; + alloc = EventNext + size; + } + + AVER(alloc <= EventLimit); + + EventNext[i++] = type; + EventNext[i++] = length; + EventNext[i++] = (Word)mps_clock(); + + AVER(i == EVENT_HEADER_SIZE); + + va_start(args, length); + for(; i < size; ++i) + EventNext[i] = va_arg(args, Word); + + va_end(args); + EventNext = alloc; + + return ResOK; +} + +#else /* EVENT, not */ + +Res (EventInit)(void) +{ + return(ResOK); +} + +void (EventFinish)(void) +{ + NOOP; +} + +#endif /* EVENT */ diff --git a/mps/src/event.h b/mps/src/event.h index e69de29bb2d..3705c5b135f 100644 --- a/mps/src/event.h +++ b/mps/src/event.h @@ -0,0 +1,128 @@ +/* impl.h.event -- Event Logging Interface + * + * Copyright (C) 1996 Harlequin Group, all rights reserved. + * $HopeName: MMsrc!event.h(MMdevel_event.3) $ + * + * .readership: MPS developers. + * .sources: mps.design.event + */ + +#ifndef event_h +#define event_h + +#include "mpm.h" + +extern Res EventEnter(EventType type, Size length, ...); +extern Res EventInit(void); +extern void EventFinish(void); + +#ifdef EVENT + +extern Word *EventNext, *EventLimit; + +#ifdef EVENT_INLINE + +#error "Inline event logging is untested -- GavinM 1997-04-07" + +#define EVENT_BEGIN(type, length) \ + BEGIN \ + Count _length = (length); \ + Count _i = 0; \ + Word *_alloc = EventNext + _length + EVENT_HEADER_SIZE; \ + if(_alloc <= EventLimit) { \ + EventNext[_i++] = (type); \ + EventNext[_i++] = _length; \ + EventNext[_i++] = (Word)mps_clock(); \ + AVER(_i == EVENT_HEADER_SIZE); + +#define EVENT_END(params) \ + AVER(_i == _length + EVENT_HEADER_SIZE); \ + EventNext = _alloc; \ + } else \ + EventEnter params; \ + END + +#define EVENT0(type) \ + EVENT_BEGIN(Event ## type, 0) \ + EVENT_END((Event ## type, 0)) + +#define EVENT1(type, p0) \ + EVENT_BEGIN(Event ## type, 1) \ + EventNext[_i++] = (Word)(p0); \ + EVENT_END((Event ## type, 1, \ + (Word)p0)) + +#define EVENT2(type, p0, p1) \ + EVENT_BEGIN(Event ## type, 2) \ + EventNext[_i++] = (Word)(p0); \ + EventNext[_i++] = (Word)(p1); \ + EVENT_END((Event ## type, 2, \ + (Word)p0, (Word)p1)) + +#define EVENT3(type, p0, p1, p2) \ + EVENT_BEGIN(Event ## type, 3) \ + EventNext[_i++] = (Word)(p0); \ + EventNext[_i++] = (Word)(p1); \ + EventNext[_i++] = (Word)(p2); \ + EVENT_END((Event ## type, 3, \ + (Word)p0, (Word)p1, (Word)p2)) + +#define EVENT4(type, p0, p1, p2, p3) \ + EVENT_BEGIN(Event ## type, 4) \ + EventNext[_i++] = (Word)(p0); \ + EventNext[_i++] = (Word)(p1); \ + EventNext[_i++] = (Word)(p2); \ + EventNext[_i++] = (Word)(p3); \ + EVENT_END((Event ## type, 4, \ + (Word)p0, (Word)p1, (Word)p2, (Word)p3)) + +#define EVENT5(type, p0, p1, p2, p3, p4) \ + EVENT_BEGIN(Event ## type, 5) \ + EventNext[_i++] = (Word)(p0); \ + EventNext[_i++] = (Word)(p1); \ + EventNext[_i++] = (Word)(p2); \ + EventNext[_i++] = (Word)(p3); \ + EventNext[_i++] = (Word)(p4); \ + EVENT_END((Event ## type, 5, \ + (Word)p0, (Word)p1, (Word)p2, (Word)p3, (Word)p4)) + +#else /* EVENT_INLINE not */ + +#define EVENT0(type) \ + EventEnter(Event ## type, 0) + +#define EVENT1(type, p0) \ + EventEnter(Event ## type, 1, (Word)p0) + +#define EVENT2(type, p0, p1) \ + EventEnter(Event ## type, 2, (Word)p0, (Word)p1) + +#define EVENT3(type, p0, p1, p2) \ + EventEnter(Event ## type, 3, \ + (Word)p0, (Word)p1, (Word)p2) + +#define EVENT4(type, p0, p1, p2, p3) \ + EventEnter(Event ## type, 4, \ + (Word)p0, (Word)p1, (Word)p2, (Word)p3) + +#define EVENT5(type, p0, p1, p2, p3, p4) \ + EventEnter(Event ## type, 5, \ + (Word)p0, (Word)p1, (Word)p2, (Word)p3, (Word)p4) + +#endif /* EVENT_INLINE */ + +#else /* EVENT not */ + +#define EVENT0(type) NOOP +#define EVENT1(type, p0) NOOP +#define EVENT2(type, p0, p1) NOOP +#define EVENT3(type, p0, p1, p2) NOOP +#define EVENT4(type, p0, p1, p2, p3) NOOP +#define EVENT5(type, p0, p1, p2, p3, p4) NOOP + +#define EventInit() NOOP +#define EventFinish() NOOP + +#endif /* EVENT */ + +#endif /* event_h */ diff --git a/mps/src/mpsio.h b/mps/src/mpsio.h index e69de29bb2d..977986cf923 100644 --- a/mps/src/mpsio.h +++ b/mps/src/mpsio.h @@ -0,0 +1,27 @@ +/* impl.h.mpsio: HARLEQUIN MEMORY POOL SYSTEM I/O INTERFACE + * + * $HopeName: MMsrc!mpsio.h(MMdevel_event.2) $ + * Copyright (C) 1996 Harlequin Group, all rights reserved. + * + * .readership: MPS client application developers, MPS developers. + * .sources: design.mps.io + * + * TRANSGRESSIONS (rule.impl.trans) + * + * There's no way this meets all the reqiurements yet. + */ + +#ifndef mpsio_h +#define mpsio_h + +#include "mps.h" /* for mps_res_t */ + +typedef struct mps_io_s *mps_io_t; + +extern mps_res_t mps_io_create(mps_io_t *mps_io_r); +extern void mps_io_destroy(mps_io_t mps_io); + +extern mps_res_t mps_io_write(mps_io_t mps_io, void *mps_buf, size_t mps_size); +extern mps_res_t mps_io_flush(mps_io_t mps_io); + +#endif /* mpsio_h */ diff --git a/mps/src/mpsioan.c b/mps/src/mpsioan.c index e69de29bb2d..d44ada0501b 100644 --- a/mps/src/mpsioan.c +++ b/mps/src/mpsioan.c @@ -0,0 +1,68 @@ +/* impl.c.mpsioan: HARLEQUIN MEMORY POOL SYSTEM I/O IMPLEMENTATION (ANSI) + * + * $HopeName: MMsrc!mpsioan.c(MMdevel_event.4) $ + * Copyright (C) 1996 Harlequin Group, all rights reserved. + * + * .readership: MPS developers. + * + * TRANSGRESSIONS (rule.impl.trans) + * + * There's no way this meets all the reqiurements yet. + */ + +#include "mpsio.h" +#include + +#include "mpstd.h" /* .sunos.warn */ +#ifdef MPS_OS_SU +#include "ossu.h" +#endif + +static FILE *ioFile = NULL; + +mps_res_t mps_io_create(mps_io_t *mps_io_r) +{ + FILE *f; + + if(ioFile != NULL) /* See impl.c.event.trans.log */ + return MPS_RES_LIMIT; /* Cannot currently open more than one log */ + + f = fopen("mpsio.log", "wb"); + if(f == NULL) + return MPS_RES_IO; + + *mps_io_r = (mps_io_t)f; + ioFile = f; + return MPS_RES_OK; +} + +void mps_io_destroy(mps_io_t mps_io) +{ + FILE *f = (FILE *)mps_io; + ioFile = NULL; /* Should check f == ioFile */ + (void)fclose(f); +} + +mps_res_t mps_io_write(mps_io_t mps_io, void *mps_buf, size_t mps_size) +{ + FILE *f = (FILE *)mps_io; /* Should check f == ioFile */ + size_t n; + + n = fwrite(mps_buf, mps_size, 1, f); + if(n != 1) + return MPS_RES_IO; + + return MPS_RES_OK; +} + +mps_res_t mps_io_flush(mps_io_t mps_io) +{ + FILE *f = (FILE *)mps_io; /* Should check f == ioFile */ + int e; + + e = fflush(f); + if(e == EOF) + return MPS_RES_IO; + + return MPS_RES_OK; +}