aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorBenoit Germain <benoit.germain@ubisoft.com>2024-04-09 10:12:30 +0200
committerBenoit Germain <benoit.germain@ubisoft.com>2024-04-09 10:12:30 +0200
commit23f25f3a9d327153e4c16ca86d937ec334803a10 (patch)
tree110826adcf29554cd59768acdccf3de006e8a7f4 /src
parent9b5c27af793a08fd17d1fde93e9512e76536f484 (diff)
downloadlanes-23f25f3a9d327153e4c16ca86d937ec334803a10.tar.gz
lanes-23f25f3a9d327153e4c16ca86d937ec334803a10.tar.bz2
lanes-23f25f3a9d327153e4c16ca86d937ec334803a10.zip
C++ migration: still more threading code cleanup. 'sudo' global moved in the Universe
Diffstat (limited to 'src')
-rw-r--r--src/deep.h2
-rw-r--r--src/keeper.h2
-rw-r--r--src/lanes.cpp32
-rw-r--r--src/state.h2
-rw-r--r--src/threading.cpp22
-rw-r--r--src/threading.h24
-rw-r--r--src/tools.h2
-rw-r--r--src/universe.cpp29
-rw-r--r--src/universe.h20
9 files changed, 67 insertions, 68 deletions
diff --git a/src/deep.h b/src/deep.h
index 1799cf0..c09af23 100644
--- a/src/deep.h
+++ b/src/deep.h
@@ -19,7 +19,7 @@ extern "C" {
19#include <atomic> 19#include <atomic>
20 20
21// forwards 21// forwards
22struct Universe; 22class Universe;
23 23
24enum class LookupMode 24enum class LookupMode
25{ 25{
diff --git a/src/keeper.h b/src/keeper.h
index 931c1d5..ba5a57b 100644
--- a/src/keeper.h
+++ b/src/keeper.h
@@ -15,7 +15,7 @@ extern "C" {
15 15
16// forwards 16// forwards
17enum class LookupMode; 17enum class LookupMode;
18struct Universe; 18class Universe;
19 19
20struct Keeper 20struct Keeper
21{ 21{
diff --git a/src/lanes.cpp b/src/lanes.cpp
index f5d5130..28f95f6 100644
--- a/src/lanes.cpp
+++ b/src/lanes.cpp
@@ -136,7 +136,7 @@ void Lane::startThread(int priority_)
136 m_thread = std::jthread([this]() { lane_main(this); }); 136 m_thread = std::jthread([this]() { lane_main(this); });
137 if (priority_ != THREAD_PRIO_DEFAULT) 137 if (priority_ != THREAD_PRIO_DEFAULT)
138 { 138 {
139 JTHREAD_SET_PRIORITY(m_thread, priority_); 139 JTHREAD_SET_PRIORITY(m_thread, priority_, U->m_sudo);
140 } 140 }
141} 141}
142 142
@@ -784,7 +784,7 @@ LUAG_FUNC(get_debug_threadname)
784 784
785LUAG_FUNC(set_thread_priority) 785LUAG_FUNC(set_thread_priority)
786{ 786{
787 int const prio{ (int) luaL_checkinteger(L, 1) }; 787 lua_Integer const prio{ luaL_checkinteger(L, 1) };
788 // public Lanes API accepts a generic range -3/+3 788 // public Lanes API accepts a generic range -3/+3
789 // that will be remapped into the platform-specific scheduler priority scheme 789 // that will be remapped into the platform-specific scheduler priority scheme
790 // On some platforms, -3 is equivalent to -2 and +3 to +2 790 // On some platforms, -3 is equivalent to -2 and +3 to +2
@@ -792,7 +792,7 @@ LUAG_FUNC(set_thread_priority)
792 { 792 {
793 return luaL_error(L, "priority out of range: %d..+%d (%d)", THREAD_PRIO_MIN, THREAD_PRIO_MAX, prio); 793 return luaL_error(L, "priority out of range: %d..+%d (%d)", THREAD_PRIO_MIN, THREAD_PRIO_MAX, prio);
794 } 794 }
795 THREAD_SET_PRIORITY(prio); 795 THREAD_SET_PRIORITY(static_cast<int>(prio), universe_get(L)->m_sudo);
796 return 0; 796 return 0;
797} 797}
798 798
@@ -1746,32 +1746,6 @@ static void init_once_LOCKED( void)
1746#if (defined PLATFORM_OSX) && (defined _UTILBINDTHREADTOCPU) 1746#if (defined PLATFORM_OSX) && (defined _UTILBINDTHREADTOCPU)
1747 chudInitialize(); 1747 chudInitialize();
1748#endif 1748#endif
1749
1750 //---
1751 // Linux needs SCHED_RR to change thread priorities, and that is only
1752 // allowed for sudo'ers. SCHED_OTHER (default) has no priorities.
1753 // SCHED_OTHER threads are always lower priority than SCHED_RR.
1754 //
1755 // ^-- those apply to 2.6 kernel. IF **wishful thinking** these
1756 // constraints will change in the future, non-sudo priorities can
1757 // be enabled also for Linux.
1758 //
1759#ifdef PLATFORM_LINUX
1760 sudo = (geteuid() == 0); // we are root?
1761
1762 // If lower priorities (-2..-1) are wanted, we need to lift the main
1763 // thread to SCHED_RR and 50 (medium) level. Otherwise, we're always below
1764 // the launched threads (even -2).
1765 //
1766#ifdef LINUX_SCHED_RR
1767 if (sudo)
1768 {
1769 struct sched_param sp;
1770 sp.sched_priority = _PRIO_0;
1771 PT_CALL(pthread_setschedparam(pthread_self(), SCHED_RR, &sp));
1772 }
1773#endif // LINUX_SCHED_RR
1774#endif // PLATFORM_LINUX
1775} 1749}
1776 1750
1777// ################################################################################################# 1751// #################################################################################################
diff --git a/src/state.h b/src/state.h
index 0e35e89..0e069da 100644
--- a/src/state.h
+++ b/src/state.h
@@ -3,7 +3,7 @@
3#include "macros_and_utils.h" 3#include "macros_and_utils.h"
4 4
5// forwards 5// forwards
6struct Universe; 6class Universe;
7 7
8void serialize_require(DEBUGSPEW_PARAM_COMMA(Universe* U) lua_State* L); 8void serialize_require(DEBUGSPEW_PARAM_COMMA(Universe* U) lua_State* L);
9 9
diff --git a/src/threading.cpp b/src/threading.cpp
index aab2fa7..4d210d6 100644
--- a/src/threading.cpp
+++ b/src/threading.cpp
@@ -65,12 +65,6 @@ THE SOFTWARE.
65# include <unistd.h> 65# include <unistd.h>
66#endif 66#endif
67 67
68/* Linux needs to check, whether it's been run as root
69*/
70#ifdef PLATFORM_LINUX
71 volatile bool sudo;
72#endif
73
74#ifdef PLATFORM_OSX 68#ifdef PLATFORM_OSX
75# include "threading_osx.h" 69# include "threading_osx.h"
76#endif 70#endif
@@ -134,10 +128,10 @@ static int const gs_prio_remap[] =
134 128
135// ############################################################################################### 129// ###############################################################################################
136 130
137void THREAD_SET_PRIORITY(int prio) 131void THREAD_SET_PRIORITY(int prio_, [[maybe_unused]] bool sudo_)
138{ 132{
139 // prio range [-3,+3] was checked by the caller 133 // prio range [-3,+3] was checked by the caller
140 if (!SetThreadPriority(GetCurrentThread(), gs_prio_remap[prio + 3])) 134 if (!SetThreadPriority(GetCurrentThread(), gs_prio_remap[prio_ + 3]))
141 { 135 {
142 FAIL("THREAD_SET_PRIORITY", GetLastError()); 136 FAIL("THREAD_SET_PRIORITY", GetLastError());
143 } 137 }
@@ -145,7 +139,7 @@ void THREAD_SET_PRIORITY(int prio)
145 139
146// ############################################################################################### 140// ###############################################################################################
147 141
148void JTHREAD_SET_PRIORITY(std::jthread& thread_, int prio_) 142void JTHREAD_SET_PRIORITY(std::jthread& thread_, int prio_, [[maybe_unused]] bool sudo_)
149{ 143{
150 // prio range [-3,+3] was checked by the caller 144 // prio range [-3,+3] was checked by the caller
151 if (!SetThreadPriority(thread_.native_handle(), gs_prio_remap[prio_ + 3])) 145 if (!SetThreadPriority(thread_.native_handle(), gs_prio_remap[prio_ + 3]))
@@ -368,25 +362,25 @@ static int select_prio(int prio /* -3..+3 */)
368 return gs_prio_remap[prio + 3]; 362 return gs_prio_remap[prio + 3];
369} 363}
370 364
371void THREAD_SET_PRIORITY(int prio) 365void THREAD_SET_PRIORITY(int prio_, [[maybe_unused]] bool sudo_)
372{ 366{
373#ifdef PLATFORM_LINUX 367#ifdef PLATFORM_LINUX
374 if (!sudo) // only root-privileged process can change priorities 368 if (!sudo_) // only root-privileged process can change priorities
375 return; 369 return;
376#endif // PLATFORM_LINUX 370#endif // PLATFORM_LINUX
377 371
378 struct sched_param sp; 372 struct sched_param sp;
379 // prio range [-3,+3] was checked by the caller 373 // prio range [-3,+3] was checked by the caller
380 sp.sched_priority = gs_prio_remap[prio + 3]; 374 sp.sched_priority = gs_prio_remap[prio_ + 3];
381 PT_CALL(pthread_setschedparam(pthread_self(), _PRIO_MODE, &sp)); 375 PT_CALL(pthread_setschedparam(pthread_self(), _PRIO_MODE, &sp));
382} 376}
383 377
384// ################################################################################################# 378// #################################################################################################
385 379
386void JTHREAD_SET_PRIORITY(std::jthread& thread_, int prio_) 380void JTHREAD_SET_PRIORITY(std::jthread& thread_, int prio_, [[maybe_unused]] bool sudo_)
387{ 381{
388#ifdef PLATFORM_LINUX 382#ifdef PLATFORM_LINUX
389 if (!sudo) // only root-privileged process can change priorities 383 if (!sudo_) // only root-privileged process can change priorities
390 return; 384 return;
391#endif // PLATFORM_LINUX 385#endif // PLATFORM_LINUX
392 386
diff --git a/src/threading.h b/src/threading.h
index c443c82..f38b2de 100644
--- a/src/threading.h
+++ b/src/threading.h
@@ -58,33 +58,19 @@ static constexpr int THREAD_PRIO_MAX{ +3 };
58#endif // PLATFORM_WIN32 58#endif // PLATFORM_WIN32
59#include <pthread.h> 59#include <pthread.h>
60 60
61// Yield is non-portable: 61#if defined(PLATFORM_LINUX) && !defined(LINUX_SCHED_RR)
62//
63// OS X 10.4.8/9 has pthread_yield_np()
64// Linux 2.4 has pthread_yield() if _GNU_SOURCE is #defined
65// FreeBSD 6.2 has pthread_yield()
66// ...
67//
68
69#if defined(PLATFORM_LINUX)
70extern volatile bool sudo;
71# ifdef LINUX_SCHED_RR
72# define THREAD_PRIO_MIN (sudo ? -3 : 0)
73# else
74static constexpr int THREAD_PRIO_MIN{ 0 }; 62static constexpr int THREAD_PRIO_MIN{ 0 };
75#endif
76# define THREAD_PRIO_MAX (sudo ? +3 : 0)
77#else 63#else
78static constexpr int THREAD_PRIO_MIN{ -3 }; 64static constexpr int THREAD_PRIO_MIN{ -3 };
79static constexpr int THREAD_PRIO_MAX{ +3 };
80#endif 65#endif
66static constexpr int THREAD_PRIO_MAX{ +3 };
81 67
82#endif // THREADAPI == THREADAPI_WINDOWS 68#endif // THREADAPI == THREADAPI_PTHREAD
83// ################################################################################################## 69// ##################################################################################################
84// ################################################################################################## 70// ##################################################################################################
85 71
86void THREAD_SETNAME(char const* _name); 72void THREAD_SETNAME(char const* _name);
87void THREAD_SET_PRIORITY(int prio); 73void THREAD_SET_PRIORITY(int prio_, bool sudo_);
88void THREAD_SET_AFFINITY(unsigned int aff); 74void THREAD_SET_AFFINITY(unsigned int aff);
89 75
90void JTHREAD_SET_PRIORITY(std::jthread& thread_, int prio_); 76void JTHREAD_SET_PRIORITY(std::jthread& thread_, int prio_, bool sudo_);
diff --git a/src/tools.h b/src/tools.h
index c1a8534..7d9aaab 100644
--- a/src/tools.h
+++ b/src/tools.h
@@ -6,7 +6,7 @@
6#include "macros_and_utils.h" 6#include "macros_and_utils.h"
7 7
8// forwards 8// forwards
9struct Universe; 9class Universe;
10 10
11// ################################################################################################ 11// ################################################################################################
12 12
diff --git a/src/universe.cpp b/src/universe.cpp
index 66da147..290e547 100644
--- a/src/universe.cpp
+++ b/src/universe.cpp
@@ -43,6 +43,35 @@ static constexpr UniqueKey UNIVERSE_LIGHT_REGKEY{ 0x3663C07C742CEB81ull };
43 43
44// ################################################################################################ 44// ################################################################################################
45 45
46Universe::Universe()
47{
48 //---
49 // Linux needs SCHED_RR to change thread priorities, and that is only
50 // allowed for sudo'ers. SCHED_OTHER (default) has no priorities.
51 // SCHED_OTHER threads are always lower priority than SCHED_RR.
52 //
53 // ^-- those apply to 2.6 kernel. IF **wishful thinking** these
54 // constraints will change in the future, non-sudo priorities can
55 // be enabled also for Linux.
56 //
57#ifdef PLATFORM_LINUX
58 // If lower priorities (-2..-1) are wanted, we need to lift the main
59 // thread to SCHED_RR and 50 (medium) level. Otherwise, we're always below
60 // the launched threads (even -2).
61 //
62#ifdef LINUX_SCHED_RR
63 if (m_sudo)
64 {
65 struct sched_param sp;
66 sp.sched_priority = _PRIO_0;
67 PT_CALL(pthread_setschedparam(pthread_self(), SCHED_RR, &sp));
68 }
69#endif // LINUX_SCHED_RR
70#endif // PLATFORM_LINUX
71}
72
73// ################################################################################################
74
46// only called from the master state 75// only called from the master state
47Universe* universe_create(lua_State* L) 76Universe* universe_create(lua_State* L)
48{ 77{
diff --git a/src/universe.h b/src/universe.h
index 38885cb..f4211af 100644
--- a/src/universe.h
+++ b/src/universe.h
@@ -119,9 +119,17 @@ class ProtectedAllocator : public AllocatorDefinition
119 119
120// everything regarding the Lanes universe is stored in that global structure 120// everything regarding the Lanes universe is stored in that global structure
121// held as a full userdata in the master Lua state that required it for the first time 121// held as a full userdata in the master Lua state that required it for the first time
122// don't forget to initialize all members in LG_configure() 122class Universe
123struct Universe
124{ 123{
124 public:
125
126#ifdef PLATFORM_LINUX
127 // Linux needs to check, whether it's been run as root
128 bool const m_sudo{ geteuid() == 0 };
129#else
130 bool const m_sudo{ false };
131#endif // PLATFORM_LINUX
132
125 // for verbose errors 133 // for verbose errors
126 bool verboseErrors{ false }; 134 bool verboseErrors{ false };
127 135
@@ -155,6 +163,7 @@ struct Universe
155 // require() serialization 163 // require() serialization
156 std::recursive_mutex require_cs; 164 std::recursive_mutex require_cs;
157 165
166 // metatable unique identifiers
158 std::atomic<lua_Integer> next_mt_id{ 1 }; 167 std::atomic<lua_Integer> next_mt_id{ 1 };
159 168
160#if USE_DEBUG_SPEW() 169#if USE_DEBUG_SPEW()
@@ -165,6 +174,13 @@ struct Universe
165 // After a lane has removed itself from the chain, it still performs some processing. 174 // After a lane has removed itself from the chain, it still performs some processing.
166 // The terminal desinit sequence should wait for all such processing to terminate before force-killing threads 175 // The terminal desinit sequence should wait for all such processing to terminate before force-killing threads
167 std::atomic<int> selfdestructing_count{ 0 }; 176 std::atomic<int> selfdestructing_count{ 0 };
177
178 Universe();
179 ~Universe() = default;
180 Universe(Universe const&) = delete;
181 Universe(Universe&&) = delete;
182 Universe& operator=(Universe const&) = delete;
183 Universe& operator=(Universe&&) = delete;
168}; 184};
169 185
170// ################################################################################################ 186// ################################################################################################