From a3ec8e0b6b5cc88063893fd7226599727a41dd29 Mon Sep 17 00:00:00 2001 From: Benoit Germain Date: Fri, 9 Nov 2018 17:36:35 +0100 Subject: new API lanes.set_thread_affinity(), and et_debug_threadname implemented with win32 pthread --- src/lanes.c | 12 ++++++++++++ src/lanes.lua | 3 ++- src/threading.c | 26 +++++++++++++++++++++++++- src/threading.h | 1 + 4 files changed, 40 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/lanes.c b/src/lanes.c index 72f9dd6..f43a2e6 100644 --- a/src/lanes.c +++ b/src/lanes.c @@ -2022,6 +2022,17 @@ LUAG_FUNC( set_thread_priority) return 0; } +LUAG_FUNC( set_thread_affinity) +{ + lua_Integer affinity = luaL_checkinteger( L, 1); + if( affinity <= 0) + { + return luaL_error( L, "invalid affinity (%d)", affinity); + } + THREAD_SET_AFFINITY( (unsigned int) affinity); + return 0; +} + #if USE_DEBUG_SPEW // can't use direct LUA_x errcode indexing because the sequence is not the same between Lua 5.1 and 5.2 :-( // LUA_ERRERR doesn't have the same value @@ -2995,6 +3006,7 @@ static const struct luaL_Reg lanes_functions [] = { {"now_secs", LG_now_secs}, {"wakeup_conv", LG_wakeup_conv}, {"set_thread_priority", LG_set_thread_priority}, + {"set_thread_affinity", LG_set_thread_affinity}, {"nameof", luaG_nameof}, {"register", LG_register}, {"set_singlethreaded", LG_set_singlethreaded}, diff --git a/src/lanes.lua b/src/lanes.lua index b82ae2a..6779095 100644 --- a/src/lanes.lua +++ b/src/lanes.lua @@ -190,7 +190,7 @@ lanes.configure = function( settings_) -- -- 'opt': .priority: int (-3..+3) smaller is lower priority (0 = default) -- - -- .cancelstep: bool | uint + -- .cancelstep: bool | uint -- false: cancellation check only at pending Linda operations -- (send/receive) so no runtime performance penalty (default) -- true: adequate cancellation check (same as 100) @@ -723,6 +723,7 @@ lanes.configure = function( settings_) lanes.set_singlethreaded = core.set_singlethreaded lanes.threads = core.threads or function() error "lane tracking is not available" end -- core.threads isn't registered if settings.track_lanes is false lanes.set_thread_priority = core.set_thread_priority + lanes.set_thread_affinity = core.set_thread_affinity lanes.timer = timer lanes.timer_lane = timer_lane lanes.timers = timers diff --git a/src/threading.c b/src/threading.c index 0a4c62a..c0e6a55 100644 --- a/src/threading.c +++ b/src/threading.c @@ -324,6 +324,13 @@ void THREAD_SET_PRIORITY( int prio) } } +void THREAD_SET_AFFINITY( unsigned int aff) +{ + if( !SetThreadAffinityMask( GetCurrentThread(), aff)); + { + FAIL( "THREAD_SET_AFFINITY", GetLastError()); + } +} bool_t THREAD_WAIT_IMPL( THREAD_T *ref, double secs) { @@ -546,6 +553,7 @@ bool_t THREAD_WAIT_IMPL( THREAD_T *ref, double secs) // On Linux, SCHED_RR and su privileges are required.. !-( // #include + #include # if (defined(__MINGW32__) || defined(__MINGW64__)) && defined pthread_attr_setschedpolicy # if pthread_attr_setschedpolicy( A, S) == ENOTSUP @@ -862,6 +870,22 @@ void THREAD_SET_PRIORITY( int prio) } } +void THREAD_SET_AFFINITY( unsigned int aff) +{ + cpu_set_t cpuset; + int bit = 0; + CPU_ZERO( &cpuset); + while( aff != 0) + { + if( aff & 1) + { + CPU_SET( bit, &cpuset); + } + ++ bit; + aff >>= 1; + } + PT_CALL( pthread_setaffinity_np( pthread_self(), sizeof(cpu_set_t), &cpuset)); +} /* * Wait for a thread to finish. @@ -959,7 +983,7 @@ bool_t THREAD_WAIT( THREAD_T *ref, double secs , SIGNAL_T *signal_ref, MUTEX_T * #elif defined PLATFORM_OSX pthread_setname_np(_name); #elif defined PLATFORM_WIN32 || defined PLATFORM_POCKETPC - // no API in win32-pthread yet :-( + PT_CALL( pthread_setname_np( pthread_self(), _name)); #endif } #endif // THREADAPI == THREADAPI_PTHREAD diff --git a/src/threading.h b/src/threading.h index 4114dba..8ebe805 100644 --- a/src/threading.h +++ b/src/threading.h @@ -255,5 +255,6 @@ void THREAD_KILL( THREAD_T* ref); void THREAD_SETNAME( char const* _name); void THREAD_MAKE_ASYNCH_CANCELLABLE(); void THREAD_SET_PRIORITY( int prio); +void THREAD_SET_AFFINITY( unsigned int aff); #endif // __threading_h__ -- cgit v1.2.3-55-g6feb