Forráskód Böngészése

feat(wasi-threads): Add example of exception propagation (#1812)

Enrico Loparco 3 éve
szülő
commit
8fc641377a

+ 24 - 1
samples/wasi-threads/README.md

@@ -1 +1,24 @@
-# "WASI threads" sample introduction
+# "WASI threads" sample introduction
+
+Currently, since the `wasi-sdk` does not have thread support in the latest release, make sure to have [wasi-libc](https://github.com/WebAssembly/wasi-libc) installed. Build it with threads enabled, e.g.
+
+```shell
+make \
+    AR=/opt/wasi-sdk/bin/llvm-ar \
+    NM=/opt/wasi-sdk/bin/llvm-nm \
+    CC=/opt/wasi-sdk/bin/clang \
+    THREAD_MODEL=posix
+```
+
+Build and run the samples
+
+```shell
+$ mkdir build
+$ cd build
+$ cmake -DWASI_SYSROOT=/path/to/wasi-libc/sysroot ..
+$ make
+...
+$ ./iwasm wasm-apps/no_pthread.wasm
+...
+$ ./iwasm wasm-apps/exception_propagation.wasm
+```

+ 7 - 0
samples/wasi-threads/wasm-apps/CMakeLists.txt

@@ -1,6 +1,12 @@
 # Copyright (C) 2022 Amazon.com, Inc. or its affiliates. All Rights Reserved.
 # SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 
+if (APPLE)
+    set (HAVE_FLAG_SEARCH_PATHS_FIRST 0)
+    set (CMAKE_C_LINK_FLAGS "")
+    set (CMAKE_CXX_LINK_FLAGS "")
+endif ()
+
 if (NOT DEFINED WASI_SDK_DIR)
   set (WASI_SDK_DIR               "/opt/wasi-sdk")
 endif ()
@@ -27,3 +33,4 @@ function (compile_sample SOURCE_FILE)
 endfunction ()
 
 compile_sample(no_pthread.c)
+compile_sample(exception_propagation.c)

+ 87 - 0
samples/wasi-threads/wasm-apps/exception_propagation.c

@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2022 Amazon.com Inc. or its affiliates. All rights reserved.
+ * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+ */
+#ifndef __wasi__
+#error This example only compiles to WASM/WASI target
+#endif
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <assert.h>
+#include <wasi/api.h>
+#include <semaphore.h>
+#include <stdbool.h>
+#include <unistd.h>
+
+#define TIMEOUT_SECONDS 10
+#define NUM_THREADS 3
+static sem_t sem;
+
+void
+run_long_task()
+{
+    // Busy waiting to be interruptible by exception
+    for (int i = 0; i < TIMEOUT_SECONDS; i++)
+        sleep(1);
+}
+
+__attribute__((export_name("wasi_thread_start"))) void
+wasi_thread_start(int thread_id, int *start_arg)
+{
+    bool has_to_throw_exception = (bool)start_arg;
+
+    if (has_to_throw_exception) {
+        // Wait for all other threads (including main thread) to be ready
+        printf("Waiting before throwing exception\n");
+        for (int i = 0; i < NUM_THREADS; i++)
+            sem_wait(&sem);
+
+        printf("Throwing exception\n");
+        __builtin_trap();
+    }
+    else {
+        printf("Thread running\n");
+
+        sem_post(&sem);
+        run_long_task(); // Wait to be interrupted by exception
+        assert(false && "Unreachable");
+    }
+}
+
+int
+main(int argc, char **argv)
+{
+    int thread_id = -1;
+    if (sem_init(&sem, 0, 0) != 0) {
+        printf("Failed to init semaphore\n");
+        return EXIT_FAILURE;
+    }
+
+    // Create a thread that throws an exception
+    thread_id = __wasi_thread_spawn((void *)true);
+    if (thread_id < 0) {
+        printf("Failed to create thread: %d\n", thread_id);
+        return EXIT_FAILURE;
+    }
+
+    // Create two additional threads to test exception propagation
+    thread_id = __wasi_thread_spawn((void *)false);
+    if (thread_id < 0) {
+        printf("Failed to create thread: %d\n", thread_id);
+        return EXIT_FAILURE;
+    }
+    thread_id = __wasi_thread_spawn((void *)false);
+    if (thread_id < 0) {
+        printf("Failed to create thread: %d\n", thread_id);
+        return EXIT_FAILURE;
+    }
+
+    printf("Main thread running\n");
+
+    sem_post(&sem);
+    run_long_task(); // Wait to be interrupted by exception
+    assert(false && "Unreachable");
+
+    return EXIT_SUCCESS;
+}