diff --git a/docs/src/threading.rst b/docs/src/threading.rst index ca9fb0ce..d379677a 100644 --- a/docs/src/threading.rst +++ b/docs/src/threading.rst @@ -119,6 +119,15 @@ Threads .. versionadded:: 1.45.0 +.. c:function:: int uv_thread_getcpu(void) + + Gets the CPU number on which the calling thread is running. + + .. note:: + Currently only implemented on Windows, Linux and FreeBSD. + + .. versionadded:: 1.45.0 + .. c:function:: uv_thread_t uv_thread_self(void) .. c:function:: int uv_thread_join(uv_thread_t *tid) .. c:function:: int uv_thread_equal(const uv_thread_t* t1, const uv_thread_t* t2) diff --git a/include/uv.h b/include/uv.h index 68128db1..30e09c61 100644 --- a/include/uv.h +++ b/include/uv.h @@ -1802,6 +1802,7 @@ UV_EXTERN int uv_thread_setaffinity(uv_thread_t* tid, UV_EXTERN int uv_thread_getaffinity(uv_thread_t* tid, char* cpumask, size_t mask_size); +UV_EXTERN int uv_thread_getcpu(void); UV_EXTERN uv_thread_t uv_thread_self(void); UV_EXTERN int uv_thread_join(uv_thread_t *tid); UV_EXTERN int uv_thread_equal(const uv_thread_t* t1, const uv_thread_t* t2); diff --git a/src/unix/thread.c b/src/unix/thread.c index 77159511..f75fe82a 100644 --- a/src/unix/thread.c +++ b/src/unix/thread.c @@ -382,6 +382,19 @@ int uv_thread_getaffinity(uv_thread_t* tid, } #endif /* defined(__linux__) || defined(UV_BSD_H) */ +int uv_thread_getcpu(void) { +#if defined(__linux__) || defined(__FreeBSD__) + int cpu; + + cpu = sched_getcpu(); + if (cpu < 0) + return UV__ERR(errno); + + return cpu; +#else + return UV_ENOTSUP; +#endif +} uv_thread_t uv_thread_self(void) { return pthread_self(); diff --git a/src/win/thread.c b/src/win/thread.c index da150e45..5e86999c 100644 --- a/src/win/thread.c +++ b/src/win/thread.c @@ -252,6 +252,9 @@ int uv_thread_getaffinity(uv_thread_t* tid, return 0; } +int uv_thread_getcpu(void) { + return GetCurrentProcessorNumber(); +} uv_thread_t uv_thread_self(void) { uv_thread_t key; diff --git a/test/test-thread-affinity.c b/test/test-thread-affinity.c index 43783bc4..2c9b696e 100644 --- a/test/test-thread-affinity.c +++ b/test/test-thread-affinity.c @@ -34,6 +34,8 @@ TEST_IMPL(thread_affinity) { char* cpumask; int ncpus; int r; + int c; + int i; uv_thread_t threads[3]; #ifdef _WIN32 @@ -99,6 +101,24 @@ TEST_IMPL(thread_affinity) { ASSERT(cpumask[t2first + 2] == (ncpus >= 3)); ASSERT(cpumask[t2first + 3] == 0); + c = uv_thread_getcpu(); + ASSERT_GE(c, 0); + + memset(cpumask, 0, cpumasksize); + cpumask[c] = 1; + r = uv_thread_setaffinity(&threads[0], cpumask, NULL, cpumasksize); + ASSERT_EQ(r, 0); + + memset(cpumask, 0, cpumasksize); + r = uv_thread_getaffinity(&threads[0], cpumask, cpumasksize); + ASSERT_EQ(r, 0); + for (i = 0; i < cpumasksize; i++) { + if (i == c) + ASSERT_EQ(1, cpumask[i]); + else + ASSERT_EQ(0, cpumask[i]); + } + free(cpumask); return 0;