22#pragma once
33
44#include < algorithm>
5- #include < android/log.h>
65#include < atomic>
76#include < chrono>
87#include < condition_variable>
1817#include < sched.h>
1918#include < sys/resource.h>
2019#include < thread>
21- #include < unistd.h>
2220#include < vector>
2321
24- #define LOG_TAG " HPThreadPool"
25- #define LOGI (...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)
26- #define LOGW (...) __android_log_print(ANDROID_LOG_WARN, LOG_TAG, __VA_ARGS__)
27- #define LOGE (...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__)
22+ #ifdef __APPLE__
23+ #include < mach/mach.h>
24+ #include < pthread.h>
25+ #include < sys/syscall.h>
26+ #include < unistd.h>
27+ #endif
28+
29+ #ifdef __ANDROID__
30+ #include < sys/types.h>
31+ #include < unistd.h>
32+ #endif
33+
2834enum class Priority { LOW, NORMAL, HIGH, REALTIME };
2935
3036struct ThreadConfig {
3137 bool pinToPerformanceCores{true };
32- Priority priority{Priority::HIGH};
33- size_t stackSize{8 * 1024 * 1024 }; // 8MB default
34- std::optional<std::vector<int >> specificCores; // Pin to specific cores
35- std::string namePrefix{" HPWorker" };
38+ std::string namePrefix{" RN_ET_Worker" };
3639};
3740
3841class HighPerformanceThreadPool {
@@ -75,11 +78,8 @@ class HighPerformanceThreadPool {
7578 std::chrono::steady_clock::time_point enqueueTime;
7679
7780 bool operator <(const WorkItem &other) const {
78- // Higher priority first, then earlier enqueue time
79- if (priority != other.priority ) {
80- return priority < other.priority ;
81- }
82- return enqueueTime > other.enqueueTime ;
81+ return priority != other.priority ? priority < other.priority
82+ : enqueueTime > other.enqueueTime ;
8383 }
8484 };
8585
@@ -148,38 +148,65 @@ class HighPerformanceThreadPool {
148148 for (const auto &core : cores) {
149149 if (core.maxFreq >= threshold) {
150150 performanceCores.push_back (core.id );
151- log (rnexecutorch::LOG_LEVEL::Error, " Performance core: %d (%.2f GHz) " ,
152- core.id , core. maxFreq / 1000000.0 );
151+ log (rnexecutorch::LOG_LEVEL::Error, " Performance core:" , core. id , " ( " ,
152+ core.maxFreq / 1000000.0 , " GHz) " );
153153 } else {
154154 efficiencyCores.push_back (core.id );
155- log (rnexecutorch::LOG_LEVEL::Error, " Efficiency core: %d (%.2f GHz) " ,
156- core.id , core. maxFreq / 1000000.0 );
155+ log (rnexecutorch::LOG_LEVEL::Error, " Efficiency core:" , core. id , " ( " ,
156+ core.maxFreq / 1000000.0 , " GHz) " );
157157 }
158158 }
159159 }
160160
161+ inline uint64_t getCurrentThreadId () {
162+ #ifdef __ANDROID__
163+ return gettid ();
164+ #elif defined(__APPLE__)
165+ // Option 1: pthread_threadid_np (recommended)
166+ uint64_t tid;
167+ pthread_threadid_np (pthread_self (), &tid);
168+ return tid;
169+
170+ // Option 2: syscall (deprecated but works)
171+ // return syscall(SYS_thread_selfid);
172+
173+ // Option 3: Mach thread ID
174+ // return mach_thread_self();
175+
176+ // Option 4: pthread_self as number (not unique across processes)
177+ // return (uint64_t)pthread_self();
178+ #else
179+ return -1 ;
180+ #endif
181+ }
182+
183+ inline void setCurrentThreadName (const std::string &name) {
184+ #ifdef __ANDROID__
185+ pthread_setname_np (pthread_self (), name.c_str ());
186+ #elif defined(__APPLE__)
187+ pthread_setname_np (name.c_str ()); // Note: no thread parameter on iOS
188+ #endif
189+ }
190+
161191 void configureThread (int workerIndex) {
162192 // Set thread name
163193 std::string threadName = config.namePrefix + std::to_string (workerIndex);
164- pthread_setname_np (pthread_self (), threadName.c_str ());
165-
166- // Configure CPU affinity
167- if (config.specificCores .has_value ()) {
168- // Pin to specific cores provided by user
169- setCPUAffinity (config.specificCores .value ());
170- } else if (config.pinToPerformanceCores && !performanceCores.empty ()) {
171- // Pin to performance cores
194+ setCurrentThreadName (threadName.c_str ());
195+
196+ // Pin to performance cores
197+ if (config.pinToPerformanceCores && !performanceCores.empty ()) {
172198 setCPUAffinity (performanceCores);
173199 }
174200
175201 // Set thread priority
176- setThreadPriority (config. priority );
202+ setThreadPriority ();
177203
178- log (rnexecutorch::LOG_LEVEL::Error, " Worker %d configured: %s " , workerIndex,
179- threadName.c_str ());
204+ log (rnexecutorch::LOG_LEVEL::Error, " Worker " , workerIndex,
205+ " configured: " , threadName.c_str ());
180206 }
181207
182208 void setCPUAffinity (const std::vector<int > &cores) {
209+ #ifdef __ANDROID__
183210 if (cores.empty ()) {
184211 log (rnexecutorch::LOG_LEVEL::Error,
185212 " No cores specified for affinity setting" );
@@ -190,8 +217,8 @@ class HighPerformanceThreadPool {
190217 int maxCores = std::thread::hardware_concurrency ();
191218 for (int core : cores) {
192219 if (core < 0 || core >= maxCores) {
193- log (rnexecutorch::LOG_LEVEL::Error, " Invalid core index %d (max: %d) " ,
194- core , maxCores - 1 );
220+ log (rnexecutorch::LOG_LEVEL::Error, " Invalid core index " , core ,
221+ " (max: " , maxCores - 1 , " ) " );
195222 return ;
196223 }
197224 }
@@ -203,62 +230,24 @@ class HighPerformanceThreadPool {
203230 CPU_SET (core, &cpuset);
204231 }
205232
206- // Use sched_setaffinity for Android compatibility
207- pid_t tid = gettid ();
233+ pid_t tid = getCurrentThreadId ();
208234 log (rnexecutorch::LOG_LEVEL::Info, " Thread id " , tid);
209235 if (sched_setaffinity (tid, sizeof (cpuset), &cpuset) == 0 ) {
210- std::string coreList;
211- for (size_t i = 0 ; i < cores.size (); ++i) {
212- coreList += std::to_string (cores[i]);
213- if (i < cores.size () - 1 )
214- coreList += " ," ;
215- }
216- log (rnexecutorch::LOG_LEVEL::Info, " Thread pinned to cores: %s" ,
217- coreList.c_str ());
236+ log (rnexecutorch::LOG_LEVEL::Info, " Thread pinned to cores: " , cores);
218237 } else {
219238 log (rnexecutorch::LOG_LEVEL::Error,
220- " Failed to set CPU affinity (error: %d). Continuing without "
221- " affinity." ,
222- errno);
239+ " Failed to set CPU affinity (error: " , errno,
240+ " ). Continuing without affinity." );
223241 }
242+ #endif
224243 }
225244
226- void setThreadPriority (Priority priority) {
227- int nice_value = 0 ;
228- int sched_policy = SCHED_OTHER;
229- int sched_priority = 0 ;
230-
231- switch (priority) {
232- case Priority::LOW:
233- nice_value = 10 ;
234- break ;
235- case Priority::NORMAL:
236- nice_value = 0 ;
237- break ;
238- case Priority::HIGH:
239- nice_value = -10 ;
240- sched_policy = SCHED_FIFO;
241- sched_priority = sched_get_priority_min (SCHED_FIFO);
242- break ;
243- case Priority::REALTIME:
244- nice_value = -20 ;
245- sched_policy = SCHED_FIFO;
246- sched_priority = sched_get_priority_max (SCHED_FIFO) - 1 ;
247- break ;
248- }
249-
250- // Try to set real-time scheduling
251- if (sched_policy != SCHED_OTHER) {
252- struct sched_param param;
253- param.sched_priority = sched_priority;
254- if (pthread_setschedparam (pthread_self (), sched_policy, ¶m) != 0 ) {
255- log (rnexecutorch::LOG_LEVEL::Error,
256- " Failed to set real-time scheduling, falling back to nice value" );
257- }
258- return ;
259- }
245+ void setThreadPriority () {
246+ // pthread_setschedparam doesn't work on android because permissions reasons
247+ // and in general does not provide visible improvements on iOS
260248
261249 // Set nice value as fallback or additional priority boost
250+ const int nice_value = 0 ;
262251 if (setpriority (PRIO_PROCESS, 0 , nice_value) != 0 ) {
263252 log (rnexecutorch::LOG_LEVEL::Error, " Failed to set nice value" );
264253 } else {
@@ -300,7 +289,7 @@ class HighPerformanceThreadPool {
300289 item.task ->execute ();
301290 stats.tasksCompleted ++;
302291 } catch (const std::exception &e) {
303- LOGE ( " Task failed: %s " , e.what ());
292+ log (rnexecutorch::LOG_LEVEL::Error, " Task failed: " , e.what ());
304293 stats.tasksFailed ++;
305294 }
306295
@@ -315,7 +304,8 @@ class HighPerformanceThreadPool {
315304 totalTasksProcessed++;
316305 }
317306
318- LOGI (" Worker %d shutting down" , workerIndex);
307+ log (rnexecutorch::LOG_LEVEL::Error, " Worker " , workerIndex,
308+ " shutting down" );
319309 }
320310
321311public:
@@ -335,8 +325,8 @@ class HighPerformanceThreadPool {
335325 workers.emplace_back (&HighPerformanceThreadPool::workerThread, this , i);
336326 }
337327
338- log (rnexecutorch::LOG_LEVEL::Error,
339- " Thread pool initialized with %zu workers" , numThreads);
328+ log (rnexecutorch::LOG_LEVEL::Error, " Thread pool initialized with " ,
329+ numThreads, " workers " , numThreads);
340330 }
341331
342332 ~HighPerformanceThreadPool () { shutdown (); }
@@ -408,16 +398,6 @@ class HighPerformanceThreadPool {
408398 worker.join ();
409399 }
410400 }
411-
412- LOGI (" Thread pool shut down. Stats: completed=%llu, failed=%llu, "
413- " avg_wait=%.1fms, avg_exec=%.1fms" ,
414- stats.tasksCompleted .load (), stats.tasksFailed .load (),
415- stats.tasksCompleted > 0
416- ? (double )stats.totalWaitTimeMs / stats.tasksCompleted
417- : 0 ,
418- stats.tasksCompleted > 0
419- ? (double )stats.totalExecutionTimeMs / stats.tasksCompleted
420- : 0 );
421401 }
422402
423403 // Get pool statistics
0 commit comments