Wasm: enable thread support
configure.json: Make the “thread” feature be allowed for wasm but disabled by default. Change qmake.conf and wasm.prf to enable Emscripten pthreads mode: - Add USE_PTHREADS=1 linker flag - Add PTHREAD_POOL_SIZE linker flag with a default pool size (4). - Add TOTAL_MEMORY linker flag to set available memory (1GB) It is possible to override options such as PTHREAD_POOL_SIZE from the application .pro file using QMAKE_WASM_PTHREAD_POOL_SIZE To change TOTAL_MEMORY, use QMAKE_WASM_TOTAL_MEMORY Make qtloader.js work in pthreads mode: - The Module.instantiateWasm callback must provide the module in addition to the instance to Emscripten. - Set Module.mainScriptUrlOrBlob so that the pthreads web workers can access the main script Task-number: QTBUG-64625 Change-Id: I1ab5a559ec97c27c5fc24500ba5f863bcd275141 Reviewed-by: Morten Johan Sørvig <morten.sorvig@qt.io> Reviewed-by: Lorn Potter <lorn.potter@gmail.com>bb10
parent
6e7a7d5fb9
commit
de4f256d48
|
|
@ -1199,7 +1199,7 @@
|
|||
"label": "Thread support",
|
||||
"purpose": "Provides QThread and related classes.",
|
||||
"section": "Kernel",
|
||||
"condition": "!config.wasm",
|
||||
"autoDetect": "!config.wasm",
|
||||
"output": [ "publicFeature" ]
|
||||
},
|
||||
"future": {
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
# due to required Qt modules being missing.
|
||||
!isEmpty(QMAKE_FAILED_REQUIREMENTS): return()
|
||||
|
||||
CONFIG *= thread
|
||||
qtConfig(thread): CONFIG *= thread
|
||||
|
||||
#handle defines
|
||||
win32 {
|
||||
|
|
|
|||
|
|
@ -2,6 +2,39 @@
|
|||
# DESTDIR will be empty if not set in the app .pro file; make sure it has a value
|
||||
isEmpty(DESTDIR): DESTDIR = $$OUT_PWD
|
||||
|
||||
exists($$QMAKE_QT_CONFIG) {
|
||||
qtConfig(thread) {
|
||||
|
||||
EMCC_THREAD_LFLAGS += -s USE_PTHREADS=1
|
||||
# Hardcode wasm memory size. Emscripten does not currently support memory growth
|
||||
# (ALLOW_MEMORY_GROWTH) in pthreads mode, and requires specifying the memory size
|
||||
# at build time. Further, browsers limit the maximum initial memory size to 1GB.
|
||||
TOTAL_MEMORY = 1GB
|
||||
!isEmpty(QMAKE_WASM_TOTAL_MEMORY) {
|
||||
TOTAL_MEMORY = $$QMAKE_WASM_TOTAL_MEMORY
|
||||
}
|
||||
|
||||
message("Setting TOTAL_MEMORY to" $$TOTAL_MEMORY)
|
||||
EMCC_THREAD_LFLAGS += -s TOTAL_MEMORY=$$TOTAL_MEMORY
|
||||
|
||||
# Create worker threads at startup. This is supposed to be an optimization,
|
||||
# however exceeding the pool size has been obesverved to hang the application.
|
||||
POOL_SIZE = 4
|
||||
!isEmpty(QMAKE_WASM_PTHREAD_POOL_SIZE) {
|
||||
POOL_SIZE = $$QMAKE_WASM_PTHREAD_POOL_SIZE
|
||||
}
|
||||
|
||||
message("Setting PTHREAD_POOL_SIZE to" $$POOL_SIZE)
|
||||
EMCC_THREAD_LFLAGS += -s PTHREAD_POOL_SIZE=$$POOL_SIZE
|
||||
} else {
|
||||
EMCC_THREAD_LFLAGS += -s ALLOW_MEMORY_GROWTH=1
|
||||
}
|
||||
QMAKE_LFLAGS += $$EMCC_THREAD_LFLAGS
|
||||
QMAKE_LFLAGS_DEBUG += $$EMCC_THREAD_LFLAGS
|
||||
QMAKE_CFLAGS += $$EMCC_THREAD_LFLAGS
|
||||
QMAKE_CXXFLAGS += $$EMCC_THREAD_LFLAGS
|
||||
}
|
||||
|
||||
# Create js and wasm files for applications
|
||||
contains(TEMPLATE, .*app) {
|
||||
TARGET_BASE = $${TARGET}
|
||||
|
|
|
|||
|
|
@ -15,7 +15,6 @@ EMTERP_FLAGS = \
|
|||
EMCC_COMMON_LFLAGS = \
|
||||
-s WASM=1 \
|
||||
-s FULL_ES2=1 \
|
||||
-s ALLOW_MEMORY_GROWTH=1 \
|
||||
-s USE_WEBGL2=1 \
|
||||
-s NO_EXIT_RUNTIME=0 \
|
||||
-s ERROR_ON_UNDEFINED_SYMBOLS=1 \
|
||||
|
|
|
|||
|
|
@ -312,13 +312,13 @@ function QtLoader(config)
|
|||
// and is ready to be instantiated. Define the instantiateWasm callback which
|
||||
// emscripten will call to create the instance.
|
||||
Module.instantiateWasm = function(imports, successCallback) {
|
||||
return WebAssembly.instantiate(wasmModule, imports).then(function(instance) {
|
||||
successCallback(instance);
|
||||
return instance;
|
||||
WebAssembly.instantiate(wasmModule, imports).then(function(instance) {
|
||||
successCallback(instance, wasmModule);
|
||||
}, function(error) {
|
||||
self.error = error;
|
||||
setStatus("Error");
|
||||
});
|
||||
return {};
|
||||
};
|
||||
|
||||
Module.locateFile = Module.locateFile || function(filename) {
|
||||
|
|
@ -382,6 +382,8 @@ function QtLoader(config)
|
|||
}
|
||||
});
|
||||
|
||||
Module.mainScriptUrlOrBlob = new Blob([emscriptenModuleSource], {type: 'text/javascript'});
|
||||
|
||||
config.restart = function() {
|
||||
|
||||
// Restart by reloading the page. This will wipe all state which means
|
||||
|
|
|
|||
Loading…
Reference in New Issue