Skip to content

Commit 56da0f5

Browse files
Eliminate fakepthread dependency (#27)
* [WASM] Minimize dependences of pthread * [WASM] Built fakepthread as a part of swift project * [WASM] Always build WasiPthread as static * [WASM] Fix to emit libswiftWasiPthread.a in swift_static * [WASM] Remove unused header file
1 parent 08a31af commit 56da0f5

18 files changed

+334
-7
lines changed

include/swift/Basic/Lazy.h

+10
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,18 @@
1616
#include <memory>
1717
#ifdef __APPLE__
1818
#include <dispatch/dispatch.h>
19+
#elif defined(__wasi__)
20+
// No pthread on wasi
1921
#else
2022
#include <mutex>
2123
#endif
2224
#include "swift/Basic/Malloc.h"
2325
#include "swift/Basic/type_traits.h"
2426

27+
#ifdef __wasi__
28+
void wasi_polyfill_call_once(int *flag, void *context, void (*func)(void *));
29+
#endif
30+
2531
namespace swift {
2632

2733
#ifdef __APPLE__
@@ -36,6 +42,10 @@ namespace swift {
3642
using OnceToken_t = unsigned long;
3743
# define SWIFT_ONCE_F(TOKEN, FUNC, CONTEXT) \
3844
_swift_once_f(&TOKEN, CONTEXT, FUNC)
45+
#elif defined(__wasi__)
46+
using OnceToken_t = int;
47+
# define SWIFT_ONCE_F(TOKEN, FUNC, CONTEXT) \
48+
::wasi_polyfill_call_once(&TOKEN, CONTEXT, FUNC)
3949
#else
4050
using OnceToken_t = std::once_flag;
4151
# define SWIFT_ONCE_F(TOKEN, FUNC, CONTEXT) \

include/swift/Runtime/Mutex.h

+3-1
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,12 @@
2020

2121
#include <type_traits>
2222

23-
#if (defined(__APPLE__) || defined(__linux__) || defined(__CYGWIN__) || defined(__FreeBSD__) || defined(__HAIKU__) || defined(__wasi__))
23+
#if (defined(__APPLE__) || defined(__linux__) || defined(__CYGWIN__) || defined(__FreeBSD__) || defined(__HAIKU__))
2424
#include "swift/Runtime/MutexPThread.h"
2525
#elif defined(_WIN32)
2626
#include "swift/Runtime/MutexWin32.h"
27+
#elif defined(__wasi__)
28+
#include "swift/Runtime/MutexWASI.h"
2729
#else
2830
#error "Implement equivalent of MutexPThread.h/cpp for your platform."
2931
#endif

include/swift/Runtime/MutexWASI.h

+66
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
//===--- MutexWin32.h - -----------------------------------------*- C++ -*-===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See https://swift.org/LICENSE.txt for license information
9+
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
//
11+
//===----------------------------------------------------------------------===//
12+
//
13+
// Mutex, ConditionVariable, Read/Write lock, and Scoped lock implementations
14+
// using Windows Slim Reader/Writer Locks and Conditional Variables.
15+
//
16+
//===----------------------------------------------------------------------===//
17+
18+
#ifndef SWIFT_RUNTIME_MUTEX_WASI_H
19+
#define SWIFT_RUNTIME_MUTEX_WASI_H
20+
21+
namespace swift {
22+
23+
typedef void* ConditionHandle;
24+
typedef void* MutexHandle;
25+
typedef void* ReadWriteLockHandle;
26+
27+
#define SWIFT_CONDITION_SUPPORTS_CONSTEXPR 1
28+
#define SWIFT_MUTEX_SUPPORTS_CONSTEXPR 1
29+
#define SWIFT_READWRITELOCK_SUPPORTS_CONSTEXPR 1
30+
31+
struct ConditionPlatformHelper {
32+
static constexpr ConditionHandle staticInit() {
33+
return nullptr;
34+
};
35+
static void init(ConditionHandle &condition) {}
36+
static void destroy(ConditionHandle &condition) {}
37+
static void notifyOne(ConditionHandle &condition) {}
38+
static void notifyAll(ConditionHandle &condition) {}
39+
static void wait(ConditionHandle &condition, MutexHandle &mutex);
40+
};
41+
42+
struct MutexPlatformHelper {
43+
static constexpr MutexHandle staticInit() { return nullptr; }
44+
static void init(MutexHandle &mutex, bool checked = false) {}
45+
static void destroy(MutexHandle &mutex) {}
46+
static void lock(MutexHandle &mutex) {}
47+
static void unlock(MutexHandle &mutex) {}
48+
static bool try_lock(MutexHandle &mutex) { return true; }
49+
static void unsafeLock(MutexHandle &mutex) {}
50+
static void unsafeUnlock(MutexHandle &mutex) {}
51+
};
52+
53+
struct ReadWriteLockPlatformHelper {
54+
static constexpr ReadWriteLockHandle staticInit() { return nullptr; }
55+
static void init(ReadWriteLockHandle &rwlock) {}
56+
static void destroy(ReadWriteLockHandle &rwlock) {}
57+
static void readLock(ReadWriteLockHandle &rwlock) {}
58+
static bool try_readLock(ReadWriteLockHandle &rwlock) { return true; }
59+
static void readUnlock(ReadWriteLockHandle &rwlock) {}
60+
static void writeLock(ReadWriteLockHandle &rwlock) {}
61+
static bool try_writeLock(ReadWriteLockHandle &rwlock) { return true; }
62+
static void writeUnlock(ReadWriteLockHandle &rwlock) {}
63+
};
64+
}
65+
66+
#endif

lib/ClangImporter/ClangImporter.cpp

+4
Original file line numberDiff line numberDiff line change
@@ -598,6 +598,10 @@ getNormalInvocationArguments(std::vector<std::string> &invocationArgStrs,
598598
});
599599
}
600600

601+
if (triple.isOSWASI()) {
602+
invocationArgStrs.insert(invocationArgStrs.end(), {"-D_WASI_EMULATED_MMAN"});
603+
}
604+
601605
if (triple.isOSWindows()) {
602606
switch (triple.getArch()) {
603607
default: llvm_unreachable("unsupported Windows architecture");

stdlib/private/SwiftPrivateThreadExtras/SwiftPrivateThreadExtras.swift

+6
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,9 @@ public func _stdlib_thread_create_block<Argument, Result>(
9898
} else {
9999
return (0, ThreadHandle(bitPattern: threadID))
100100
}
101+
#elseif os(WASI)
102+
// WASI environment has a only single thread
103+
return (0, nil)
101104
#else
102105
var threadID = _make_pthread_t()
103106
let result = pthread_create(&threadID, nil,
@@ -128,6 +131,9 @@ public func _stdlib_thread_join<Result>(
128131
} else {
129132
return (CInt(result), nil)
130133
}
134+
#elseif os(WASI)
135+
// WASI environment has a only single thread
136+
return (0, nil)
131137
#else
132138
var threadResultRawPtr: UnsafeMutableRawPointer?
133139
let result = pthread_join(thread, &threadResultRawPtr)

stdlib/private/SwiftPrivateThreadExtras/ThreadBarriers.swift

+15
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@ public struct _stdlib_thread_barrier_t {
3636
#elseif os(Cygwin) || os(FreeBSD)
3737
var mutex: UnsafeMutablePointer<pthread_mutex_t?>?
3838
var cond: UnsafeMutablePointer<pthread_cond_t?>?
39+
#elseif os(WASI)
40+
// No pthread for WASI
3941
#else
4042
var mutex: UnsafeMutablePointer<pthread_mutex_t>?
4143
var cond: UnsafeMutablePointer<pthread_cond_t>?
@@ -67,6 +69,8 @@ public func _stdlib_thread_barrier_init(
6769

6870
barrier.pointee.cond = UnsafeMutablePointer.allocate(capacity: 1)
6971
InitializeConditionVariable(barrier.pointee.cond!)
72+
#elseif os(WASI)
73+
// WASI environment has a only single thread
7074
#else
7175
barrier.pointee.mutex = UnsafeMutablePointer.allocate(capacity: 1)
7276
if pthread_mutex_init(barrier.pointee.mutex!, nil) != 0 {
@@ -89,6 +93,8 @@ public func _stdlib_thread_barrier_destroy(
8993
#if os(Windows)
9094
// Condition Variables do not need to be explicitly destroyed
9195
// Mutexes do not need to be explicitly destroyed
96+
#elseif os(WASI)
97+
// WASI environment has a only single thread
9298
#else
9399
if pthread_cond_destroy(barrier.pointee.cond!) != 0 {
94100
// FIXME: leaking memory, leaking a mutex.
@@ -99,11 +105,14 @@ public func _stdlib_thread_barrier_destroy(
99105
return -1
100106
}
101107
#endif
108+
109+
#if !os(WASI)
102110
barrier.pointee.cond!.deinitialize(count: 1)
103111
barrier.pointee.cond!.deallocate()
104112

105113
barrier.pointee.mutex!.deinitialize(count: 1)
106114
barrier.pointee.mutex!.deallocate()
115+
#endif
107116

108117
return 0
109118
}
@@ -113,6 +122,8 @@ public func _stdlib_thread_barrier_wait(
113122
) -> CInt {
114123
#if os(Windows)
115124
AcquireSRWLockExclusive(barrier.pointee.mutex!)
125+
#elseif os(WASI)
126+
// WASI environment has a only single thread
116127
#else
117128
if pthread_mutex_lock(barrier.pointee.mutex!) != 0 {
118129
return -1
@@ -127,6 +138,8 @@ public func _stdlib_thread_barrier_wait(
127138
return -1
128139
}
129140
ReleaseSRWLockExclusive(barrier.pointee.mutex!)
141+
#elseif os(WASI)
142+
// WASI environment has a only single thread
130143
#else
131144
if pthread_cond_wait(barrier.pointee.cond!, barrier.pointee.mutex!) != 0 {
132145
return -1
@@ -144,6 +157,8 @@ public func _stdlib_thread_barrier_wait(
144157
#if os(Windows)
145158
WakeAllConditionVariable(barrier.pointee.cond!)
146159
ReleaseSRWLockExclusive(barrier.pointee.mutex!)
160+
#elseif os(WASI)
161+
// WASI environment has a only single thread
147162
#else
148163
if pthread_cond_broadcast(barrier.pointee.cond!) != 0 {
149164
return -1

stdlib/public/CMakeLists.txt

+3
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,9 @@ if(SWIFT_BUILD_STDLIB)
6161
add_subdirectory(stubs)
6262
add_subdirectory(core)
6363
add_subdirectory(SwiftOnoneSupport)
64+
if(WASI IN_LIST SWIFT_SDKS)
65+
add_subdirectory(WASI)
66+
endif()
6467
endif()
6568

6669
# Build differentiable programming support library only if enabled.

stdlib/public/Platform/glibc.modulemap.gyb

+1-1
Original file line numberDiff line numberDiff line change
@@ -377,11 +377,11 @@ module SwiftGlibc [system] {
377377
header "${GLIBC_INCLUDE_PATH}/poll.h"
378378
export *
379379
}
380+
% if CMAKE_SDK != "WASI":
380381
module pthread {
381382
header "${GLIBC_INCLUDE_PATH}/pthread.h"
382383
export *
383384
}
384-
% if CMAKE_SDK != "WASI":
385385
module pwd {
386386
header "${GLIBC_INCLUDE_PATH}/pwd.h"
387387
export *

stdlib/public/WASI/CMakeLists.txt

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
add_swift_target_library(swiftWasiPthread STATIC IS_STDLIB
2+
Pthread.cpp
3+
INSTALL_IN_COMPONENT stdlib)

stdlib/public/WASI/Pthread.cpp

+153
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,153 @@
1+
// SPDX-License-Identifier: 0BSD
2+
// prototypes taken from opengroup
3+
#include <stdlib.h>
4+
#include <stdio.h>
5+
#include <pthread.h>
6+
#include <semaphore.h>
7+
8+
#define STUB() do {fprintf(stderr, "FakePthread: unsupported %s\n", __func__);abort();}while(0)
9+
10+
// mutexes: just no-ops
11+
12+
int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *attr) {
13+
return 0;
14+
}
15+
16+
int pthread_mutex_destroy(pthread_mutex_t *mutex) {
17+
return 0;
18+
}
19+
20+
int pthread_mutexattr_init(pthread_mutexattr_t *attr) {
21+
return 0;
22+
}
23+
24+
int pthread_mutexattr_destroy(pthread_mutexattr_t *attr) {
25+
return 0;
26+
}
27+
28+
int pthread_mutexattr_gettype(const pthread_mutexattr_t *attr, int *type) {
29+
return 0;
30+
}
31+
32+
int pthread_mutexattr_settype(pthread_mutexattr_t *attr, int type) {
33+
return 0;
34+
}
35+
36+
int pthread_mutex_lock(pthread_mutex_t *mutex) {
37+
return 0;
38+
}
39+
40+
int pthread_mutex_trylock(pthread_mutex_t *mutex) {
41+
return 0;
42+
}
43+
44+
int pthread_mutex_unlock(pthread_mutex_t *mutex) {
45+
return 0;
46+
}
47+
48+
// pthread_cond: STUB
49+
50+
int pthread_cond_init(pthread_cond_t *cond, const pthread_condattr_t *attr) {
51+
return 0;
52+
}
53+
54+
int pthread_cond_destroy(pthread_cond_t *cond) {
55+
return 0;
56+
}
57+
58+
int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex) {
59+
STUB();
60+
}
61+
62+
int pthread_cond_timedwait(pthread_cond_t *cond,
63+
pthread_mutex_t *mutex, const struct timespec *abstime) {
64+
STUB();
65+
}
66+
67+
int pthread_cond_broadcast(pthread_cond_t *cond) {
68+
return 0;
69+
}
70+
71+
int pthread_cond_signal(pthread_cond_t *cond) {
72+
return 0;
73+
}
74+
75+
// tls
76+
77+
int pthread_key_create(pthread_key_t *key, void (*destructor)(void*)) {
78+
STUB();
79+
}
80+
81+
void *pthread_getspecific(pthread_key_t key) {
82+
STUB();
83+
}
84+
85+
int pthread_setspecific(pthread_key_t key, const void *value) {
86+
STUB();
87+
}
88+
89+
// threads
90+
91+
pthread_t pthread_self() {
92+
return (pthread_t)1234;
93+
}
94+
95+
#undef pthread_equal
96+
97+
int pthread_equal(pthread_t t1, pthread_t t2) {
98+
return t1 == t2;
99+
}
100+
101+
int pthread_join(pthread_t thread, void **value_ptr) {
102+
STUB();
103+
}
104+
105+
int pthread_detach(pthread_t thread) {
106+
STUB();
107+
}
108+
109+
int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine)(void *), void *arg) {
110+
return 0;
111+
}
112+
113+
// once
114+
115+
int pthread_once(pthread_once_t *once_control, void (*init_routine)(void)) {
116+
STUB();
117+
}
118+
119+
// rwlock
120+
121+
int pthread_rwlock_init(pthread_rwlock_t *rwlock, const pthread_rwlockattr_t *attr) {
122+
return 0;
123+
}
124+
125+
int pthread_rwlock_destroy(pthread_rwlock_t *rwlock) {
126+
return 0;
127+
}
128+
129+
int pthread_rwlock_rdlock(pthread_rwlock_t *rwlock) {
130+
return 0;
131+
}
132+
133+
int pthread_rwlock_tryrdlock(pthread_rwlock_t *rwlock) {
134+
return 0;
135+
}
136+
137+
int pthread_rwlock_wrlock(pthread_rwlock_t *rwlock) {
138+
return 0;
139+
}
140+
141+
int pthread_rwlock_trywrlock(pthread_rwlock_t *rwlock) {
142+
return 0;
143+
}
144+
145+
int pthread_rwlock_unlock(pthread_rwlock_t *rwlock) {
146+
return 0;
147+
}
148+
149+
// named semaphores
150+
151+
sem_t *sem_open(const char *name, int oflag, ...) {
152+
STUB();
153+
}

stdlib/public/runtime/CMakeLists.txt

+1
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ set(swift_runtime_sources
5656
MetadataLookup.cpp
5757
MutexPThread.cpp
5858
MutexWin32.cpp
59+
MutexWASI.cpp
5960
Numeric.cpp
6061
Once.cpp
6162
Portability.cpp

0 commit comments

Comments
 (0)