diff options
author | Benoit Germain <benoit.germain@ubisoft.com> | 2024-04-09 10:12:30 +0200 |
---|---|---|
committer | Benoit Germain <benoit.germain@ubisoft.com> | 2024-04-09 10:12:30 +0200 |
commit | 23f25f3a9d327153e4c16ca86d937ec334803a10 (patch) | |
tree | 110826adcf29554cd59768acdccf3de006e8a7f4 /src | |
parent | 9b5c27af793a08fd17d1fde93e9512e76536f484 (diff) | |
download | lanes-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.h | 2 | ||||
-rw-r--r-- | src/keeper.h | 2 | ||||
-rw-r--r-- | src/lanes.cpp | 32 | ||||
-rw-r--r-- | src/state.h | 2 | ||||
-rw-r--r-- | src/threading.cpp | 22 | ||||
-rw-r--r-- | src/threading.h | 24 | ||||
-rw-r--r-- | src/tools.h | 2 | ||||
-rw-r--r-- | src/universe.cpp | 29 | ||||
-rw-r--r-- | src/universe.h | 20 |
9 files changed, 67 insertions, 68 deletions
@@ -19,7 +19,7 @@ extern "C" { | |||
19 | #include <atomic> | 19 | #include <atomic> |
20 | 20 | ||
21 | // forwards | 21 | // forwards |
22 | struct Universe; | 22 | class Universe; |
23 | 23 | ||
24 | enum class LookupMode | 24 | enum 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 |
17 | enum class LookupMode; | 17 | enum class LookupMode; |
18 | struct Universe; | 18 | class Universe; |
19 | 19 | ||
20 | struct Keeper | 20 | struct 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 | ||
785 | LUAG_FUNC(set_thread_priority) | 785 | LUAG_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 |
6 | struct Universe; | 6 | class Universe; |
7 | 7 | ||
8 | void serialize_require(DEBUGSPEW_PARAM_COMMA(Universe* U) lua_State* L); | 8 | void 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 | ||
137 | void THREAD_SET_PRIORITY(int prio) | 131 | void 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 | ||
148 | void JTHREAD_SET_PRIORITY(std::jthread& thread_, int prio_) | 142 | void 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 | ||
371 | void THREAD_SET_PRIORITY(int prio) | 365 | void 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 | ||
386 | void JTHREAD_SET_PRIORITY(std::jthread& thread_, int prio_) | 380 | void 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) | ||
70 | extern volatile bool sudo; | ||
71 | # ifdef LINUX_SCHED_RR | ||
72 | # define THREAD_PRIO_MIN (sudo ? -3 : 0) | ||
73 | # else | ||
74 | static constexpr int THREAD_PRIO_MIN{ 0 }; | 62 | static constexpr int THREAD_PRIO_MIN{ 0 }; |
75 | #endif | ||
76 | # define THREAD_PRIO_MAX (sudo ? +3 : 0) | ||
77 | #else | 63 | #else |
78 | static constexpr int THREAD_PRIO_MIN{ -3 }; | 64 | static constexpr int THREAD_PRIO_MIN{ -3 }; |
79 | static constexpr int THREAD_PRIO_MAX{ +3 }; | ||
80 | #endif | 65 | #endif |
66 | static constexpr int THREAD_PRIO_MAX{ +3 }; | ||
81 | 67 | ||
82 | #endif // THREADAPI == THREADAPI_WINDOWS | 68 | #endif // THREADAPI == THREADAPI_PTHREAD |
83 | // ################################################################################################## | 69 | // ################################################################################################## |
84 | // ################################################################################################## | 70 | // ################################################################################################## |
85 | 71 | ||
86 | void THREAD_SETNAME(char const* _name); | 72 | void THREAD_SETNAME(char const* _name); |
87 | void THREAD_SET_PRIORITY(int prio); | 73 | void THREAD_SET_PRIORITY(int prio_, bool sudo_); |
88 | void THREAD_SET_AFFINITY(unsigned int aff); | 74 | void THREAD_SET_AFFINITY(unsigned int aff); |
89 | 75 | ||
90 | void JTHREAD_SET_PRIORITY(std::jthread& thread_, int prio_); | 76 | void 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 |
9 | struct Universe; | 9 | class 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 | ||
46 | Universe::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 |
47 | Universe* universe_create(lua_State* L) | 76 | Universe* 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() | 122 | class Universe |
123 | struct 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 | // ################################################################################################ |