static void fillGlueTables(sqlite3 *db) { int i; sqlite3_stmt *statement; int res; statement = prepareStatement(db, "INSERT OR IGNORE INTO event_kind (name, description, enum)" "VALUES (?, ?, ?)"); i = 0; EventKindENUM(EVENT_KIND_DO_INSERT, X); finalizeStatement(db, statement); statement = prepareStatement(db, "INSERT OR IGNORE INTO event_type (name, code, always, kind)" "VALUES (?, ?, ?, ?)"); EVENT_LIST(EVENT_TYPE_DO_INSERT, X); finalizeStatement(db, statement); statement = prepareStatement(db, "INSERT OR IGNORE INTO event_param (type, param_index, sort, ident)" "VALUES (?, ?, ?, ?)"); EVENT_LIST(EVENT_TYPE_INSERT_PARAMS, X); finalizeStatement(db, statement); }
static void readLog(FILE *input) { int i; for (i=0; i <= EventCodeMAX; ++i) eventName[i] = NULL; EVENT_LIST(EVENT_SET_NAME, X); while (TRUE) { /* loop for each event */ char line[MAX_LOG_LINE_LENGTH]; char *p, *q; ulongest_t clock; int code; ulongest_t val_hex; double val_float; const char *val_string; p = fgets(line, MAX_LOG_LINE_LENGTH, input); if (!p) { if (feof(input)) break; else everror("Couldn't read line from input."); } clock = parseHex(&p); code = (int)parseHex(&p); if (eventName[code]) printf("%0*" PRIXLONGEST " %04X %-19s ", hexWordWidth, clock, code, eventName[code]); else printf("%0*" PRIXLONGEST " %04X %-19s ", hexWordWidth, clock, code, "[Unknown]"); q = p; /* for a few particular codes, we do local processing. */ if (code == EventInternCode) { recordIntern(q); } else if (code == EventLabelCode) { recordLabel(q); } else if (code == EventEventInitCode) { ulongest_t major, median, minor, maxCode, maxNameLen, wordWidth, clocksPerSec; major = parseHex(&q); /* EVENT_VERSION_MAJOR */ median = parseHex(&q); /* EVENT_VERSION_MEDIAN */ minor = parseHex(&q); /* EVENT_VERSION_MINOR */ maxCode = parseHex(&q); /* EventCodeMAX */ maxNameLen = parseHex(&q); /* EventNameMAX */ wordWidth = parseHex(&q); /* MPS_WORD_WIDTH */ clocksPerSec = parseHex(&q); /* mps_clocks_per_sec() */ UNUSED(clocksPerSec); UNUSED(maxNameLen); if ((major != EVENT_VERSION_MAJOR) || (median != EVENT_VERSION_MEDIAN) || (minor != EVENT_VERSION_MINOR)) { fprintf(stderr, "Event log version does not match: %d.%d.%d vs %d.%d.%d\n", (int)major, (int)median, (int)minor, EVENT_VERSION_MAJOR, EVENT_VERSION_MEDIAN, EVENT_VERSION_MINOR); } if (maxCode > EventCodeMAX) { fprintf(stderr, "Event log may contain unknown events with codes from %d to %d\n", EventCodeMAX+1, (int)maxCode); } if (wordWidth > MPS_WORD_WIDTH) { int newHexWordWidth = (int)((wordWidth + 3) / 4); if (newHexWordWidth > hexWordWidth) { fprintf(stderr, "Event log word width is greater than on current platform;" "previous values may be printed too narrowly.\n"); } hexWordWidth = newHexWordWidth; } if (wordWidth > sizeof(ulongest_t) * CHAR_BIT) { everror("Event log word width %d is too wide for the current platform.", (int)wordWidth); } } switch(code) { EVENT_LIST(EVENT_PROCESS, X); default: printf("Unknown event."); } putchar('\n'); } }
void EventInit(void) { /* Make local enums for all event params in order to check that the indexes in the parameter definition macros are in order, and that parameter idents are unique. */ #define EVENT_CHECK_ENUM_PARAM(name, index, sort, ident) \ Event##name##Param##ident, #define EVENT_CHECK_ENUM(X, name, code, always, kind) \ enum Event##name##ParamEnum { \ EVENT_##name##_PARAMS(EVENT_CHECK_ENUM_PARAM, name) \ Event##name##ParamLIMIT \ }; EVENT_LIST(EVENT_CHECK_ENUM, X) /* Check consistency of the event definitions. These are all compile-time checks and should get optimised away. */ #define EVENT_PARAM_CHECK_P(name, index, ident) #define EVENT_PARAM_CHECK_A(name, index, ident) #define EVENT_PARAM_CHECK_W(name, index, ident) #define EVENT_PARAM_CHECK_U(name, index, ident) #define EVENT_PARAM_CHECK_D(name, index, ident) #define EVENT_PARAM_CHECK_B(name, index, ident) #define EVENT_PARAM_CHECK_S(name, index, ident) \ AVER(index + 1 == Event##name##ParamLIMIT); /* strings must come last */ #define EVENT_PARAM_CHECK(name, index, sort, ident) \ AVER(index == Event##name##Param##ident); \ AVER(sizeof(EventF##sort) >= 0); /* check existence of type */ \ EVENT_PARAM_CHECK_##sort(name, index, ident) #define EVENT_CHECK(X, name, code, always, kind) \ AVER(size_tAlignUp(sizeof(Event##name##Struct), MPS_PF_ALIGN) \ <= EventSizeMAX); \ AVER(Event##name##Code == code); \ AVER(0 <= code && code <= EventCodeMAX); \ AVER(sizeof(#name) - 1 <= EventNameMAX); \ AVER((Bool)Event##name##Always == always); \ AVERT(Bool, always); \ AVER(0 <= Event##name##Kind); \ AVER((EventKind)Event##name##Kind < EventKindLIMIT); \ EVENT_##name##_PARAMS(EVENT_PARAM_CHECK, name) EVENT_LIST(EVENT_CHECK, X) /* Ensure that no event can be larger than the maximum event size. */ AVER(EventBufferSIZE <= EventSizeMAX); /* Only if this is the first call. */ if(!eventInited) { /* See .trans.log */ EventKind kind; for (kind = 0; kind < EventKindLIMIT; ++kind) { AVER(EventLast[kind] == NULL); EventLast[kind] = EventBuffer[kind] + EventBufferSIZE; } eventUserCount = (Count)1; eventInited = TRUE; EventKindControl = (Word)mps_lib_telemetry_control(); EventInternSerial = (Serial)1; /* 0 is reserved */ (void)EventInternString(MPSVersion()); /* emit version */ } else { ++eventUserCount; } }
static int64 readLog(FILE *input, sqlite3 *db) { int64 eventCount = 0; /* declare statements for every event type */ EVENT_LIST(EVENT_TYPE_DECLARE_STATEMENT, X); /* prepare statements for every event type */ EVENT_LIST(EVENT_TYPE_PREPARE_STATEMENT, X); runStatement(db, "BEGIN", "Transaction start"); while (TRUE) { /* loop for each event */ char line[MAX_LOG_LINE_LENGTH]; char *p; char *q; int last_index=0; sqlite3_stmt *statement = NULL; int res; int64 clock_field; long code; p = fgets(line, MAX_LOG_LINE_LENGTH, input); if (!p) { if (feof(input)) break; else error("Couldn't read line after event %llu", eventCount); } eventCount++; clock_field = strtoll(p, &q, 16); if (q == p) error("event %llu clock field not a hex integer: %s", eventCount, p); if (*q != ' ') error("event %llu code field not preceded by ' ': %s", eventCount, q); while(*q == ' ') ++q; p = q; code = strtol(p, &q, 16); if (q == p) error("event %llu code field not an integer: %s", eventCount, p); p = q; /* Write event to SQLite. */ switch (code) { /* this macro sets statement and last_index */ EVENT_LIST(EVENT_TYPE_WRITE_SQL, X); default: error("Event %llu has Unknown event code %d", eventCount, code); } /* bind the fields we store for every event */ \ res = sqlite3_bind_int64(statement, last_index+1, logSerial); if (res != SQLITE_OK) sqlite_error(res, db, "Event %llu bind of log_serial failed.", eventCount); res = sqlite3_bind_int64(statement, last_index+2, clock_field); if (res != SQLITE_OK) sqlite_error(res, db, "Event %llu bind of clock failed.", eventCount); res = sqlite3_step(statement); if (res != SQLITE_DONE) sqlite_error(res, db, "insert of event %llu failed.", eventCount); res = sqlite3_reset(statement); if (res != SQLITE_OK) sqlite_error(res, db, "Couldn't reset insert statement of event %llu", eventCount); if (progress) { if ((eventCount % SMALL_TICK) == 0) { printf("."); fflush(stdout); if (((eventCount / SMALL_TICK) % BIG_TICK) == 0) { printf("\n"); fflush(stdout); evlog(LOG_SOMETIMES, "%lu events.", (unsigned long)eventCount); } } } } if (progress) { printf("\n"); fflush(stdout); } runStatement(db, "COMMIT", "Transaction finish"); logFileCompleted(db, eventCount); /* finalize all the statements */ EVENT_LIST(EVENT_TYPE_FINALIZE_STATEMENT, X); return eventCount; }
" kind INTEGER," " FOREIGN KEY (kind) REFERENCES event_kind(enum));", "CREATE TABLE IF NOT EXISTS event_param (type INTEGER," " param_index INTEGER," " sort TEXT," " ident TEXT," " FOREIGN KEY (type) REFERENCES event_type(code));", "CREATE TABLE IF NOT EXISTS event_log (name TEXT," " size INTEGER," " modtime INTEGER," " completed INTEGER," " serial INTEGER PRIMARY KEY AUTOINCREMENT)", EVENT_LIST(EVENT_TABLE_CREATE, X) }; /* makeTables makes all the tables. */ static void makeTables(sqlite3 *db) { size_t i; evlog(LOG_SOMETIMES, "Creating tables."); for (i=0; i < (sizeof(createStatements)/sizeof(createStatements[0])); ++i) { runStatement(db, createStatements[i], "Table creation"); } } const char *glueTables[] = {