diff options
author | Tom Smeding <tom@tomsmeding.com> | 2022-04-21 00:46:24 +0200 |
---|---|---|
committer | Tom Smeding <tom@tomsmeding.com> | 2022-04-21 00:46:24 +0200 |
commit | 7b9e405e2f77268e3242a6d723c1b65d7759fd63 (patch) | |
tree | ace2f30ecc395a04758b18ec311b9aee41a64860 /cbits | |
parent | e6ca9f166c5af915946bb8ae5ed7e5a42f40b8bd (diff) |
Expose GC end timestamp
Diffstat (limited to 'cbits')
-rw-r--r-- | cbits/hook.c | 25 |
1 files changed, 20 insertions, 5 deletions
diff --git a/cbits/hook.c b/cbits/hook.c index e05ccd4..2175be4 100644 --- a/cbits/hook.c +++ b/cbits/hook.c @@ -1,5 +1,6 @@ #include "Rts.h" #include <string.h> +#include <time.h> // needs C11 #include <threads.h> @@ -12,6 +13,9 @@ extern RtsConfig rtsConfig; // A copy of GCDetails_ with known structure that can be depended on by the Haskell code. struct ShadowDetails { + int64_t timestamp_sec; + int64_t timestamp_nsec; + // The generation number of this GC uint32_t gen; // Number of threads used in this GC @@ -106,13 +110,21 @@ static struct ShadowDetails *detlog = NULL; // -------- static void hook_callback(const struct GCDetails_ *details) { - static bool alloc_failed = false; + static bool fatal_failure = false; + + if (fatal_failure) goto cleanup_no_mutex; - if (alloc_failed) goto cleanup_no_mutex; + // Do this now already, before waiting on the mutex + struct timespec now; + if (clock_gettime(CLOCK_MONOTONIC, &now) != 0) { + perror("clock_gettime"); + fatal_failure = true; + goto cleanup_no_mutex; + } if (mtx_lock(&detlog_mutex) != thrd_success) { fprintf(stderr, "ghc-gc-hook: ERROR: Mutex lock failed\n"); - alloc_failed = true; // dumb proxy for "don't do anything anymore please" + fatal_failure = true; goto cleanup_no_mutex; } @@ -123,12 +135,15 @@ static void hook_callback(const struct GCDetails_ *details) { detlog = realloc(detlog, detlog_capacity * sizeof(detlog[0])); if (detlog == NULL || detlog_capacity == 0) { // also check for overflow here fprintf(stderr, "ghc-gc-hook: ERROR: Could not allocate memory for GC log hook\n"); - alloc_failed = true; + fatal_failure = true; goto cleanup; } } - shadow_copy(&detlog[detlog_length], details); + struct ShadowDetails *dst = &detlog[detlog_length]; + dst->timestamp_sec = now.tv_sec; + dst->timestamp_nsec = now.tv_nsec; + shadow_copy(dst, details); detlog_length++; cleanup: |