summaryrefslogtreecommitdiff
path: root/cbits
diff options
context:
space:
mode:
Diffstat (limited to 'cbits')
-rw-r--r--cbits/hook.c25
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: