Skip to content

Commit

Permalink
Create a placeholder for WASI threads implementation (bytecodeallianc…
Browse files Browse the repository at this point in the history
…e#1783)

This a simpler version of the PR: bytecodealliance#1638
  • Loading branch information
loganek authored and eloparco committed Dec 11, 2022
1 parent 1449275 commit 6d3c307
Show file tree
Hide file tree
Showing 11 changed files with 256 additions and 2 deletions.
5 changes: 5 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,11 @@ if (NOT DEFINED WAMR_BUILD_LIB_PTHREAD)
set (WAMR_BUILD_LIB_PTHREAD 0)
endif ()

if (NOT DEFINED WAMR_BUILD_LIB_WASI_THREADS)
# Disable wasi threads library by default
set (WAMR_BUILD_LIB_WASI_THREADS 0)
endif ()

if (NOT DEFINED WAMR_BUILD_MINI_LOADER)
# Disable wasm mini loader by default
set (WAMR_BUILD_MINI_LOADER 0)
Expand Down
8 changes: 8 additions & 0 deletions build-scripts/runtime_lib.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,13 @@ if (WAMR_BUILD_LIB_PTHREAD EQUAL 1)
set (WAMR_BUILD_SHARED_MEMORY 1)
endif ()

if (WAMR_BUILD_LIB_WASI_THREADS EQUAL 1)
include (${IWASM_DIR}/libraries/lib-wasi-threads/lib_wasi_threads.cmake)
# Enable the dependent feature if lib wasi threads is enabled
set (WAMR_BUILD_BULK_MEMORY 1)
set (WAMR_BUILD_SHARED_MEMORY 1)
endif ()

if (WAMR_BUILD_DEBUG_INTERP EQUAL 1)
set (WAMR_BUILD_THREAD_MGR 1)
include (${IWASM_DIR}/libraries/debug-engine/debug_engine.cmake)
Expand Down Expand Up @@ -186,6 +193,7 @@ set (source_all
${WASM_APP_LIB_SOURCE_ALL}
${NATIVE_INTERFACE_SOURCE}
${APP_MGR_SOURCE}
${LIB_WASI_THREADS_SOURCE}
${LIB_PTHREAD_SOURCE}
${THREAD_MGR_SOURCE}
${LIBC_EMCC_SOURCE}
Expand Down
4 changes: 4 additions & 0 deletions core/config.h
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,10 @@
#define WASM_ENABLE_LIB_PTHREAD_SEMAPHORE 0
#endif

#ifndef WASM_ENABLE_LIB_WASI_THREADS
#define WASM_ENABLE_LIB_WASI_THREADS 0
#endif

#ifndef WASM_ENABLE_BASE_LIB
#define WASM_ENABLE_BASE_LIB 0
#endif
Expand Down
17 changes: 15 additions & 2 deletions core/iwasm/common/wasm_native.c
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,11 @@ uint32
get_lib_pthread_export_apis(NativeSymbol **p_lib_pthread_apis);
#endif

#if WASM_ENABLE_LIB_WASI_THREADS != 0
uint32
get_lib_wasi_threads_export_apis(NativeSymbol **p_lib_wasi_threads_apis);
#endif

uint32
get_libc_emcc_export_apis(NativeSymbol **p_libc_emcc_apis);

Expand Down Expand Up @@ -383,7 +388,7 @@ wasm_native_init()
|| WASM_ENABLE_BASE_LIB != 0 || WASM_ENABLE_LIBC_EMCC != 0 \
|| WASM_ENABLE_LIB_RATS != 0 || WASM_ENABLE_WASI_NN != 0 \
|| WASM_ENABLE_APP_FRAMEWORK != 0 || WASM_ENABLE_LIBC_WASI != 0 \
|| WASM_ENABLE_LIB_PTHREAD != 0
|| WASM_ENABLE_LIB_PTHREAD != 0 || WASM_ENABLE_LIB_WASI_THREADS != 0
NativeSymbol *native_symbols;
uint32 n_native_symbols;
#endif
Expand Down Expand Up @@ -438,6 +443,14 @@ wasm_native_init()
goto fail;
#endif

#if WASM_ENABLE_LIB_WASI_THREADS != 0
n_native_symbols = get_lib_wasi_threads_export_apis(&native_symbols);
if (n_native_symbols > 0
&& !wasm_native_register_natives("wasi", native_symbols,
n_native_symbols))
goto fail;
#endif

#if WASM_ENABLE_LIBC_EMCC != 0
n_native_symbols = get_libc_emcc_export_apis(&native_symbols);
if (n_native_symbols > 0
Expand Down Expand Up @@ -466,7 +479,7 @@ wasm_native_init()
|| WASM_ENABLE_BASE_LIB != 0 || WASM_ENABLE_LIBC_EMCC != 0 \
|| WASM_ENABLE_LIB_RATS != 0 || WASM_ENABLE_WASI_NN != 0 \
|| WASM_ENABLE_APP_FRAMEWORK != 0 || WASM_ENABLE_LIBC_WASI != 0 \
|| WASM_ENABLE_LIB_PTHREAD != 0
|| WASM_ENABLE_LIB_PTHREAD != 0 || WASM_ENABLE_LIB_WASI_THREADS != 0
fail:
wasm_native_destroy();
return false;
Expand Down
11 changes: 11 additions & 0 deletions core/iwasm/libraries/lib-wasi-threads/lib_wasi_threads.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# Copyright (C) 2022 Amazon.com, Inc. or its affiliates. All Rights Reserved.
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception

set (LIB_WASI_THREADS_DIR ${CMAKE_CURRENT_LIST_DIR})

add_definitions (-DWASM_ENABLE_LIB_WASI_THREADS=1)

include_directories(${LIB_WASI_THREADS_DIR})

set (LIB_WASI_THREADS_SOURCE
${LIB_WASI_THREADS_DIR}/lib_wasi_threads_wrapper.c)
35 changes: 35 additions & 0 deletions core/iwasm/libraries/lib-wasi-threads/lib_wasi_threads_wrapper.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/*
* Copyright (C) 2022 Amazon.com, Inc. or its affiliates. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
*/

#include "wasmtime_ssp.h"

#if WASM_ENABLE_INTERP != 0
#include "wasm_runtime.h"
#endif

#if WASM_ENABLE_AOT != 0
#include "aot_runtime.h"
#endif

static __wasi_errno_t
thread_spawn_wrapper(wasm_exec_env_t exec_env, void *start_arg)
{
return __WASI_ENOSYS;
}

/* clang-format off */
#define REG_NATIVE_FUNC(func_name, signature) \
{ #func_name, func_name##_wrapper, signature, NULL }
/* clang-format on */

static NativeSymbol native_symbols_lib_wasi_threads[] = { REG_NATIVE_FUNC(
thread_spawn, "(*)i") };

uint32
get_lib_wasi_threads_export_apis(NativeSymbol **p_lib_wasi_threads_apis)
{
*p_lib_wasi_threads_apis = native_symbols_lib_wasi_threads;
return sizeof(native_symbols_lib_wasi_threads) / sizeof(NativeSymbol);
}
6 changes: 6 additions & 0 deletions product-mini/platforms/linux/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,12 @@ if (NOT DEFINED WAMR_BUILD_LIB_PTHREAD)
set (WAMR_BUILD_LIB_PTHREAD 0)
endif ()

if (NOT DEFINED WAMR_BUILD_LIB_WASI_THREADS)
# Disable wasi threads library by default
set (WAMR_BUILD_LIB_WASI_THREADS 0)
endif()


if (NOT DEFINED WAMR_BUILD_MINI_LOADER)
# Disable wasm mini loader by default
set (WAMR_BUILD_MINI_LOADER 0)
Expand Down
87 changes: 87 additions & 0 deletions samples/wasi-threads/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -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

cmake_minimum_required(VERSION 3.14)

include(CheckPIESupported)

project(wasi_threads_sample)

if (NOT DEFINED WASI_SYSROOT)
message (WARNING "Custom sysroot with threads enabled is required to build wasi threads samples.
Please note that current wasi-sdk doesn't ship with threads enabled.
Run cmake command with -DWASI_SYSROOT=/path/to/sysroot/with/threads to compile samples.")
return ()
endif ()

################ runtime settings ################
string (TOLOWER ${CMAKE_HOST_SYSTEM_NAME} WAMR_BUILD_PLATFORM)
if (APPLE)
add_definitions(-DBH_PLATFORM_DARWIN)
endif ()

# Resetdefault linker flags
set(CMAKE_SHARED_LIBRARY_LINK_C_FLAGS "")
set(CMAKE_SHARED_LIBRARY_LINK_CXX_FLAGS "")

# WAMR features switch

# Set WAMR_BUILD_TARGET, currently values supported:
# "X86_64", "AMD_64", "X86_32", "AARCH64[sub]", "ARM[sub]", "THUMB[sub]",
# "MIPS", "XTENSA", "RISCV64[sub]", "RISCV32[sub]"
if (NOT DEFINED WAMR_BUILD_TARGET)
if (CMAKE_SYSTEM_PROCESSOR MATCHES "^(arm64|aarch64)")
set (WAMR_BUILD_TARGET "AARCH64")
elseif (CMAKE_SYSTEM_PROCESSOR STREQUAL "riscv64")
set (WAMR_BUILD_TARGET "RISCV64")
elseif (CMAKE_SIZEOF_VOID_P EQUAL 8)
# Build as X86_64 by default in 64-bit platform
set (WAMR_BUILD_TARGET "X86_64")
elseif (CMAKE_SIZEOF_VOID_P EQUAL 4)
# Build as X86_32 by default in 32-bit platform
set (WAMR_BUILD_TARGET "X86_32")
else ()
message(SEND_ERROR "Unsupported build target platform!")
endif ()
endif ()

if (NOT CMAKE_BUILD_TYPE)
set (CMAKE_BUILD_TYPE Release)
endif ()

set(WAMR_BUILD_INTERP 1)
set(WAMR_BUILD_AOT 1)
set(WAMR_BUILD_JIT 0)
set(WAMR_BUILD_LIBC_BUILTIN 1)
set(WAMR_BUILD_FAST_INTERP 1)
set(WAMR_BUILD_LIBC_WASI 1)
set(WAMR_BUILD_LIB_WASI_THREADS 1)

# compiling and linking flags
if (NOT (CMAKE_C_COMPILER MATCHES ".*clang.*" OR CMAKE_C_COMPILER_ID MATCHES ".*Clang"))
set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--gc-sections")
endif ()
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra -Wformat -Wformat-security")

# build out vmlib
set(WAMR_ROOT_DIR ${CMAKE_CURRENT_LIST_DIR}/../..)
include (${WAMR_ROOT_DIR}/build-scripts/runtime_lib.cmake)

add_library(vmlib ${WAMR_RUNTIME_LIB_SOURCE})
################################################


################ wasm application ################
add_subdirectory(wasm-apps)

################ wamr runtime ################
include (${SHARED_DIR}/utils/uncommon/shared_uncommon.cmake)

set (RUNTIME_SOURCE_ALL
${CMAKE_CURRENT_LIST_DIR}/../../product-mini/platforms/linux/main.c
${UNCOMMON_SHARED_SOURCE}
)
add_executable (iwasm ${RUNTIME_SOURCE_ALL})
check_pie_supported()
set_target_properties (iwasm PROPERTIES POSITION_INDEPENDENT_CODE ON)
target_link_libraries(iwasm vmlib -lpthread -lm -ldl)
1 change: 1 addition & 0 deletions samples/wasi-threads/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# "WASI threads" sample introduction
29 changes: 29 additions & 0 deletions samples/wasi-threads/wasm-apps/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# Copyright (C) 2022 Amazon.com, Inc. or its affiliates. All Rights Reserved.
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception

if (NOT DEFINED WASI_SDK_DIR)
set (WASI_SDK_DIR "/opt/wasi-sdk")
endif ()

set (CMAKE_SYSROOT "${WASI_SYSROOT}")
set (CMAKE_C_COMPILER "${WASI_SDK_DIR}/bin/clang")
set (CMAKE_C_COMPILER_TARGET "wasm32-wasi")

function (compile_sample SOURCE_FILE)
get_filename_component (FILE_NAME ${SOURCE_FILE} NAME_WLE)
set (WASM_MODULE ${FILE_NAME}.wasm)
add_executable (${WASM_MODULE} ${SOURCE_FILE})

target_compile_options (${WASM_MODULE} PRIVATE
-pthread -ftls-model=local-exec)

target_link_options (${WASM_MODULE} PRIVATE
-z stack-size=32768
LINKER:--export=__heap_base
LINKER:--export=__data_end
LINKER:--shared-memory,--max-memory=1966080
LINKER:--export=wasi_thread_start
)
endfunction ()

compile_sample(no_pthread.c)
55 changes: 55 additions & 0 deletions samples/wasi-threads/wasm-apps/no_pthread.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
/*
* 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 <wasi/api.h>

static const int64_t SECOND = 1000 * 1000 * 1000;

typedef struct {
int th_ready;
int value;
} shared_t;

__attribute__((export_name("wasi_thread_start"))) void
wasi_thread_start(int thread_id, int *start_arg)
{
shared_t *data = (shared_t *)start_arg;

printf("New thread ID: %d, starting parameter: %d\n", thread_id,
data->value);

data->value += 8;
printf("Updated value: %d\n", data->value);

data->th_ready = 1;
__builtin_wasm_memory_atomic_notify(&data->th_ready, 1);
}

int
main(int argc, char **argv)
{
shared_t data = { 0, 52 };
__wasi_errno_t err;

err = __wasi_thread_spawn(&data);
if (err != __WASI_ERRNO_SUCCESS) {
printf("Failed to create thread: %d\n", err);
return EXIT_FAILURE;
}

if (__builtin_wasm_memory_atomic_wait32(&data.th_ready, 0, SECOND) == 2) {
printf("Timeout\n");
return EXIT_FAILURE;
}

printf("Thread completed, new value: %d\n", data.value);

return EXIT_SUCCESS;
}

0 comments on commit 6d3c307

Please sign in to comment.