Skip to content

Commit 2d33506

Browse files
committed
[Runtime] Don't use threading related APIs when building single threaded.
Mostly this consists of #if-ing out code that we don't need when running single threaded. rdar://84393438
1 parent 34267d7 commit 2d33506

File tree

6 files changed

+40
-10
lines changed

6 files changed

+40
-10
lines changed

include/swift/Runtime/ThreadLocal.h

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,13 +23,13 @@
2323

2424
/// SWIFT_RUNTIME_SUPPORTS_THREAD_LOCAL - Does the current configuration
2525
/// allow the use of SWIFT_RUNTIME_ATTRIBUTE_THREAD_LOCAL?
26-
#if defined(__APPLE__)
27-
// The pthread TLS APIs work better than C++ TLS on Apple platforms.
28-
#define SWIFT_RUNTIME_SUPPORTS_THREAD_LOCAL 0
29-
#elif defined(SWIFT_STDLIB_SINGLE_THREADED_RUNTIME)
26+
#if SWIFT_STDLIB_SINGLE_THREADED_RUNTIME
3027
// We define SWIFT_RUNTIME_ATTRIBUTE_THREAD_LOCAL to nothing in this
3128
// configuration and just use a global variable, so this is okay.
3229
#define SWIFT_RUNTIME_SUPPORTS_THREAD_LOCAL 1
30+
#elif defined(__APPLE__)
31+
// The pthread TLS APIs work better than C++ TLS on Apple platforms.
32+
#define SWIFT_RUNTIME_SUPPORTS_THREAD_LOCAL 0
3333
#elif __has_feature(tls)
3434
// If __has_feature reports that TLS is available, use it.
3535
#define SWIFT_RUNTIME_SUPPORTS_THREAD_LOCAL 1
@@ -43,7 +43,7 @@
4343

4444
/// SWIFT_RUNTIME_THREAD_LOCAL - Declare that something is a
4545
/// thread-local variable in the runtime.
46-
#if defined(SWIFT_STDLIB_SINGLE_THREADED_RUNTIME)
46+
#if SWIFT_STDLIB_SINGLE_THREADED_RUNTIME
4747
// In a single-threaded runtime, thread-locals are global.
4848
#define SWIFT_RUNTIME_ATTRIBUTE_THREAD_LOCAL
4949
#elif defined(__GNUC__)

include/swift/Runtime/VoucherShims.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,10 @@
2020
#include "Config.h"
2121

2222
// swift-corelibs-libdispatch has os/voucher_private.h but it doesn't work for
23-
// us yet, so only look for it on Apple platforms.
24-
#if __APPLE__ && __has_include(<os/voucher_private.h>)
23+
// us yet, so only look for it on Apple platforms. We also don't need vouchers
24+
// in the single threaded concurrency runtime.
25+
#if __APPLE__ && !SWIFT_STDLIB_SINGLE_THREADED_RUNTIME \
26+
&& __has_include(<os/voucher_private.h>)
2527
#define SWIFT_HAS_VOUCHER_HEADER 1
2628
#include <os/voucher_private.h>
2729
#endif

stdlib/cmake/modules/SwiftSource.cmake

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -306,6 +306,10 @@ function(_add_target_variant_swift_compile_flags
306306
list(APPEND result "-Xcc" "-DSWIFT_STDLIB_HAS_ENVIRON")
307307
endif()
308308

309+
if(SWIFT_STDLIB_SINGLE_THREADED_RUNTIME)
310+
list(APPEND result "-D" "SWIFT_STDLIB_SINGLE_THREADED_RUNTIME")
311+
endif()
312+
309313
set("${result_var_name}" "${result}" PARENT_SCOPE)
310314
endfunction()
311315

stdlib/public/Concurrency/Actor.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -288,7 +288,9 @@ static HANDLE __initialPthread = INVALID_HANDLE_VALUE;
288288
/// Determine whether we are currently executing on the main thread
289289
/// independently of whether we know that we are on the main actor.
290290
static bool isExecutingOnMainThread() {
291-
#if defined(__linux__)
291+
#if SWIFT_STDLIB_SINGLE_THREADED_RUNTIME
292+
return true;
293+
#elif defined(__linux__)
292294
return syscall(SYS_gettid) == getpid();
293295
#elif defined(_WIN32)
294296
if (__initialPthread == INVALID_HANDLE_VALUE) {
@@ -304,7 +306,9 @@ static bool isExecutingOnMainThread() {
304306
}
305307

306308
JobPriority swift::swift_task_getCurrentThreadPriority() {
307-
#if defined(__APPLE__)
309+
#if SWIFT_STDLIB_SINGLE_THREADED_RUNTIME
310+
return JobPriority::UserInitiated;
311+
#elif defined(__APPLE__)
308312
return static_cast<JobPriority>(qos_class_self());
309313
#else
310314
if (isExecutingOnMainThread())

stdlib/public/Concurrency/TaskGroup.cpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -279,8 +279,10 @@ class TaskGroupImpl: public TaskGroupTaskStatusRecord {
279279

280280
private:
281281

282+
#if !SWIFT_STDLIB_SINGLE_THREADED_RUNTIME
282283
// TODO: move to lockless via the status atomic (make readyQueue an mpsc_queue_t<ReadyQueueItem>)
283284
mutable std::mutex mutex;
285+
#endif
284286

285287
/// Used for queue management, counting number of waiting and ready tasks
286288
std::atomic <uint64_t> status;
@@ -559,7 +561,9 @@ void TaskGroupImpl::offer(AsyncTask *completedTask, AsyncContext *context) {
559561
assert(completedTask->groupChildFragment()->getGroup() == asAbstract(this));
560562
SWIFT_TASK_DEBUG_LOG("offer task %p to group %p", completedTask, this);
561563

564+
#if !SWIFT_STDLIB_SINGLE_THREADED_RUNTIME
562565
mutex.lock(); // TODO: remove fragment lock, and use status for synchronization
566+
#endif
563567

564568
// Immediately increment ready count and acquire the status
565569
// Examples:
@@ -597,7 +601,9 @@ void TaskGroupImpl::offer(AsyncTask *completedTask, AsyncContext *context) {
597601
// Run the task.
598602
auto result = PollResult::get(completedTask, hadErrorResult);
599603

604+
#if !SWIFT_STDLIB_SINGLE_THREADED_RUNTIME
600605
mutex.unlock(); // TODO: remove fragment lock, and use status for synchronization
606+
#endif
601607

602608
auto waitingContext =
603609
static_cast<TaskFutureWaitAsyncContext *>(
@@ -637,7 +643,9 @@ void TaskGroupImpl::offer(AsyncTask *completedTask, AsyncContext *context) {
637643
assert(completedTask == readyItem.getTask());
638644
assert(readyItem.getTask()->isFuture());
639645
readyQueue.enqueue(readyItem);
646+
#if !SWIFT_STDLIB_SINGLE_THREADED_RUNTIME
640647
mutex.unlock(); // TODO: remove fragment lock, and use status for synchronization
648+
#endif
641649
return;
642650
}
643651

@@ -722,7 +730,9 @@ static void swift_taskGroup_wait_next_throwingImpl(
722730
}
723731

724732
PollResult TaskGroupImpl::poll(AsyncTask *waitingTask) {
733+
#if !SWIFT_STDLIB_SINGLE_THREADED_RUNTIME
725734
mutex.lock(); // TODO: remove group lock, and use status for synchronization
735+
#endif
726736
SWIFT_TASK_DEBUG_LOG("poll group = %p", this);
727737
auto assumed = statusMarkWaitingAssumeAcquire();
728738

@@ -740,7 +750,9 @@ PollResult TaskGroupImpl::poll(AsyncTask *waitingTask) {
740750
statusRemoveWaiting();
741751
result.status = PollStatus::Empty;
742752
result.successType = this->successType;
753+
#if !SWIFT_STDLIB_SINGLE_THREADED_RUNTIME
743754
mutex.unlock(); // TODO: remove group lock, and use status for synchronization
755+
#endif
744756
return result;
745757
}
746758

@@ -787,7 +799,9 @@ PollResult TaskGroupImpl::poll(AsyncTask *waitingTask) {
787799
result.successType = futureFragment->getResultType();
788800
assert(result.retainedTask && "polled a task, it must be not null");
789801
_swift_tsan_acquire(static_cast<Job *>(result.retainedTask));
802+
#if !SWIFT_STDLIB_SINGLE_THREADED_RUNTIME
790803
mutex.unlock(); // TODO: remove fragment lock, and use status for synchronization
804+
#endif
791805
return result;
792806

793807
case ReadyStatus::Error:
@@ -798,15 +812,19 @@ PollResult TaskGroupImpl::poll(AsyncTask *waitingTask) {
798812
result.successType = nullptr;
799813
assert(result.retainedTask && "polled a task, it must be not null");
800814
_swift_tsan_acquire(static_cast<Job *>(result.retainedTask));
815+
#if !SWIFT_STDLIB_SINGLE_THREADED_RUNTIME
801816
mutex.unlock(); // TODO: remove fragment lock, and use status for synchronization
817+
#endif
802818
return result;
803819

804820
case ReadyStatus::Empty:
805821
result.status = PollStatus::Empty;
806822
result.storage = nullptr;
807823
result.retainedTask = nullptr;
808824
result.successType = this->successType;
825+
#if !SWIFT_STDLIB_SINGLE_THREADED_RUNTIME
809826
mutex.unlock(); // TODO: remove fragment lock, and use status for synchronization
827+
#endif
810828
return result;
811829
}
812830
assert(false && "must return result when status compare-and-swap was successful");
@@ -826,7 +844,9 @@ PollResult TaskGroupImpl::poll(AsyncTask *waitingTask) {
826844
waitHead, waitingTask,
827845
/*success*/ std::memory_order_release,
828846
/*failure*/ std::memory_order_acquire)) {
847+
#if !SWIFT_STDLIB_SINGLE_THREADED_RUNTIME
829848
mutex.unlock(); // TODO: remove fragment lock, and use status for synchronization
849+
#endif
830850
// no ready tasks, so we must wait.
831851
result.status = PollStatus::MustWait;
832852
_swift_task_clearCurrent();

utils/build-presets.ini

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2501,7 +2501,7 @@ verbose-build
25012501

25022502
[preset: mixin_stdlib_minimal]
25032503
enable-experimental-differentiable-programming=0
2504-
enable-experimental-concurrency=0
2504+
enable-experimental-concurrency=1
25052505
enable-experimental-distributed=0
25062506
build-swift-dynamic-sdk-overlay=0
25072507
build-swift-dynamic-stdlib=0

0 commit comments

Comments
 (0)