From bda5ad2ec9fa333c8200451496d6c251abbeee19 Mon Sep 17 00:00:00 2001 From: Paul Oliver Date: Sat, 21 Mar 2026 01:36:24 +0100 Subject: Adds data server (WIP) --- core.c | 274 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 271 insertions(+), 3 deletions(-) (limited to 'core.c') diff --git a/core.c b/core.c index a4b57d8..79fc6f2 100644 --- a/core.c +++ b/core.c @@ -39,6 +39,20 @@ struct Core { uint64_t *ivav; uint8_t *iviv; +#if defined(DATA_PUSH_PATH) + uint64_t emb0; // executions within mb0 counter + uint64_t emb1; // executions within mb1 counter + uint64_t eliv; // executions within not-owned live code counter (parasites) + uint64_t edea; // executions within dead code counter + + uint64_t aeva[MVEC_SIZE]; // allocation events array + //uint64_t eeva[MVEC_SIZE]; // execution events array + +#define CORE_DATA_FIELD(type, name, suff) type name suff; + CORE_DATA_FIELDS +#undef CORE_FIELD +#endif + #define CORE_FIELD(type, name, suff) type name suff; CORE_FIELDS #undef CORE_FIELD @@ -99,7 +113,9 @@ wchar_t arch_symbol(uint8_t inst); const char *arch_mnemonic(uint8_t inst); #if defined(DATA_PUSH_PATH) +#if defined(COMMAND_NEW) void arch_push_data_header(); +#endif void arch_push_data_line(); #endif @@ -132,9 +148,17 @@ void mvec_alloc(struct Core *core, uint64_t addr) { #if defined(MVEC_LOOP) core->mvec[mvec_loop(addr)] |= MALL_FLAG; +#if defined(DATA_PUSH_PATH) + // Record deallocation event + ++core->aeva[mvec_loop(addr)]; +#endif #else assert(addr < MVEC_SIZE); core->mvec[addr] |= MALL_FLAG; +#if defined(DATA_PUSH_PATH) + // Record deallocation event + ++core->aeva[addr]; +#endif #endif core->mall++; } @@ -145,9 +169,17 @@ void mvec_free(struct Core *core, uint64_t addr) { #if defined(MVEC_LOOP) core->mvec[mvec_loop(addr)] ^= MALL_FLAG; +#if defined(DATA_PUSH_PATH) + // Record deallocation event + ++core->aeva[mvec_loop(addr)]; +#endif #else assert(addr < MVEC_SIZE); core->mvec[addr] ^= MALL_FLAG; +#if defined(DATA_PUSH_PATH) + // Record deallocation event + ++core->aeva[addr]; +#endif #endif core->mall--; } @@ -373,11 +405,21 @@ void core_save(FILE *f, const struct Core *core) { fwrite(&core->pcur, sizeof(uint64_t), 1, f); fwrite(&core->psli, sizeof(uint64_t), 1, f); fwrite(&core->ivpt, sizeof(uint64_t), 1, f); +#if defined(DATA_PUSH_PATH) + fwrite(&core->emb0, sizeof(uint64_t), 1, f); + fwrite(&core->emb1, sizeof(uint64_t), 1, f); + fwrite(&core->eliv, sizeof(uint64_t), 1, f); + fwrite(&core->edea, sizeof(uint64_t), 1, f); +#endif fwrite(core->iviv, sizeof(uint8_t), SYNC_INTERVAL, f); fwrite(core->ivav, sizeof(uint64_t), SYNC_INTERVAL, f); fwrite(core->pvec, sizeof(struct Proc), core->pcap, f); fwrite(core->mvec, sizeof(uint8_t), MVEC_SIZE, f); +#if defined(DATA_PUSH_PATH) + fwrite(core->aeva, sizeof(uint64_t), MVEC_SIZE, f); + //fwrite(core->eeva, sizeof(uint64_t), MVEC_SIZE, f); +#endif arch_core_save(f, core); } @@ -451,6 +493,12 @@ void core_load(FILE *f, struct Core *core) { fread(&core->pcur, sizeof(uint64_t), 1, f); fread(&core->psli, sizeof(uint64_t), 1, f); fread(&core->ivpt, sizeof(uint64_t), 1, f); +#if defined(DATA_PUSH_PATH) + fread(&core->emb0, sizeof(uint64_t), 1, f); + fread(&core->emb1, sizeof(uint64_t), 1, f); + fread(&core->eliv, sizeof(uint64_t), 1, f); + fread(&core->edea, sizeof(uint64_t), 1, f); +#endif core->iviv = calloc(SYNC_INTERVAL, sizeof(uint8_t)); core->ivav = calloc(SYNC_INTERVAL, sizeof(uint64_t)); @@ -464,6 +512,10 @@ void core_load(FILE *f, struct Core *core) { fread(core->ivav, sizeof(uint64_t), SYNC_INTERVAL, f); fread(core->pvec, sizeof(struct Proc), core->pcap, f); fread(core->mvec, sizeof(uint8_t), MVEC_SIZE, f); +#if defined(DATA_PUSH_PATH) + fread(core->aeva, sizeof(uint64_t), MVEC_SIZE, f); + //fread(core->eeva, sizeof(uint64_t), MVEC_SIZE, f); +#endif arch_core_load(f, core); } @@ -507,6 +559,24 @@ void core_step(struct Core *core) { if (core->psli != 0) { core_pull_ipcm(core); + +#if defined(DATA_PUSH_PATH) + // Save execution event locations in database + assert(mvec_proc_is_live(core, core->pcur)); + + struct Proc *proc = proc_fetch(core, core->pcur); + + if (mvec_is_in_mb0_of_proc(core, proc->ip, core->pcur)) { + ++core->emb0; + } else if (mvec_is_in_mb1_of_proc(core, proc->ip, core->pcur)) { + ++core->emb1; + } else if (mvec_is_alloc(core, proc->ip)) { + ++core->eliv; + } else { + ++core->edea; + } +#endif + arch_proc_step(core, core->pcur); core->psli--; @@ -664,6 +734,203 @@ void salis_exec_sql(int blob_cnt, const void **blobs, const int *blob_sizes, con } #endif +#if defined(DATA_PUSH_PATH) +#if defined(COMMAND_NEW) +void salis_push_data_header() { + assert(g_sim_data); + + g_info("Creating 'general' table in SQLite database"); + salis_exec_sql( + 0, NULL, NULL, + "create table general (" +#define FOR_CORE(i) \ + "cycl_" #i " int not null, " \ + "mall_" #i " int not null, " \ + "pnum_" #i " int not null, " \ + "pfst_" #i " int not null, " \ + "plst_" #i " int not null, " \ + "amb0_" #i " real not null, " \ + "amb1_" #i " real not null, " \ + "emb0_" #i " int not null, " \ + "emb1_" #i " int not null, " \ + "eliv_" #i " int not null, " \ + "edea_" #i " int not null, " + FOR_CORES +#undef FOR_CORE + "step int not null" + ");" + ); + + // Memory events + char *eprefs[] = { "aev" /*, "eev" */ }; + int eprefs_cnt = sizeof(eprefs) / sizeof(eprefs[0]); + + for (int i = 0; i < CORES; ++i) { + for (int j = 0; j < eprefs_cnt; ++j) { + g_info("Creating '%s_%d' table in SQLite database", eprefs[j], i); + salis_exec_sql( + 0, NULL, NULL, + "create table %s_%d (" +#define FOR_CORE(i) "cycl_" #i " int not null, " + FOR_CORES +#undef FOR_CORE + "size int not null, " + "evts blob not null ," + "step int not null" + ");", + eprefs[j], i + ); + } + } + + arch_push_data_header(); +} +#endif + +void salis_push_data_line() { + assert(g_sim_data); + + // Measure average membory block sizes + double amb0[CORES] = { 0 }; + double amb1[CORES] = { 0 }; + + for (int i = 0; i < CORES; ++i) { + struct Core *core = &g_cores[i]; + + for (uint64_t j = core->pfst; j <= core->plst; ++j) { + const struct Proc *proc = proc_get(core, j); + + amb0[i] += (double)proc->mb0s; + amb1[i] += (double)proc->mb1s; + } + + amb0[i] /= core->pnum; + amb1[i] /= core->pnum; + } + + g_info("Pushing row to 'general' table in SQLite database"); + salis_exec_sql( + 0, NULL, NULL, + "insert into general (" +#define FOR_CORE(i) \ + "cycl_" #i ", " \ + "mall_" #i ", " \ + "pnum_" #i ", " \ + "pfst_" #i ", " \ + "plst_" #i ", " \ + "amb0_" #i ", " \ + "amb1_" #i ", " \ + "emb0_" #i ", " \ + "emb1_" #i ", " \ + "eliv_" #i ", " \ + "edea_" #i ", " + FOR_CORES +#undef FOR_CORE + "step" + ") values (" +#define FOR_CORE(i) "%ld, %ld, %ld, %ld, %ld, %f, %f, %ld, %ld, %ld, %ld, " + FOR_CORES +#undef FOR_CORE + "%ld" + ");", +#define FOR_CORE(i) \ + g_cores[i].cycl, \ + g_cores[i].mall, \ + g_cores[i].pnum, \ + g_cores[i].pfst, \ + g_cores[i].plst, \ + amb0[i], \ + amb1[i], \ + g_cores[i].emb0, \ + g_cores[i].emb1, \ + g_cores[i].eliv, \ + g_cores[i].edea, + FOR_CORES +#undef FOR_CORE + g_steps + ); + + // TODO: insert execute memory events + char *eprefs[] = { "aev" /*, "eev" */ }; + int eprefs_cnt = sizeof(eprefs) / sizeof(eprefs[0]); + + for (int i = 0; i < CORES; ++i) { + for (int j = 0; j < eprefs_cnt; ++j) { + uint64_t *in = NULL; + + if (!strcmp("aev", eprefs[j])) { + in = g_cores[i].aeva; + } // else if (!strcmp("eev", eprefs[j])) { + // in = g_cores[i].eeva; + // } + + // Compress event data + size_t size = sizeof(uint64_t) * MVEC_SIZE; + char *out = malloc(size); + assert(out); + + z_stream strm = { 0 }; + strm.zalloc = NULL; + strm.zfree = NULL; + strm.opaque = NULL; + + deflateInit(&strm, Z_DEFAULT_COMPRESSION); + + strm.avail_in = size; + strm.avail_out = size; + strm.next_in = (Bytef *)in; + strm.next_out = (Bytef *)out; + + deflate(&strm, Z_FINISH); + + // Insert blob + const void *blob = out; + int blob_size = strm.total_out; + + g_info("Pushing row to '%s_%d' table in SQLite database", eprefs[j], i); + salis_exec_sql( + 1, &blob, &blob_size, + "insert into %s_%d (" +#define FOR_CORE(i) "cycl_" #i ", " + FOR_CORES +#undef FOR_CORE + "size, evts, step" + ") values (" +#define FOR_CORE(i) "%ld, " + FOR_CORES +#undef FOR_CORE + "%ld, ?, %ld" + ");", + eprefs[j], i, +#define FOR_CORE(i) g_cores[i].cycl, + FOR_CORES +#undef FOR_CORE + blob_size, g_steps + ); + + deflateEnd(&strm); + free(out); + } + } + + // Reset data aggregation fields + for (int i = 0; i < CORES; ++i) { + struct Core *core = &g_cores[i]; + + core->emb0 = 0; + core->emb1 = 0; + core->eliv = 0; + core->edea = 0; + + memset(core->aeva, 0, sizeof(uint64_t) * MVEC_SIZE); + //memset(core->eeva, 0, sizeof(uint64_t) * MVEC_SIZE); + } + + // Push arch-specific data + arch_push_data_line(); +} +#endif + #if defined(COMMAND_BENCH) || defined(COMMAND_NEW) void salis_init() { assert(g_info); @@ -691,8 +958,9 @@ void salis_init() { // See: https://sqlite.org/wal.html salis_exec_sql(0, NULL, NULL, "pragma journal_mode=wal;"); - arch_push_data_header(); - arch_push_data_line(); + // Initialize database + salis_push_data_header(); + salis_push_data_line(); #endif } #endif @@ -835,7 +1103,7 @@ void salis_loop(uint64_t ns, uint64_t dt) { #if defined(DATA_PUSH_PATH) if (g_steps % DATA_PUSH_INTERVAL == 0) { - arch_push_data_line(); + salis_push_data_line(); } #endif -- cgit v1.2.3-70-g09d2