Skip to content

Commit 3504761

Browse files
author
Mateusz Kopciński
committed
Initial changes for iOS compliance
1 parent c03b233 commit 3504761

File tree

9 files changed

+164
-237
lines changed

9 files changed

+164
-237
lines changed

apps/llm/app.json

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,11 @@
5858
"foregroundImage": "./assets/icons/adaptive-icon.png",
5959
"backgroundColor": "#ffffff"
6060
},
61-
"package": "com.anonymous.llm"
61+
"package": "com.anonymous.llm",
62+
"permissions": [
63+
"android.permission.READ_CALENDAR",
64+
"android.permission.WRITE_CALENDAR"
65+
]
6266
},
6367
"web": {
6468
"favicon": "./assets/icons/favicon.png"

apps/llm/ios/llm.xcodeproj/project.pbxproj

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,7 @@
180180
TargetAttributes = {
181181
13B07F861A680F5B00A75B9A = {
182182
LastSwiftMigration = 1250;
183+
ProvisioningStyle = Automatic;
183184
};
184185
};
185186
};
@@ -358,7 +359,10 @@
358359
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
359360
CLANG_ENABLE_MODULES = YES;
360361
CODE_SIGN_ENTITLEMENTS = llm/llm.entitlements;
362+
CODE_SIGN_IDENTITY = "Apple Development";
363+
CODE_SIGN_STYLE = Automatic;
361364
CURRENT_PROJECT_VERSION = 1;
365+
DEVELOPMENT_TEAM = J5FM626PE2;
362366
ENABLE_BITCODE = NO;
363367
GCC_PREPROCESSOR_DEFINITIONS = (
364368
"$(inherited)",
@@ -377,7 +381,7 @@
377381
"-lc++",
378382
);
379383
OTHER_SWIFT_FLAGS = "$(inherited) -D EXPO_CONFIGURATION_DEBUG";
380-
PRODUCT_BUNDLE_IDENTIFIER = com.anonymous.llm;
384+
PRODUCT_BUNDLE_IDENTIFIER = com.anonymous.llm2;
381385
PRODUCT_NAME = llm;
382386
SWIFT_OBJC_BRIDGING_HEADER = "llm/llm-Bridging-Header.h";
383387
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
@@ -394,7 +398,10 @@
394398
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
395399
CLANG_ENABLE_MODULES = YES;
396400
CODE_SIGN_ENTITLEMENTS = llm/llm.entitlements;
401+
CODE_SIGN_IDENTITY = "Apple Development";
402+
CODE_SIGN_STYLE = Automatic;
397403
CURRENT_PROJECT_VERSION = 1;
404+
DEVELOPMENT_TEAM = J5FM626PE2;
398405
INFOPLIST_FILE = llm/Info.plist;
399406
IPHONEOS_DEPLOYMENT_TARGET = 15.1;
400407
LD_RUNPATH_SEARCH_PATHS = (
@@ -408,7 +415,7 @@
408415
"-lc++",
409416
);
410417
OTHER_SWIFT_FLAGS = "$(inherited) -D EXPO_CONFIGURATION_RELEASE";
411-
PRODUCT_BUNDLE_IDENTIFIER = com.anonymous.llm;
418+
PRODUCT_BUNDLE_IDENTIFIER = com.anonymous.llm2;
412419
PRODUCT_NAME = llm;
413420
SWIFT_OBJC_BRIDGING_HEADER = "llm/llm-Bridging-Header.h";
414421
SWIFT_VERSION = 5.0;
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3+
<plist version="1.0">
4+
<dict>
5+
<key>IDEWorkspaceSharedSettings_AutocreateContextsIfNeeded</key>
6+
<false/>
7+
</dict>
8+
</plist>

packages/react-native-executorch/android/src/main/cpp/CMakeLists.txt

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -32,19 +32,6 @@ set(RN_VERSION_LINK_LIBRARIES
3232
ReactAndroid::reactnative
3333
)
3434

35-
# Dependencies:
36-
# ------- pthreadpool -------
37-
add_library(pthreadpool SHARED IMPORTED)
38-
set_target_properties(pthreadpool PROPERTIES
39-
IMPORTED_LOCATION "${LIBS_DIR}/pthreadpool/${ANDROID_ABI}/libpthreadpool.so"
40-
INTERFACE_INCLUDE_DIRECTORIES "${CMAKE_CURRENT_SOURCE_DIR}/../../../../../../third-party/executorch/backends/xnnpack/third-party/pthreadpool/include")
41-
42-
# ------- cpuinfo -------
43-
add_library(cpuinfo SHARED IMPORTED)
44-
set_target_properties(cpuinfo PROPERTIES
45-
IMPORTED_LOCATION "${LIBS_DIR}/cpuinfo/${ANDROID_ABI}/libcpuinfo.so"
46-
INTERFACE_INCLUDE_DIRECTORIES "${CMAKE_CURRENT_SOURCE_DIR}/../../../../../../third-party/executorch/backends/xnnpack/third-party/cpuinfo/include")
47-
4835
# ------- Executorch -------
4936

5037
add_library(executorch SHARED IMPORTED)

packages/react-native-executorch/common/rnexecutorch/GlobalThreadPool.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
#include "HighPerformanceThreadPool.h"
55
#include <memory>
66
#include <mutex>
7+
#include <rnexecutorch/Log.h>
78

89
class GlobalThreadPool {
910
private:
@@ -22,7 +23,8 @@ class GlobalThreadPool {
2223
numThreads = std::min(numThreads, size_t(4)); // Cap at 4 for mobile
2324
}
2425

25-
LOGI("Initializing global thread pool with %zu threads", numThreads);
26+
log(rnexecutorch::LOG_LEVEL::Info,
27+
"Initializing global thread pool with ", numThreads, " threads");
2628
instance =
2729
std::make_unique<HighPerformanceThreadPool>(numThreads, config);
2830
});

packages/react-native-executorch/common/rnexecutorch/HighPerformanceThreadPool.h

Lines changed: 73 additions & 93 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
#pragma once
33

44
#include <algorithm>
5-
#include <android/log.h>
65
#include <atomic>
76
#include <chrono>
87
#include <condition_variable>
@@ -18,21 +17,25 @@
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+
2834
enum class Priority { LOW, NORMAL, HIGH, REALTIME };
2935

3036
struct 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

3841
class 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, &param) != 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

321311
public:
@@ -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

packages/react-native-executorch/common/rnexecutorch/RnExecutorchInstaller.cpp

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -111,9 +111,6 @@ void RnExecutorchInstaller::injectJSIBindings(
111111
#endif
112112

113113
ThreadConfig config;
114-
config.pinToPerformanceCores = true;
115-
config.priority = Priority::HIGH;
116-
config.namePrefix = "NativeWorker";
117114
GlobalThreadPool::initialize(2, config);
118115
}
119116

0 commit comments

Comments
 (0)