<pre style='margin:0'>
Chris Jones (cjones051073) pushed a commit to branch master
in repository macports-legacy-support.
</pre>
<p><a href="https://github.com/macports/macports-legacy-support/commit/fd311adb67210a68307191cbafc84bdb541e5c8d">https://github.com/macports/macports-legacy-support/commit/fd311adb67210a68307191cbafc84bdb541e5c8d</a></p>
<pre style="white-space: pre; background: #F8F8F8">The following commit(s) were added to refs/heads/master by this push:
<span style='display:block; white-space:pre;color:#404040;'> new fd311ad Implemented `CLOCK_THREAD_CPUTIME_ID` via `thread_info`
</span>fd311ad is described below
<span style='display:block; white-space:pre;color:#808000;'>commit fd311adb67210a68307191cbafc84bdb541e5c8d
</span>Author: Kirill A. Korinsky <kirill@korins.ky>
AuthorDate: Tue Aug 22 21:57:10 2023 +0200
<span style='display:block; white-space:pre;color:#404040;'> Implemented `CLOCK_THREAD_CPUTIME_ID` via `thread_info`
</span><span style='display:block; white-space:pre;color:#404040;'>
</span><span style='display:block; white-space:pre;color:#404040;'> This seems the best source of that value on macOS since 10.0
</span>---
include/time.h | 4 +++
src/time.c | 21 +++++++++++--
test/test_time.cpp | 88 +++++++++++++++++++++++++++++++++++++++++++++++++++++-
3 files changed, 110 insertions(+), 3 deletions(-)
<span style='display:block; white-space:pre;color:#808080;'>diff --git a/include/time.h b/include/time.h
</span><span style='display:block; white-space:pre;color:#808080;'>index 4a62300..7f2e88a 100644
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>--- a/include/time.h
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>+++ b/include/time.h
</span><span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -74,6 +74,10 @@ typedef int clockid_t;
</span> #define CLOCK_PROCESS_CPUTIME_ID 12
#endif
<span style='display:block; white-space:pre;background:#e0ffe0;'>+#ifndef CLOCK_THREAD_CPUTIME_ID
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#define CLOCK_THREAD_CPUTIME_ID 16
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#endif
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span> __MP__BEGIN_DECLS
extern int clock_gettime( clockid_t clk_id, struct timespec *ts );
<span style='display:block; white-space:pre;color:#808080;'>diff --git a/src/time.c b/src/time.c
</span><span style='display:block; white-space:pre;color:#808080;'>index 61a078c..ec3885c 100644
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>--- a/src/time.c
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>+++ b/src/time.c
</span><span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -22,7 +22,11 @@
</span> #include <sys/time.h>
#include <sys/sysctl.h>
#include <sys/resource.h>
<span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#include <mach/mach_init.h>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#include <mach/mach_port.h>
</span> #include <mach/mach_time.h>
<span style='display:block; white-space:pre;background:#e0ffe0;'>+#include <mach/thread_act.h>
</span>
#define BILLION 1000000000L
#define MILLION 1000000L
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -61,6 +65,19 @@ int clock_gettime( clockid_t clk_id, struct timespec *ts )
</span> ts->tv_sec = ru.ru_utime.tv_sec;
ts->tv_nsec = ru.ru_utime.tv_usec * 1000;
}
<span style='display:block; white-space:pre;background:#e0ffe0;'>+ else if ( CLOCK_THREAD_CPUTIME_ID == clk_id )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ mach_msg_type_number_t count = THREAD_BASIC_INFO_COUNT;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ thread_basic_info_data_t info;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ thread_port_t thread = mach_thread_self();
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ ret = thread_info(thread, THREAD_BASIC_INFO, (thread_info_t) &info, &count);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ mach_port_deallocate(mach_task_self(), thread);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ time_value_add(&info.user_time, &info.system_time);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ ts->tv_sec = info.user_time.seconds;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ ts->tv_nsec = info.user_time.microseconds * 1000;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span> else if ( CLOCK_MONOTONIC_RAW == clk_id ||
CLOCK_MONOTONIC_RAW_APPROX == clk_id ||
CLOCK_UPTIME_RAW == clk_id ||
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -87,7 +104,8 @@ int clock_getres( clockid_t clk_id, struct timespec *ts )
</span> {
if ( CLOCK_REALTIME == clk_id ||
CLOCK_MONOTONIC == clk_id ||
<span style='display:block; white-space:pre;background:#ffe0e0;'>- CLOCK_PROCESS_CPUTIME_ID == clk_id )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ CLOCK_PROCESS_CPUTIME_ID == clk_id ||
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ CLOCK_THREAD_CPUTIME_ID == clk_id)
</span> {
// return 1us precision
ts->tv_sec = 0;
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -96,7 +114,6 @@ int clock_getres( clockid_t clk_id, struct timespec *ts )
</span> }
else if ( CLOCK_MONOTONIC_RAW == clk_id ||
CLOCK_MONOTONIC_RAW_APPROX == clk_id ||
<span style='display:block; white-space:pre;background:#ffe0e0;'>- CLOCK_PROCESS_CPUTIME_ID == clk_id ||
</span> CLOCK_UPTIME_RAW == clk_id ||
CLOCK_UPTIME_RAW_APPROX == clk_id )
{
<span style='display:block; white-space:pre;color:#808080;'>diff --git a/test/test_time.cpp b/test/test_time.cpp
</span><span style='display:block; white-space:pre;color:#808080;'>index 1c8b81a..41b2a03 100644
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>--- a/test/test_time.cpp
</span><span style='display:block; white-space:pre;background:#e0e0ff;'>+++ b/test/test_time.cpp
</span><span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -1,7 +1,9 @@
</span>
#include <iostream>
<span style='display:block; white-space:pre;background:#ffe0e0;'>-//#include <cstdint>
</span>
<span style='display:block; white-space:pre;background:#e0ffe0;'>+#include <pthread.h>
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+#include <unistd.h>
</span> #include <time.h>
static unsigned long long kSecondsToNanos = 1000ULL * 1000ULL * 1000ULL;
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -26,6 +28,64 @@ inline void res( CLOCKID clk_id )
</span> << std::endl;
}
<span style='display:block; white-space:pre;background:#e0ffe0;'>+static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+static void* test_thread_sleep(void *arg)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ int delay = *(int *)arg;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ int c = 0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ while ( ++c < 10 )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ unsigned long long was = time(CLOCK_THREAD_CPUTIME_ID);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ usleep(delay);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ unsigned long long now = time(CLOCK_THREAD_CPUTIME_ID);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ ::pthread_mutex_lock(&lock);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ std::cout << "[sleep for " << delay << "us] consumed thread CPU time: "<< now - was << " ns" << std::endl;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ ::pthread_mutex_unlock(&lock);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ return NULL;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+static void* test_blackhole_thread(void *arg)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ int cycles = *(int *)arg;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ int c = 0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ while ( ++c < 10 )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ unsigned long long was = time(CLOCK_THREAD_CPUTIME_ID);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ int i = 0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ int cc = 0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ while ( ++cc < cycles )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ i = cc * cc % c;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ unsigned long long now = time(CLOCK_THREAD_CPUTIME_ID);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ ::pthread_mutex_lock(&lock);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ std::cout << "[" << i << "~" << cycles << "] consumed thread CPU time: "<< now - was << " ns" << std::endl;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ ::pthread_mutex_unlock(&lock);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ return NULL;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+static void* test_wait_thread(void *arg)
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+{
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ int c = 0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ while ( ++c < 10 )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ usleep(100);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ ::pthread_mutex_lock(&lock);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ std::cout << "[t2] CLOCK_THREAD_CPUTIME_ID ("<< CLOCK_THREAD_CPUTIME_ID << ") " << time(CLOCK_THREAD_CPUTIME_ID) << std::endl;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ ::pthread_mutex_unlock(&lock);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ return NULL;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+}
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span> int main()
{
{
<span style='display:block; white-space:pre;background:#e0e0e0;'>@@ -84,5 +144,31 @@ int main()
</span> std::cout << "CLOCK_PROCESS_CPUTIME_ID ("<< CLOCK_PROCESS_CPUTIME_ID << ") " << time(CLOCK_PROCESS_CPUTIME_ID) << std::endl;
}
}
<span style='display:block; white-space:pre;background:#e0ffe0;'>+ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ int c = 0;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ res(CLOCK_THREAD_CPUTIME_ID);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ while ( ++c < 10 )
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ std::cout << "CLOCK_THREAD_CPUTIME_ID ("<< CLOCK_THREAD_CPUTIME_ID << ") " << time(CLOCK_THREAD_CPUTIME_ID) << std::endl;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ {
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ pthread_t t1, t2, t3, t4;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ int sleep1 = 100;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ int sleep2 = 100000;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ int cycles1 = 1000;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ int cycles2 = 10000000;
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ ::pthread_create(&t1, NULL, test_thread_sleep, &sleep1);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ ::pthread_create(&t2, NULL, test_thread_sleep, &sleep2);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ ::pthread_create(&t3, NULL, test_blackhole_thread, &cycles1);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ ::pthread_create(&t4, NULL, test_blackhole_thread, &cycles2);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ ::pthread_join(t1, NULL);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ ::pthread_join(t2, NULL);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ ::pthread_join(t3, NULL);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ ::pthread_join(t4, NULL);
</span><span style='display:block; white-space:pre;background:#e0ffe0;'>+ }
</span> return 0;
}
</pre><pre style='margin:0'>
</pre>