aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDylan Baker <dylan@pnwbakers.com>2020-02-24 10:55:31 -0800
committerDylan Baker <dylan@pnwbakers.com>2020-02-27 16:35:02 -0800
commit771b0d3ffbc7b034b436d4ad27be7d0a1da6b3cd (patch)
tree051bf624f251dceb88a0c36d4c4affac7a4914ea
parentb2f86c461b72e405695ab1491baba00f45af93a6 (diff)
downloadmeson-771b0d3ffbc7b034b436d4ad27be7d0a1da6b3cd.zip
meson-771b0d3ffbc7b034b436d4ad27be7d0a1da6b3cd.tar.gz
meson-771b0d3ffbc7b034b436d4ad27be7d0a1da6b3cd.tar.bz2
compilers/mixins/emscripten: Implement thread support
Emscripten has pthread support (as well as C++ threads), but we don't currently implement them. This fixes that by adding the necessary code. The one thing I'm not sure about is setting the pool size. The docs suggest that you really want to do this to ensure that your code works correctly, but the number should really be configurable, not sure how to set that. Fixes #6684
-rw-r--r--docs/markdown/Builtin-options.md34
-rw-r--r--docs/markdown/snippets/emscripten_threads.md6
-rw-r--r--mesonbuild/compilers/c.py2
-rw-r--r--mesonbuild/compilers/cpp.py2
-rw-r--r--mesonbuild/compilers/mixins/emscripten.py26
-rw-r--r--test cases/wasm/2 threads/meson.build10
-rw-r--r--test cases/wasm/2 threads/threads.c21
-rw-r--r--test cases/wasm/2 threads/threads.cpp13
8 files changed, 98 insertions, 16 deletions
diff --git a/docs/markdown/Builtin-options.md b/docs/markdown/Builtin-options.md
index 067966f..ac40263 100644
--- a/docs/markdown/Builtin-options.md
+++ b/docs/markdown/Builtin-options.md
@@ -134,20 +134,22 @@ The following options are available. Note that both the options themselves and
the possible values they can take will depend on the target platform or
compiler being used:
-| Option | Default value | Possible values | Description |
-| ------ | ------------- | --------------- | ----------- |
-| c_args | | free-form comma-separated list | C compile arguments to use |
-| c_link_args | | free-form comma-separated list | C link arguments to use |
-| c_std | none | none, c89, c99, c11, c17, c18, gnu89, gnu99, gnu11, gnu17, gnu18 | C language standard to use |
-| c_winlibs | see below | free-form comma-separated list | Standard Windows libs to link against |
-| cpp_args | | free-form comma-separated list | C++ compile arguments to use |
-| cpp_link_args| | free-form comma-separated list | C++ link arguments to use |
-| cpp_std | none | none, c++98, c++03, c++11, c++14, c++17, <br/>c++1z, gnu++03, gnu++11, gnu++14, gnu++17, gnu++1z, <br/> vc++14, vc++17, vc++latest | C++ language standard to use |
-| cpp_debugstl | false | true, false | C++ STL debug mode |
-| cpp_eh | default | none, default, a, s, sc | C++ exception handling type |
-| cpp_rtti | true | true, false | Whether to enable RTTI (runtime type identification) |
-| cpp_winlibs | see below | free-form comma-separated list | Standard Windows libs to link against |
-| fortran_std | none | [none, legacy, f95, f2003, f2008, f2018] | Fortran language standard to use |
+| Option | Default value | Possible values | Description |
+| ------ | ------------- | --------------- | ----------- |
+| c_args | | free-form comma-separated list | C compile arguments to use |
+| c_link_args | | free-form comma-separated list | C link arguments to use |
+| c_std | none | none, c89, c99, c11, c17, c18, gnu89, gnu99, gnu11, gnu17, gnu18 | C language standard to use |
+| c_winlibs | see below | free-form comma-separated list | Standard Windows libs to link against |
+| c_thread_count | 4 | integer value ≥ 0 | Number of threads to use with emcc when using threads |
+| cpp_args | | free-form comma-separated list | C++ compile arguments to use |
+| cpp_link_args | | free-form comma-separated list | C++ link arguments to use |
+| cpp_std | none | none, c++98, c++03, c++11, c++14, c++17, <br/>c++1z, gnu++03, gnu++11, gnu++14, gnu++17, gnu++1z, <br/> vc++14, vc++17, vc++latest | C++ language standard to use |
+| cpp_debugstl | false | true, false | C++ STL debug mode |
+| cpp_eh | default | none, default, a, s, sc | C++ exception handling type |
+| cpp_rtti | true | true, false | Whether to enable RTTI (runtime type identification) |
+| cpp_thread_count | 4 | integer value ≥ 0 | Number of threads to use with emcc when using threads |
+| cpp_winlibs | see below | free-form comma-separated list | Standard Windows libs to link against |
+| fortran_std | none | [none, legacy, f95, f2003, f2008, f2018] | Fortran language standard to use |
The default values of `c_winlibs` and `cpp_winlibs` are in compiler-specific
argument forms, but the libraries are: kernel32, user32, gdi32, winspool,
@@ -162,3 +164,7 @@ while the `cpp_eh=[value]` will result in `/EH[value]`.
Since *0.51.0* `cpp_eh=default` will result in `/EHsc` on MSVC. When using
gcc-style compilers, nothing is passed (allowing exceptions to work), while
`cpp_eh=none` passes `-fno-exceptions`.
+
+Since *0.54.0* The `<lang>_thread_count` option can be used to control the
+value passed to `-s PTHREAD_POOL_SIZE` when using emcc. No other c/c++
+compiler supports this option.
diff --git a/docs/markdown/snippets/emscripten_threads.md b/docs/markdown/snippets/emscripten_threads.md
new file mode 100644
index 0000000..bdf808e
--- /dev/null
+++ b/docs/markdown/snippets/emscripten_threads.md
@@ -0,0 +1,6 @@
+## Emscripten (emcc) now supports threads
+
+In addition to properly setting the compile and linker arguments, a new meson
+builtin has been added to control the PTHREAD_POOL_SIZE option,
+`-D<lang>_thread_count`, which may be set to any integer value greater than 0.
+If it set to 0 then the PTHREAD_POOL_SIZE option will not be passed.
diff --git a/mesonbuild/compilers/c.py b/mesonbuild/compilers/c.py
index e27eb90..f3ed9e8 100644
--- a/mesonbuild/compilers/c.py
+++ b/mesonbuild/compilers/c.py
@@ -133,7 +133,7 @@ class AppleClangCCompiler(ClangCCompiler):
_C18_VERSION = '>=11.0.0'
-class EmscriptenCCompiler(BasicLinkerIsCompilerMixin, LinkerEnvVarsMixin, EmscriptenMixin, ClangCCompiler):
+class EmscriptenCCompiler(EmscriptenMixin, BasicLinkerIsCompilerMixin, LinkerEnvVarsMixin, ClangCCompiler):
def __init__(self, exelist, version, for_machine: MachineChoice,
is_cross: bool, info: 'MachineInfo', exe_wrapper=None, **kwargs):
if not is_cross:
diff --git a/mesonbuild/compilers/cpp.py b/mesonbuild/compilers/cpp.py
index f6f4cfc..2a244e9 100644
--- a/mesonbuild/compilers/cpp.py
+++ b/mesonbuild/compilers/cpp.py
@@ -201,7 +201,7 @@ class AppleClangCPPCompiler(ClangCPPCompiler):
pass
-class EmscriptenCPPCompiler(BasicLinkerIsCompilerMixin, LinkerEnvVarsMixin, EmscriptenMixin, ClangCPPCompiler):
+class EmscriptenCPPCompiler(EmscriptenMixin, BasicLinkerIsCompilerMixin, LinkerEnvVarsMixin, ClangCPPCompiler):
def __init__(self, exelist, version, for_machine: MachineChoice,
is_cross: bool, info: 'MachineInfo', exe_wrapper=None, **kwargs):
if not is_cross:
diff --git a/mesonbuild/compilers/mixins/emscripten.py b/mesonbuild/compilers/mixins/emscripten.py
index 36a757a..ee86ce4 100644
--- a/mesonbuild/compilers/mixins/emscripten.py
+++ b/mesonbuild/compilers/mixins/emscripten.py
@@ -17,8 +17,13 @@
import os.path
import typing as T
+from ... import coredata
from ...mesonlib import MesonException
+if T.TYPE_CHECKING:
+ from ..environment import Environment
+
+
class EmscriptenMixin:
def get_option_link_args(self, options):
@@ -45,3 +50,24 @@ class EmscriptenMixin:
else:
suffix = 'wasm'
return os.path.join(dirname, 'output.' + suffix)
+
+ def thread_flags(self, env: 'Environment') -> T.List[str]:
+ return ['-s', 'USE_PTHREADS=1']
+
+ def thread_link_flags(self, env: 'Environment') -> T.List[str]:
+ args = ['-s', 'USE_PTHREADS=1']
+ count = env.coredata.compiler_options[self.for_machine]['{}_thread_count'.format(self.language)].value # type: int
+ if count:
+ args.extend(['-s', 'PTHREAD_POOL_SIZE={}'.format(count)])
+ return args
+
+ def get_options(self):
+ opts = super().get_options()
+ opts.update({
+ '{}_thread_count'.format(self.language): coredata.UserIntegerOption(
+ 'Number of threads to use in web assembly, set to 0 to disable',
+ (0, None, 4), # Default was picked at random
+ ),
+ })
+
+ return opts
diff --git a/test cases/wasm/2 threads/meson.build b/test cases/wasm/2 threads/meson.build
new file mode 100644
index 0000000..cb682b8
--- /dev/null
+++ b/test cases/wasm/2 threads/meson.build
@@ -0,0 +1,10 @@
+project(
+ 'threads',
+ 'c', 'cpp',
+ default_options : ['cpp_std=c++11'],
+)
+
+dep_threads = dependency('threads')
+
+executable('threads-c', 'threads.c', dependencies : dep_threads)
+executable('threads-c++', 'threads.cpp', dependencies : dep_threads)
diff --git a/test cases/wasm/2 threads/threads.c b/test cases/wasm/2 threads/threads.c
new file mode 100644
index 0000000..e79bff1
--- /dev/null
+++ b/test cases/wasm/2 threads/threads.c
@@ -0,0 +1,21 @@
+#include <stdio.h>
+#include <unistd.h>
+#include <pthread.h>
+
+void inthread(void * args) {
+ sleep(1);
+ printf("In thread\n");
+}
+
+int main() {
+#ifdef __EMSCRIPTEN_PTHREADS__
+ pthread_t thread_id;
+ printf("Before Thread\n");
+ pthread_create(&thread_id, NULL, (void *)*inthread, NULL);
+ pthread_join(thread_id, NULL);
+ printf("After Thread\n");
+ return 0;
+#else
+# error "threads not enabled\n"
+#endif
+}
diff --git a/test cases/wasm/2 threads/threads.cpp b/test cases/wasm/2 threads/threads.cpp
new file mode 100644
index 0000000..1caa73d
--- /dev/null
+++ b/test cases/wasm/2 threads/threads.cpp
@@ -0,0 +1,13 @@
+#include <unistd.h>
+#include <iostream>
+#include <thread>
+
+int main(void) {
+ std::cout << "Before thread" << std::endl;
+ std::thread t([]() {
+ sleep(1);
+ std::cout << "In a thread." << std::endl;
+ });
+ t.join();
+ std::cout << "After thread" << std::endl;
+}