Bug 1701613 part 3 - Add stub thread implementation for WASI. r=jandem,wingo

WASI lacks thread support so the stub implementation for threads has been added.

Differential Revision: https://phabricator.services.mozilla.com/D110073
This commit is contained in:
Chris Fallin 2021-04-08 08:02:16 +00:00
Родитель bd584a6d38
Коммит f062cdc9ba
20 изменённых файлов: 228 добавлений и 13 удалений

Просмотреть файл

@ -493,6 +493,12 @@ if CONFIG["OS_ARCH"] == "WINNT":
"threading/windows/CpuCount.cpp",
"threading/windows/WindowsThread.cpp",
]
# WASI hasn't supported thread yet so noop implementation is used.
elif CONFIG["OS_ARCH"] == "WASI":
UNIFIED_SOURCES += [
"threading/noop/CpuCount.cpp",
"threading/noop/NoopThread.cpp",
]
else:
UNIFIED_SOURCES += [
"threading/posix/CpuCount.cpp",

Просмотреть файл

@ -45,7 +45,6 @@
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <thread>
#include <utility>
#ifdef XP_UNIX
# include <sys/mman.h>
@ -8064,7 +8063,7 @@ static void BufferStreamMain(BufferStreamJob* job) {
break;
}
std::this_thread::sleep_for(std::chrono::milliseconds(delayMillis));
ThisThread::SleepMilliseconds(delayMillis);
chunkSize = std::min(chunkSize, byteLength - byteOffset);

Просмотреть файл

@ -12,7 +12,7 @@
#include <stdint.h>
#include <utility>
#ifndef XP_WIN
#if !defined(XP_WIN) && !defined(__wasi__)
# include <pthread.h>
#endif

Просмотреть файл

@ -157,6 +157,10 @@ void SetName(const char* name);
// 'nameBuffer', including the terminating NUL.
void GetName(char* nameBuffer, size_t len);
// Causes the current thread to sleep until the
// number of real-time milliseconds specified have elapsed.
void SleepMilliseconds(size_t ms);
} // namespace ThisThread
namespace detail {

Просмотреть файл

@ -0,0 +1,9 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include <unistd.h>
#include "threading/CpuCount.h"
uint32_t js::GetCPUCount() { return 1; }

Просмотреть файл

@ -0,0 +1,34 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "mozilla/Assertions.h"
#include "threading/noop/ThreadPlatformData.h"
namespace js {
inline ThreadId::PlatformData* ThreadId::platformData() {
return reinterpret_cast<PlatformData*>(platformData_);
}
inline const ThreadId::PlatformData* ThreadId::platformData() const {
return reinterpret_cast<const PlatformData*>(platformData_);
}
ThreadId::ThreadId() {}
ThreadId::operator bool() const { return false; }
bool ThreadId::operator==(const ThreadId& aOther) const { return true; }
bool Thread::create(void* (*aMain)(void*), void* aArg) { return false; }
void Thread::join() {}
void Thread::detach() {}
ThreadId ThreadId::ThisThreadId() { return ThreadId(); }
void ThisThread::SetName(const char*) {}
void ThisThread::GetName(char*, size_t) {}
void ThisThread::SleepMilliseconds(size_t) {
MOZ_CRASH("There is no any implementation for sleep.");
}
} // namespace js

Просмотреть файл

@ -0,0 +1,24 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef threading_noop_ThreadPlatformData_h
#define threading_noop_ThreadPlatformData_h
#include <stdlib.h>
#include <string.h>
#include "threading/Thread.h"
namespace js {
class ThreadId::PlatformData {
friend class Thread;
friend class ThreadId;
};
} // namespace js
#endif // threading_noop_ThreadPlatformData_h

Просмотреть файл

@ -6,6 +6,9 @@
#include "mozilla/Assertions.h"
#include <chrono>
#include <thread>
#include "js/Utility.h"
#include "threading/posix/ThreadPlatformData.h"
#include "threading/Thread.h"
@ -136,4 +139,8 @@ void ThisThread::GetName(char* nameBuffer, size_t len) {
}
}
void ThisThread::SleepMilliseconds(size_t ms) {
std::this_thread::sleep_for(std::chrono::milliseconds(ms));
}
} // namespace js

Просмотреть файл

@ -4,6 +4,9 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include <chrono>
#include <thread>
#include "threading/Thread.h"
#include "threading/windows/ThreadPlatformData.h"
@ -117,4 +120,8 @@ void ThisThread::GetName(char* nameBuffer, size_t len) {
*nameBuffer = '\0';
}
void ThisThread::SleepMilliseconds(size_t ms) {
std::this_thread::sleep_for(std::chrono::milliseconds(ms));
}
} // namespace js

Просмотреть файл

@ -71,7 +71,11 @@ JS::FilenameValidationCallback js::gFilenameValidationCallback = nullptr;
namespace js {
bool (*HelperThreadTaskCallback)(js::UniquePtr<RunnableTask>);
#ifndef __wasi__
bool gCanUseExtraThreads = true;
#else
bool gCanUseExtraThreads = false;
#endif
} // namespace js
void js::DisableExtraThreads() { gCanUseExtraThreads = false; }

Просмотреть файл

@ -24,7 +24,6 @@
#include "mozilla/Unused.h"
#include <algorithm>
#include <thread>
#include "util/Memory.h"
#include "util/Text.h"
@ -1340,7 +1339,7 @@ bool ModuleGenerator::finishTier2(const Module& module) {
if (MOZ_UNLIKELY(JitOptions.wasmDelayTier2)) {
// Introduce an artificial delay when testing wasmDelayTier2, since we
// want to exercise both tier1 and tier2 code in this case.
std::this_thread::sleep_for(std::chrono::milliseconds(500));
ThisThread::SleepMilliseconds(500);
}
return module.finishTier2(*linkData_, std::move(codeTier));

Просмотреть файл

@ -19,7 +19,6 @@
#include "wasm/WasmModule.h"
#include <chrono>
#include <thread>
#include "jit/JitOptions.h"
#include "js/BuildId.h" // JS::BuildIdCharVector
@ -199,7 +198,7 @@ bool Module::finishTier2(const LinkData& linkData2,
void Module::testingBlockOnTier2Complete() const {
while (testingTier2Active_) {
std::this_thread::sleep_for(std::chrono::milliseconds(1));
ThisThread::SleepMilliseconds(1);
}
}

Просмотреть файл

@ -9,7 +9,7 @@
#ifndef mozilla_ThreadLocal_h
#define mozilla_ThreadLocal_h
#if !defined(XP_WIN)
#if !defined(XP_WIN) && !defined(__wasi__)
# include <pthread.h>
#endif
@ -120,6 +120,28 @@ class ThreadLocalKeyStorage {
unsigned long mKey;
};
# endif
#elif defined(__wasi__)
// There are no threads on WASI, so we just use a global variable.
template <typename T>
class ThreadLocalKeyStorage {
public:
constexpr ThreadLocalKeyStorage() : mInited(false) {}
inline bool initialized() const { return mInited; }
inline void init() { mInited = true; }
inline T get() const { return mVal; }
inline bool set(const T aValue) {
mVal = aValue;
return true;
}
private:
bool mInited;
T mVal;
};
#else
template <typename T>
class ThreadLocalKeyStorage {

Просмотреть файл

@ -0,0 +1,40 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "mozilla/Assertions.h"
#include "mozilla/PlatformConditionVariable.h"
#include "mozilla/PlatformMutex.h"
#include "MutexPlatformData_noop.h"
using mozilla::TimeDuration;
struct mozilla::detail::ConditionVariableImpl::PlatformData {};
mozilla::detail::ConditionVariableImpl::ConditionVariableImpl() {}
mozilla::detail::ConditionVariableImpl::~ConditionVariableImpl() {}
void mozilla::detail::ConditionVariableImpl::notify_one() {}
void mozilla::detail::ConditionVariableImpl::notify_all() {}
void mozilla::detail::ConditionVariableImpl::wait(MutexImpl&) {
// On WASI, there are no threads, so we never wait (either the condvar must
// be ready or there is a deadlock).
}
mozilla::CVStatus mozilla::detail::ConditionVariableImpl::wait_for(
MutexImpl&, const TimeDuration&) {
return CVStatus::NoTimeout;
}
mozilla::detail::ConditionVariableImpl::PlatformData*
mozilla::detail::ConditionVariableImpl::platformData() {
static_assert(sizeof platformData_ >= sizeof(PlatformData),
"platformData_ is too small");
return reinterpret_cast<PlatformData*>(platformData_);
}

Просмотреть файл

@ -0,0 +1,18 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
* vim: set ts=8 sts=2 et sw=2 tw=80:
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef MutexPlatformData_noop_h
#define MutexPlatformData_noop_h
#if !defined(__wasi__)
# error This code is for WASI only.
#endif
#include "mozilla/PlatformMutex.h"
struct mozilla::detail::MutexImpl::PlatformData {};
#endif // MutexPlatformData_noop_h

Просмотреть файл

@ -0,0 +1,34 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "mozilla/Assertions.h"
#include <errno.h>
#include <stdio.h>
#include "mozilla/PlatformMutex.h"
#include "MutexPlatformData_noop.h"
mozilla::detail::MutexImpl::MutexImpl() {}
mozilla::detail::MutexImpl::~MutexImpl() {}
inline void mozilla::detail::MutexImpl::mutexLock() {}
bool mozilla::detail::MutexImpl::tryLock() { return mutexTryLock(); }
bool mozilla::detail::MutexImpl::mutexTryLock() { return true; }
void mozilla::detail::MutexImpl::lock() { mutexLock(); }
void mozilla::detail::MutexImpl::unlock() {}
mozilla::detail::MutexImpl::PlatformData*
mozilla::detail::MutexImpl::platformData() {
static_assert(sizeof(platformData_) >= sizeof(PlatformData),
"platformData_ is too small");
return reinterpret_cast<PlatformData*>(platformData_);
}

Просмотреть файл

@ -14,7 +14,7 @@
#include "mozilla/Attributes.h"
#include "mozilla/PlatformMutex.h"
#include "mozilla/TimeStamp.h"
#ifndef XP_WIN
#if !defined(XP_WIN) && !defined(__wasi__)
# include <pthread.h>
#endif
@ -54,7 +54,7 @@ class ConditionVariableImpl {
PlatformData* platformData();
#ifndef XP_WIN
#if !defined(XP_WIN) && !defined(__wasi__)
void* platformData_[sizeof(pthread_cond_t) / sizeof(void*)];
static_assert(sizeof(pthread_cond_t) / sizeof(void*) != 0 &&
sizeof(pthread_cond_t) % sizeof(void*) == 0,

Просмотреть файл

@ -12,7 +12,7 @@
#include "mozilla/Attributes.h"
#include "mozilla/Types.h"
#if !defined(XP_WIN)
#if !defined(XP_WIN) && !defined(__wasi__)
# include <pthread.h>
#endif
@ -48,7 +48,7 @@ class MutexImpl {
PlatformData* platformData();
#if !defined(XP_WIN)
#if !defined(XP_WIN) && !defined(__wasi__)
void* platformData_[sizeof(pthread_mutex_t) / sizeof(void*)];
static_assert(sizeof(pthread_mutex_t) / sizeof(void*) != 0 &&
sizeof(pthread_mutex_t) % sizeof(void*) == 0,

Просмотреть файл

@ -50,7 +50,10 @@
#include "mozilla/Sprintf.h"
#include "mozilla/TimeStamp.h"
#include "mozilla/Uptime.h"
#include <pthread.h>
#if !defined(__wasi__)
# include <pthread.h>
#endif
// Estimate of the smallest duration of time we can measure.
static uint64_t sResolution;

Просмотреть файл

@ -87,6 +87,12 @@ if CONFIG["OS_ARCH"] == "WINNT":
"ConditionVariable_windows.cpp",
"Mutex_windows.cpp",
]
# WASI hasn't supported cond vars and mutexes yet so noop implementation is used.
elif CONFIG["OS_ARCH"] == "WASI":
SOURCES += [
"ConditionVariable_noop.cpp",
"Mutex_noop.cpp",
]
else:
SOURCES += [
"ConditionVariable_posix.cpp",