Remodel threading to use a global thread pool so it never block on the main thread. Bump emscripten to 3.1.65
This commit is contained in:
41
src/Util.cc
41
src/Util.cc
@@ -1,5 +1,6 @@
|
||||
#include "Util.h"
|
||||
|
||||
#include <emscripten/em_asm.h>
|
||||
ThreadPool globalPool;
|
||||
void fireEv(int index, const char* content, const char* type) {
|
||||
MAIN_THREAD_EM_ASM({
|
||||
objs[$0].dispatchEvent(new CustomEvent($2 === 0 ? "0" : UTF8ToString($2), { "detail" : UTF8ToString($1) }));
|
||||
@@ -44,4 +45,42 @@ int untar(unsigned char* tar, int tarSize, const std::string& storepath) {
|
||||
}
|
||||
}
|
||||
return Successful;
|
||||
}
|
||||
void Thread::startup(ThreadPool* pool) {
|
||||
while(!pool->done) {
|
||||
// Wait until unlocked
|
||||
emscripten_atomic_wait_u32(&pool->qLock, true, -1);
|
||||
if(pool->done) break;
|
||||
// If there is no task then everyone has to wait until there is more
|
||||
if(pool->taskQ.empty()) {
|
||||
emscripten_atomic_store_u32(&pool->qLock, true);
|
||||
continue;
|
||||
}
|
||||
// If this locks, the returned (loaded) value will be false, and we move on
|
||||
if(emscripten_atomic_cas_u32(&pool->qLock, false, true)) continue;
|
||||
fn = pool->taskQ.front();
|
||||
pool->taskQ.pop();
|
||||
// Unlock
|
||||
emscripten_atomic_store_u32(&pool->qLock, false);
|
||||
emscripten_atomic_notify(&pool->qLock, 1);
|
||||
fn();
|
||||
}
|
||||
}
|
||||
ThreadPool::ThreadPool() {
|
||||
for(Thread& thrd : threads) {
|
||||
thrd.handle = std::thread{&Thread::startup, &thrd, this};
|
||||
}
|
||||
}
|
||||
ThreadPool::~ThreadPool() {
|
||||
done = true;
|
||||
emscripten_atomic_store_u32(&qLock, false);
|
||||
emscripten_atomic_notify(&qLock, -1);
|
||||
for(Thread& thrd : threads) {
|
||||
thrd.handle.detach();
|
||||
}
|
||||
}
|
||||
void ThreadPool::exec(std::function<void()> fn) {
|
||||
taskQ.emplace(fn);
|
||||
emscripten_atomic_store_u32(&qLock, false);
|
||||
emscripten_atomic_notify(&qLock, 1);
|
||||
}
|
||||
Reference in New Issue
Block a user