aboutsummaryrefslogtreecommitdiff
path: root/core
diff options
context:
space:
mode:
Diffstat (limited to 'core')
-rw-r--r--core/compress.c97
-rw-r--r--core/render.c15
-rw-r--r--core/salis.c143
3 files changed, 164 insertions, 91 deletions
diff --git a/core/compress.c b/core/compress.c
index df61123..1938bb3 100644
--- a/core/compress.c
+++ b/core/compress.c
@@ -1,56 +1,77 @@
-void salis_deflate(z_stream *strm, size_t size, Bytef *in, Bytef *out) {
- assert(strm);
- assert(size);
- assert(in);
- assert(out);
+#define EVA_SIZE (sizeof(uint64_t) * MVEC_SIZE)
- strm->zalloc = NULL;
- strm->zfree = NULL;
- strm->opaque = NULL;
+struct DeflateParams {
+ z_stream strm;
+ size_t size;
+ Bytef *in;
+ Bytef *out;
+ uint8_t tgap[THREAD_GAP];
+};
- deflateInit(strm, Z_DEFAULT_COMPRESSION);
+struct InflateParams {
+ z_stream strm;
+ size_t avail_in;
+ size_t size;
+ Bytef *in;
+ Bytef *out;
+ uint8_t tgap[THREAD_GAP];
+};
- strm->avail_in = size;
- strm->avail_out = size;
- strm->next_in = in;
- strm->next_out = out;
+int salis_deflate(struct DeflateParams *params) {
+ assert(params);
+ assert(params->size);
+ assert(params->in);
+ assert(params->out);
- deflate(strm, Z_FINISH);
-}
+ params->strm.zalloc = NULL;
+ params->strm.zfree = NULL;
+ params->strm.opaque = NULL;
+
+ deflateInit(&params->strm, Z_DEFAULT_COMPRESSION);
-void salis_deflate_end(z_stream *strm) {
- assert(strm);
+ params->strm.avail_in = params->size;
+ params->strm.avail_out = params->size;
+ params->strm.next_in = params->in;
+ params->strm.next_out = params->out;
- deflateEnd(strm);
+ deflate(&params->strm, Z_FINISH);
+
+ return 0;
}
-void salis_inflate(z_stream *strm, size_t avail_in, size_t size, Bytef *in, Bytef *out) {
- assert(strm);
- assert(avail_in);
- assert(size);
- assert(in);
- assert(out);
+void salis_deflate_end(struct DeflateParams *params) {
+ assert(params);
+ deflateEnd(&params->strm);
+}
- strm->next_in = in;
- strm->avail_in = avail_in;
- strm->zalloc = NULL;
- strm->zfree = NULL;
- strm->opaque = NULL;
+int salis_inflate(struct InflateParams *params) {
+ assert(params);
+ assert(params->avail_in);
+ assert(params->size);
+ assert(params->in);
+ assert(params->out);
- inflateInit(strm);
+ params->strm.next_in = params->in;
+ params->strm.avail_in = params->avail_in;
+ params->strm.zalloc = NULL;
+ params->strm.zfree = NULL;
+ params->strm.opaque = NULL;
- strm->avail_out = size;
- strm->next_out = out;
+ inflateInit(&params->strm);
+
+ params->strm.avail_out = params->size;
+ params->strm.next_out = params->out;
#if defined(NDEBUG)
- inflate(strm, Z_FINISH);
+ inflate(&params->strm, Z_FINISH);
#else
- assert(inflate(strm, Z_FINISH));
+ assert(inflate(&params->strm, Z_FINISH));
#endif
-}
-void salis_inflate_end(z_stream *strm) {
- assert(strm);
+ return 0;
+}
- inflateEnd(strm);
+void salis_inflate_end(struct InflateParams *params) {
+ assert(params);
+ inflateEnd(&params->strm);
}
diff --git a/core/render.c b/core/render.c
index f9da65d..f42e821 100644
--- a/core/render.c
+++ b/core/render.c
@@ -8,8 +8,6 @@ SQLITE_EXTENSION_INIT1
#include "compress.c"
-#define EVA_SIZE (sizeof(uint64_t) * MVEC_SIZE)
-
void eva_render(sqlite3_context *context, int argc, sqlite3_value **argv) {
assert(context);
assert(argc == 4);
@@ -40,9 +38,16 @@ void eva_render(sqlite3_context *context, int argc, sqlite3_value **argv) {
size_t out_size = sizeof(uint64_t) * px_count;
uint64_t *eva = sqlite3_malloc(EVA_SIZE);
uint64_t *out = sqlite3_malloc(out_size);
- z_stream strm = { 0 };
- salis_inflate(&strm, blob_size, EVA_SIZE, (Bytef *)blob, (Bytef *)eva);
- salis_inflate_end(&strm);
+
+ struct InflateParams params = {
+ .avail_in = blob_size,
+ .size = EVA_SIZE,
+ .in = (Bytef *)blob,
+ .out = (Bytef *)eva,
+ };
+
+ salis_inflate(&params);
+ salis_inflate_end(&params);
// Render image
for (size_t i = 0; i < px_count; i++) {
diff --git a/core/salis.c b/core/salis.c
index def8243..6a42bb3 100644
--- a/core/salis.c
+++ b/core/salis.c
@@ -14,6 +14,14 @@
#define MALL_FLAG 0x80
#define UINT64_HALF 0x8000000000000000ul
+#if defined(DATA_PUSH_PATH)
+#define EVENT_ARRAYS \
+ EVENT_ARRAY(0, aev) /* allocation events array */ \
+ EVENT_ARRAY(1, eev) /* executions events array */ \
+ EVENT_ARRAY(2, bev) /* birth events array */
+#define EVENT_ARRAYS_COUNT 3
+#endif
+
#if defined(COMPRESS) || defined(DATA_PUSH_PATH)
#include "compress.c"
#endif
@@ -37,7 +45,7 @@ struct Core {
uint64_t psli;
thrd_t thrd;
- uint64_t thrd_idx;
+ uint64_t thrd_steps;
uint64_t ivpt;
uint64_t *ivav;
@@ -49,9 +57,9 @@ struct Core {
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
- uint64_t beva[MVEC_SIZE]; // birth events array
+#define EVENT_ARRAY(_, ev) uint64_t ev##a[MVEC_SIZE];
+ EVENT_ARRAYS
+#undef EVENT_ARRAY
#define CORE_DATA_FIELD(type, name, suff) type name suff;
CORE_DATA_FIELDS
@@ -79,6 +87,8 @@ char g_asav_pbuf[AUTOSAVE_NAME_LEN];
#if defined(DATA_PUSH_PATH)
sqlite3 *g_sim_data;
+thrd_t g_eva_thrds[CORES][EVENT_ARRAYS_COUNT];
+struct DeflateParams g_eva_deflate_params[CORES][EVENT_ARRAYS_COUNT];
#endif
// Each UI must install these logger functions before salis_init() gets invoked
@@ -437,9 +447,10 @@ void core_save(FILE *f, const struct Core *core) {
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);
- fwrite(core->beva, sizeof(uint64_t), MVEC_SIZE, f);
+#define EVENT_ARRAY(_, ev) \
+ fwrite(core->ev##a, sizeof(uint64_t), MVEC_SIZE, f);
+ EVENT_ARRAYS
+#undef EVENT_ARRAY
#endif
arch_core_save(f, core);
@@ -534,9 +545,10 @@ void core_load(FILE *f, struct Core *core) {
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);
- fread(core->beva, sizeof(uint64_t), MVEC_SIZE, f);
+#define EVENT_ARRAY(_, ev) \
+ fread(core->ev##a, sizeof(uint64_t), MVEC_SIZE, f);
+ EVENT_ARRAYS
+#undef EVENT_ARRAY
#endif
arch_core_load(f, core);
@@ -663,17 +675,22 @@ void salis_save(const char *path) {
char *out = malloc(size);
assert(out);
- z_stream strm = { 0 };
- salis_deflate(&strm, size, (Bytef *)in, (Bytef *)out);
+ struct DeflateParams params = {
+ .size = size,
+ .in = (Bytef *)in,
+ .out = (Bytef *)out,
+ };
+
+ salis_deflate(&params);
FILE *fx = fopen(path, "wb");
assert(fx);
fwrite(&size, sizeof(size_t), 1, fx);
- fwrite(out, sizeof(char), strm.total_out, fx);
+ fwrite(out, sizeof(char), params.strm.total_out, fx);
fclose(fx);
- salis_deflate_end(&strm);
+ salis_deflate_end(&params);
free(in);
free(out);
@@ -781,12 +798,19 @@ void salis_push_data_header(void) {
);
// Memory events
- char *eprefs[] = { "aev", "eev", "bev" };
- 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);
+ for (int j = 0; j < EVENT_ARRAYS_COUNT; ++j) {
+ char *pref = NULL;
+
+ switch (j) {
+#define EVENT_ARRAY(idx, ev) \
+ case idx: pref = #ev; break;
+ EVENT_ARRAYS
+#undef EVENT_ARRAY
+ default: assert(false);
+ }
+
+ g_info("Creating '%s_%d' table in SQLite database", pref, i);
salis_exec_sql(
0, NULL, NULL,
"create table %s_%d ("
@@ -797,7 +821,7 @@ void salis_push_data_header(void) {
"evts blob not null ,"
"step int not null"
");",
- eprefs[j], i
+ pref, i
);
}
}
@@ -868,34 +892,50 @@ void salis_push_data_line(void) {
);
// Insert generic memory events
- char *eprefs[] = { "aev", "eev", "bev" };
- int eprefs_cnt = sizeof(eprefs) / sizeof(eprefs[0]);
+ // Compression (deflation) is CPU intensive so it is done in parallel
+ memset(&g_eva_deflate_params, 0, sizeof(struct DeflateParams) * CORES * EVENT_ARRAYS_COUNT);
for (int i = 0; i < CORES; ++i) {
- for (int j = 0; j < eprefs_cnt; ++j) {
+ for (int j = 0; j < EVENT_ARRAYS_COUNT; ++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;
- } else if (!strcmp("bev", eprefs[j])) {
- in = g_cores[i].beva;
+ switch (j) {
+#define EVENT_ARRAY(idx, ev) \
+ case idx: in = g_cores[i].ev##a; break;
+ EVENT_ARRAYS
+#undef EVENT_ARRAY
+ default: assert(false);
}
// Compress event data
- size_t size = sizeof(uint64_t) * MVEC_SIZE;
- char *out = malloc(size);
- assert(out);
+ struct DeflateParams *params = &g_eva_deflate_params[i][j];
+ params->size = EVA_SIZE,
+ params->in = (Bytef *)in,
+ params->out = (Bytef *)malloc(EVA_SIZE),
+ thrd_create(&g_eva_thrds[i][j], (thrd_start_t)salis_deflate, params);
+ }
+ }
- z_stream strm = { 0 };
- salis_deflate(&strm, size, (Bytef *)in, (Bytef *)out);
+ for (int i = 0; i < CORES; ++i) {
+ for (int j = 0; j < EVENT_ARRAYS_COUNT; ++j) {
+ char *pref = NULL;
+
+ switch (j) {
+#define EVENT_ARRAY(idx, ev) \
+ case idx: pref = #ev; break;
+ EVENT_ARRAYS
+#undef EVENT_ARRAY
+ default: assert(false);
+ }
+
+ thrd_join(g_eva_thrds[i][j], NULL);
// Insert blob
- const void *blob = out;
- int blob_size = strm.total_out;
+ struct DeflateParams *params = &g_eva_deflate_params[i][j];
+ const void *blob = params->out;
+ int blob_size = params->strm.total_out;
- g_info("Pushing row to '%s_%d' table in SQLite database", eprefs[j], i);
+ g_info("Pushing row to '%s_%d' table in SQLite database", pref, i);
salis_exec_sql(
1, &blob, &blob_size,
"insert into %s_%d ("
@@ -909,15 +949,15 @@ void salis_push_data_line(void) {
#undef FOR_CORE
"%ld, ?, %ld"
");",
- eprefs[j], i,
+ pref, i,
#define FOR_CORE(i) g_cores[i].cycl,
FOR_CORES
#undef FOR_CORE
blob_size, g_steps
);
- salis_deflate_end(&strm);
- free(out);
+ salis_deflate_end(params);
+ free(params->out);
}
}
@@ -930,9 +970,10 @@ void salis_push_data_line(void) {
core->eliv = 0;
core->edea = 0;
- memset(core->aeva, 0, sizeof(uint64_t) * MVEC_SIZE);
- memset(core->eeva, 0, sizeof(uint64_t) * MVEC_SIZE);
- memset(core->beva, 0, sizeof(uint64_t) * MVEC_SIZE);
+#define EVENT_ARRAY(_, ev) \
+ memset(core->ev##a, 0, EVA_SIZE);
+ EVENT_ARRAYS
+#undef EVENT_ARRAY
}
// Push arch-specific data
@@ -996,9 +1037,15 @@ void salis_load(void) {
char *out = malloc(size);
assert(out);
- z_stream strm = { 0 };
- salis_inflate(&strm, x_size, size, (Bytef *)in, (Bytef *)out);
- salis_inflate_end(&strm);
+ struct InflateParams params = {
+ .avail_in = x_size,
+ .size = size,
+ .in = (Bytef *)in,
+ .out = (Bytef *)out,
+ };
+
+ salis_inflate(&params);
+ salis_inflate_end(&params);
FILE *f = fmemopen(out, size, "rb");
#else
@@ -1033,7 +1080,7 @@ void salis_load(void) {
int salis_thread(struct Core *core) {
assert(core);
- for (uint64_t i = 0; i < core->thrd_idx; ++i) {
+ for (uint64_t i = 0; i < core->thrd_steps; ++i) {
core_step(core);
}
@@ -1042,7 +1089,7 @@ int salis_thread(struct Core *core) {
void salis_run_thread(uint64_t ns) {
for (int i = 0; i < CORES; ++i) {
- g_cores[i].thrd_idx = ns;
+ g_cores[i].thrd_steps = ns;
thrd_create(
&g_cores[i].thrd,