Skip to content

Commit

Permalink
Eliminate fakepthread dependency (#27)
Browse files Browse the repository at this point in the history
* [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
  • Loading branch information
kateinoigakukun committed Jan 11, 2020
1 parent 7b5516f commit a2bb344
Show file tree
Hide file tree
Showing 18 changed files with 334 additions and 7 deletions.
10 changes: 10 additions & 0 deletions include/swift/Basic/Lazy.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,18 @@
#include <memory>
#ifdef __APPLE__
#include <dispatch/dispatch.h>
#elif defined(__wasi__)
// No pthread on wasi
#else
#include <mutex>
#endif
#include "swift/Basic/Malloc.h"
#include "swift/Basic/type_traits.h"

#ifdef __wasi__
void wasi_polyfill_call_once(int *flag, void *context, void (*func)(void *));
#endif

namespace swift {

#ifdef __APPLE__
Expand All @@ -36,6 +42,10 @@ namespace swift {
using OnceToken_t = unsigned long;
# define SWIFT_ONCE_F(TOKEN, FUNC, CONTEXT) \
_swift_once_f(&TOKEN, CONTEXT, FUNC)
#elif defined(__wasi__)
using OnceToken_t = int;
# define SWIFT_ONCE_F(TOKEN, FUNC, CONTEXT) \
::wasi_polyfill_call_once(&TOKEN, CONTEXT, FUNC)
#else
using OnceToken_t = std::once_flag;
# define SWIFT_ONCE_F(TOKEN, FUNC, CONTEXT) \
Expand Down
4 changes: 3 additions & 1 deletion include/swift/Runtime/Mutex.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,12 @@

#include <type_traits>

#if (defined(__APPLE__) || defined(__linux__) || defined(__CYGWIN__) || defined(__FreeBSD__) || defined(__HAIKU__) || defined(__wasi__))
#if (defined(__APPLE__) || defined(__linux__) || defined(__CYGWIN__) || defined(__FreeBSD__) || defined(__HAIKU__))
#include "swift/Runtime/MutexPThread.h"
#elif defined(_WIN32)
#include "swift/Runtime/MutexWin32.h"
#elif defined(__wasi__)
#include "swift/Runtime/MutexWASI.h"
#else
#error "Implement equivalent of MutexPThread.h/cpp for your platform."
#endif
Expand Down
66 changes: 66 additions & 0 deletions include/swift/Runtime/MutexWASI.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
//===--- MutexWin32.h - -----------------------------------------*- C++ -*-===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//
//
// Mutex, ConditionVariable, Read/Write lock, and Scoped lock implementations
// using Windows Slim Reader/Writer Locks and Conditional Variables.
//
//===----------------------------------------------------------------------===//

#ifndef SWIFT_RUNTIME_MUTEX_WASI_H
#define SWIFT_RUNTIME_MUTEX_WASI_H

namespace swift {

typedef void* ConditionHandle;
typedef void* MutexHandle;
typedef void* ReadWriteLockHandle;

#define SWIFT_CONDITION_SUPPORTS_CONSTEXPR 1
#define SWIFT_MUTEX_SUPPORTS_CONSTEXPR 1
#define SWIFT_READWRITELOCK_SUPPORTS_CONSTEXPR 1

struct ConditionPlatformHelper {
static constexpr ConditionHandle staticInit() {
return nullptr;
};
static void init(ConditionHandle &condition) {}
static void destroy(ConditionHandle &condition) {}
static void notifyOne(ConditionHandle &condition) {}
static void notifyAll(ConditionHandle &condition) {}
static void wait(ConditionHandle &condition, MutexHandle &mutex);
};

struct MutexPlatformHelper {
static constexpr MutexHandle staticInit() { return nullptr; }
static void init(MutexHandle &mutex, bool checked = false) {}
static void destroy(MutexHandle &mutex) {}
static void lock(MutexHandle &mutex) {}
static void unlock(MutexHandle &mutex) {}
static bool try_lock(MutexHandle &mutex) { return true; }
static void unsafeLock(MutexHandle &mutex) {}
static void unsafeUnlock(MutexHandle &mutex) {}
};

struct ReadWriteLockPlatformHelper {
static constexpr ReadWriteLockHandle staticInit() { return nullptr; }
static void init(ReadWriteLockHandle &rwlock) {}
static void destroy(ReadWriteLockHandle &rwlock) {}
static void readLock(ReadWriteLockHandle &rwlock) {}
static bool try_readLock(ReadWriteLockHandle &rwlock) { return true; }
static void readUnlock(ReadWriteLockHandle &rwlock) {}
static void writeLock(ReadWriteLockHandle &rwlock) {}
static bool try_writeLock(ReadWriteLockHandle &rwlock) { return true; }
static void writeUnlock(ReadWriteLockHandle &rwlock) {}
};
}

#endif
4 changes: 4 additions & 0 deletions lib/ClangImporter/ClangImporter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -598,6 +598,10 @@ getNormalInvocationArguments(std::vector<std::string> &invocationArgStrs,
});
}

if (triple.isOSWASI()) {
invocationArgStrs.insert(invocationArgStrs.end(), {"-D_WASI_EMULATED_MMAN"});
}

if (triple.isOSWindows()) {
switch (triple.getArch()) {
default: llvm_unreachable("unsupported Windows architecture");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,9 @@ public func _stdlib_thread_create_block<Argument, Result>(
} else {
return (0, ThreadHandle(bitPattern: threadID))
}
#elseif os(WASI)
// WASI environment has a only single thread
return (0, nil)
#else
var threadID = _make_pthread_t()
let result = pthread_create(&threadID, nil,
Expand Down Expand Up @@ -128,6 +131,9 @@ public func _stdlib_thread_join<Result>(
} else {
return (CInt(result), nil)
}
#elseif os(WASI)
// WASI environment has a only single thread
return (0, nil)
#else
var threadResultRawPtr: UnsafeMutableRawPointer?
let result = pthread_join(thread, &threadResultRawPtr)
Expand Down
15 changes: 15 additions & 0 deletions stdlib/private/SwiftPrivateThreadExtras/ThreadBarriers.swift
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ public struct _stdlib_thread_barrier_t {
#elseif os(Cygwin) || os(FreeBSD)
var mutex: UnsafeMutablePointer<pthread_mutex_t?>?
var cond: UnsafeMutablePointer<pthread_cond_t?>?
#elseif os(WASI)
// No pthread for WASI
#else
var mutex: UnsafeMutablePointer<pthread_mutex_t>?
var cond: UnsafeMutablePointer<pthread_cond_t>?
Expand Down Expand Up @@ -67,6 +69,8 @@ public func _stdlib_thread_barrier_init(

barrier.pointee.cond = UnsafeMutablePointer.allocate(capacity: 1)
InitializeConditionVariable(barrier.pointee.cond!)
#elseif os(WASI)
// WASI environment has a only single thread
#else
barrier.pointee.mutex = UnsafeMutablePointer.allocate(capacity: 1)
if pthread_mutex_init(barrier.pointee.mutex!, nil) != 0 {
Expand All @@ -89,6 +93,8 @@ public func _stdlib_thread_barrier_destroy(
#if os(Windows)
// Condition Variables do not need to be explicitly destroyed
// Mutexes do not need to be explicitly destroyed
#elseif os(WASI)
// WASI environment has a only single thread
#else
if pthread_cond_destroy(barrier.pointee.cond!) != 0 {
// FIXME: leaking memory, leaking a mutex.
Expand All @@ -99,11 +105,14 @@ public func _stdlib_thread_barrier_destroy(
return -1
}
#endif

#if !os(WASI)
barrier.pointee.cond!.deinitialize(count: 1)
barrier.pointee.cond!.deallocate()

barrier.pointee.mutex!.deinitialize(count: 1)
barrier.pointee.mutex!.deallocate()
#endif

return 0
}
Expand All @@ -113,6 +122,8 @@ public func _stdlib_thread_barrier_wait(
) -> CInt {
#if os(Windows)
AcquireSRWLockExclusive(barrier.pointee.mutex!)
#elseif os(WASI)
// WASI environment has a only single thread
#else
if pthread_mutex_lock(barrier.pointee.mutex!) != 0 {
return -1
Expand All @@ -127,6 +138,8 @@ public func _stdlib_thread_barrier_wait(
return -1
}
ReleaseSRWLockExclusive(barrier.pointee.mutex!)
#elseif os(WASI)
// WASI environment has a only single thread
#else
if pthread_cond_wait(barrier.pointee.cond!, barrier.pointee.mutex!) != 0 {
return -1
Expand All @@ -144,6 +157,8 @@ public func _stdlib_thread_barrier_wait(
#if os(Windows)
WakeAllConditionVariable(barrier.pointee.cond!)
ReleaseSRWLockExclusive(barrier.pointee.mutex!)
#elseif os(WASI)
// WASI environment has a only single thread
#else
if pthread_cond_broadcast(barrier.pointee.cond!) != 0 {
return -1
Expand Down
3 changes: 3 additions & 0 deletions stdlib/public/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,9 @@ if(SWIFT_BUILD_STDLIB)
add_subdirectory(stubs)
add_subdirectory(core)
add_subdirectory(SwiftOnoneSupport)
if(WASI IN_LIST SWIFT_SDKS)
add_subdirectory(WASI)
endif()
endif()

# Build differentiable programming support library only if enabled.
Expand Down
2 changes: 1 addition & 1 deletion stdlib/public/Platform/glibc.modulemap.gyb
Original file line number Diff line number Diff line change
Expand Up @@ -377,11 +377,11 @@ module SwiftGlibc [system] {
header "${GLIBC_INCLUDE_PATH}/poll.h"
export *
}
% if CMAKE_SDK != "WASI":
module pthread {
header "${GLIBC_INCLUDE_PATH}/pthread.h"
export *
}
% if CMAKE_SDK != "WASI":
module pwd {
header "${GLIBC_INCLUDE_PATH}/pwd.h"
export *
Expand Down
3 changes: 3 additions & 0 deletions stdlib/public/WASI/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
add_swift_target_library(swiftWasiPthread STATIC IS_STDLIB
Pthread.cpp
INSTALL_IN_COMPONENT stdlib)
153 changes: 153 additions & 0 deletions stdlib/public/WASI/Pthread.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
// SPDX-License-Identifier: 0BSD
// prototypes taken from opengroup
#include <stdlib.h>
#include <stdio.h>
#include <pthread.h>
#include <semaphore.h>

#define STUB() do {fprintf(stderr, "FakePthread: unsupported %s\n", __func__);abort();}while(0)

// mutexes: just no-ops

int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *attr) {
return 0;
}

int pthread_mutex_destroy(pthread_mutex_t *mutex) {
return 0;
}

int pthread_mutexattr_init(pthread_mutexattr_t *attr) {
return 0;
}

int pthread_mutexattr_destroy(pthread_mutexattr_t *attr) {
return 0;
}

int pthread_mutexattr_gettype(const pthread_mutexattr_t *attr, int *type) {
return 0;
}

int pthread_mutexattr_settype(pthread_mutexattr_t *attr, int type) {
return 0;
}

int pthread_mutex_lock(pthread_mutex_t *mutex) {
return 0;
}

int pthread_mutex_trylock(pthread_mutex_t *mutex) {
return 0;
}

int pthread_mutex_unlock(pthread_mutex_t *mutex) {
return 0;
}

// pthread_cond: STUB

int pthread_cond_init(pthread_cond_t *cond, const pthread_condattr_t *attr) {
return 0;
}

int pthread_cond_destroy(pthread_cond_t *cond) {
return 0;
}

int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex) {
STUB();
}

int pthread_cond_timedwait(pthread_cond_t *cond,
pthread_mutex_t *mutex, const struct timespec *abstime) {
STUB();
}

int pthread_cond_broadcast(pthread_cond_t *cond) {
return 0;
}

int pthread_cond_signal(pthread_cond_t *cond) {
return 0;
}

// tls

int pthread_key_create(pthread_key_t *key, void (*destructor)(void*)) {
STUB();
}

void *pthread_getspecific(pthread_key_t key) {
STUB();
}

int pthread_setspecific(pthread_key_t key, const void *value) {
STUB();
}

// threads

pthread_t pthread_self() {
return (pthread_t)1234;
}

#undef pthread_equal

int pthread_equal(pthread_t t1, pthread_t t2) {
return t1 == t2;
}

int pthread_join(pthread_t thread, void **value_ptr) {
STUB();
}

int pthread_detach(pthread_t thread) {
STUB();
}

int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine)(void *), void *arg) {
return 0;
}

// once

int pthread_once(pthread_once_t *once_control, void (*init_routine)(void)) {
STUB();
}

// rwlock

int pthread_rwlock_init(pthread_rwlock_t *rwlock, const pthread_rwlockattr_t *attr) {
return 0;
}

int pthread_rwlock_destroy(pthread_rwlock_t *rwlock) {
return 0;
}

int pthread_rwlock_rdlock(pthread_rwlock_t *rwlock) {
return 0;
}

int pthread_rwlock_tryrdlock(pthread_rwlock_t *rwlock) {
return 0;
}

int pthread_rwlock_wrlock(pthread_rwlock_t *rwlock) {
return 0;
}

int pthread_rwlock_trywrlock(pthread_rwlock_t *rwlock) {
return 0;
}

int pthread_rwlock_unlock(pthread_rwlock_t *rwlock) {
return 0;
}

// named semaphores

sem_t *sem_open(const char *name, int oflag, ...) {
STUB();
}
1 change: 1 addition & 0 deletions stdlib/public/runtime/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ set(swift_runtime_sources
MetadataLookup.cpp
MutexPThread.cpp
MutexWin32.cpp
MutexWASI.cpp
Numeric.cpp
Once.cpp
Portability.cpp
Expand Down

0 comments on commit a2bb344

Please sign in to comment.