diff --git a/rts/GetTime.h b/rts/GetTime.h
index 97f499cd6c526a2af89fe046e5917708710a8864..5bff00c9cb3d7d579fc992d6e4bff2ee092dfdd7 100644
--- a/rts/GetTime.h
+++ b/rts/GetTime.h
@@ -13,6 +13,7 @@
 void initializeTimer       (void);
 
 Time getProcessCPUTime     (void);
+Time getCurrentThreadCPUTime (void);
 void getProcessTimes       (Time *user, Time *elapsed);
 
 /* Get the current date and time.
diff --git a/rts/posix/GetTime.c b/rts/posix/GetTime.c
index 8d20d18bfb89a1e1e49f6cdaccd5a65c2940b813..1c777081315f5b8838ef944d5b3b17d8cbf66381 100644
--- a/rts/posix/GetTime.c
+++ b/rts/posix/GetTime.c
@@ -44,11 +44,61 @@ void initializeTimer()
 #endif
 }
 
+#if defined(HAVE_CLOCK_GETTIME)
+static Time getClockTime(clockid_t clock)
+{
+    struct timespec ts;
+    int res = clock_gettime(clock, &ts);
+    if (res == 0) {
+        return SecondsToTime(ts.tv_sec) + NSToTime(ts.tv_nsec);
+    } else {
+        sysErrorBelch("clock_gettime");
+        stg_exit(EXIT_FAILURE);
+    }
+}
+#endif
+
+Time getCurrentThreadCPUTime(void)
+{
+#if defined(HAVE_CLOCK_GETTIME)          &&  \
+       defined(CLOCK_PROCESS_CPUTIME_ID) &&  \
+       defined(HAVE_SYSCONF)
+    static bool have_checked_usability = false;
+    if (!have_checked_usability) {
+        // The Linux clock_getres(2) manpage claims that some early versions of
+        // Linux will return values which are uninterpretable in the presence
+        // of migration across CPUs. They claim that clock_getcpuclockid(0)
+        // will return ENOENT in this case. Check this.
+        clockid_t clkid;
+        if (clock_getcpuclockid(0, &clkid)) {
+            sysErrorBelch("getCurrentThreadCPUTime: no supported");
+            stg_exit(EXIT_FAILURE);
+        }
+        have_checked_usability = true;
+    }
+    return getClockTime(CLOCK_THREAD_CPUTIME_ID);
+#elif defined(darwin_HOST_OS)
+    mach_port_t port = pthread_mach_thread_np(osThreadId());
+    thread_basic_info_data_t info = { 0 };
+    mach_msg_type_number_t info_count = THREAD_BASIC_INFO_COUNT;
+    kern_return_t kern_err = thread_info(mach_thread_self(), THREAD_BASIC_INFO,
+                                         (thread_info_t) &info, &info_count);
+    if (kern_err == KERN_SUCCESS) {
+        return SecondsToTime(info.user_time.seconds) + USToTime(info.user_time.microseconds);
+    } else {
+        sysErrorBelch("getThreadCPUTime");
+        stg_exit(EXIT_FAILURE);
+    }
+#else
+#error I know of no means to find the CPU time of current thread on this platform.
+#endif
+}
+
 Time getProcessCPUTime(void)
 {
 #if !defined(BE_CONSERVATIVE)            &&  \
        defined(HAVE_CLOCK_GETTIME)       &&  \
-       defined(_SC_CPUTIME)             &&  \
+       defined(_SC_CPUTIME)              &&  \
        defined(CLOCK_PROCESS_CPUTIME_ID) &&  \
        defined(HAVE_SYSCONF)
     static int checked_sysconf = 0;
@@ -59,15 +109,7 @@ Time getProcessCPUTime(void)
         checked_sysconf = 1;
     }
     if (sysconf_result != -1) {
-        struct timespec ts;
-        int res;
-        res = clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &ts);
-        if (res == 0) {
-            return SecondsToTime(ts.tv_sec) + NSToTime(ts.tv_nsec);
-        } else {
-            sysErrorBelch("clock_gettime");
-            stg_exit(EXIT_FAILURE);
-        }
+        return getClockTime(CLOCK_PROCESS_CPUTIME_ID);
     }
 #endif
 
@@ -82,16 +124,7 @@ Time getProcessCPUTime(void)
 StgWord64 getMonotonicNSec(void)
 {
 #if defined(HAVE_CLOCK_GETTIME)
-    struct timespec ts;
-    int res;
-
-    res = clock_gettime(CLOCK_ID, &ts);
-    if (res != 0) {
-        sysErrorBelch("clock_gettime");
-        stg_exit(EXIT_FAILURE);
-    }
-    return (StgWord64)ts.tv_sec * 1000000000 +
-           (StgWord64)ts.tv_nsec;
+    return getClockTime(CLOCK_ID);
 
 #elif defined(darwin_HOST_OS)
 
@@ -102,7 +135,9 @@ StgWord64 getMonotonicNSec(void)
 
     struct timeval tv;
 
-    gettimeofday(&tv, (struct timezone *) NULL);
+    if (gettimeofday(&tv, (struct timezone *) NULL) != 0) {
+        debugBlech("getMonotonicNSec: gettimeofday failed: %s", strerror(errno));
+    };
     return (StgWord64)tv.tv_sec * 1000000000 +
            (StgWord64)tv.tv_usec * 1000;
 
diff --git a/rts/win32/GetTime.c b/rts/win32/GetTime.c
index 61a978e2aa6ec5749204b205d2cac2192bbac5b2..e0f5e7d4067f1d3b6524293ff8e47ce367ffc51c 100644
--- a/rts/win32/GetTime.c
+++ b/rts/win32/GetTime.c
@@ -34,6 +34,20 @@ getProcessTimes(Time *user, Time *elapsed)
     *elapsed = getProcessElapsedTime();
 }
 
+Time
+getCurrentThreadCPUTime(void)
+{
+    FILETIME creationTime, exitTime, userTime, kernelTime = {0,0};
+
+    if (!GetThreadTimes(GetCurrentThread(), &creationTime,
+                        &exitTime, &kernelTime, &userTime)) {
+        sysErrorBelch("getCurrentThreadCPUTime: Win32 error %lu", GetLastError());
+        return 0;
+    }
+
+    return fileTimeToRtsTime(userTime);
+}
+
 Time
 getProcessCPUTime(void)
 {