Add shared heap sample (#3806)
This commit is contained in:
92
samples/shared-heap/CMakeLists.txt
Normal file
92
samples/shared-heap/CMakeLists.txt
Normal file
@ -0,0 +1,92 @@
|
||||
# Copyright (C) 2019 Intel Corporation. All rights reserved.
|
||||
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
|
||||
cmake_minimum_required (VERSION 3.14)
|
||||
|
||||
include(CheckPIESupported)
|
||||
|
||||
if (NOT WAMR_BUILD_PLATFORM STREQUAL "windows")
|
||||
project (shared_heap_test)
|
||||
else()
|
||||
project (shared_heap_test C ASM)
|
||||
endif()
|
||||
|
||||
################ runtime settings ################
|
||||
string (TOLOWER ${CMAKE_HOST_SYSTEM_NAME} WAMR_BUILD_PLATFORM)
|
||||
if (APPLE)
|
||||
add_definitions(-DBH_PLATFORM_DARWIN)
|
||||
endif ()
|
||||
|
||||
# Reset default 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 Debug)
|
||||
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_LIBC_WASI 0)
|
||||
set (WAMR_BUILD_SHARED_HEAP 1)
|
||||
set (WAMR_BUILD_GC_HEAP_VERIFY 1)
|
||||
|
||||
if (NOT MSVC)
|
||||
# linker 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")
|
||||
if (WAMR_BUILD_TARGET MATCHES "X86_.*" OR WAMR_BUILD_TARGET STREQUAL "AMD_64")
|
||||
if (NOT (CMAKE_C_COMPILER MATCHES ".*clang.*" OR CMAKE_C_COMPILER_ID MATCHES ".*Clang"))
|
||||
set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -mindirect-branch-register")
|
||||
endif ()
|
||||
endif ()
|
||||
endif ()
|
||||
|
||||
# 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})
|
||||
|
||||
################ application related ################
|
||||
include_directories(${CMAKE_CURRENT_LIST_DIR}/src)
|
||||
include (${SHARED_DIR}/utils/uncommon/shared_uncommon.cmake)
|
||||
|
||||
add_executable (shared_heap_test src/main.c ${UNCOMMON_SHARED_SOURCE})
|
||||
|
||||
check_pie_supported()
|
||||
set_target_properties (shared_heap_test PROPERTIES POSITION_INDEPENDENT_CODE ON)
|
||||
|
||||
if (APPLE)
|
||||
target_link_libraries (shared_heap_test vmlib -lm -ldl -lpthread)
|
||||
else ()
|
||||
target_link_libraries (shared_heap_test vmlib -lm -ldl -lpthread -lrt)
|
||||
endif ()
|
||||
|
||||
add_subdirectory(wasm-apps)
|
||||
309
samples/shared-heap/src/main.c
Normal file
309
samples/shared-heap/src/main.c
Normal file
@ -0,0 +1,309 @@
|
||||
/*
|
||||
* Copyright (C) 2019 Intel Corporation. All rights reserved.
|
||||
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
*/
|
||||
|
||||
#include "wasm_export.h"
|
||||
#include "bh_platform.h"
|
||||
#include "bh_read_file.h"
|
||||
|
||||
typedef struct thread_arg {
|
||||
bh_queue *queue;
|
||||
wasm_module_inst_t module_inst;
|
||||
} thread_arg;
|
||||
|
||||
static void *
|
||||
thread1_callback(void *arg)
|
||||
{
|
||||
thread_arg *targ = arg;
|
||||
wasm_module_inst_t module_inst = targ->module_inst;
|
||||
bh_queue *queue = targ->queue;
|
||||
wasm_exec_env_t exec_env;
|
||||
wasm_function_inst_t my_shared_malloc_func;
|
||||
wasm_function_inst_t my_shared_free_func;
|
||||
uint32 i, argv[2];
|
||||
|
||||
/* lookup wasm functions */
|
||||
if (!(my_shared_malloc_func =
|
||||
wasm_runtime_lookup_function(module_inst, "my_shared_malloc"))
|
||||
|| !(my_shared_free_func =
|
||||
wasm_runtime_lookup_function(module_inst, "my_shared_free"))) {
|
||||
printf("Failed to lookup function.\n");
|
||||
}
|
||||
|
||||
/* create exec env */
|
||||
if (!(exec_env = wasm_runtime_create_exec_env(module_inst, 32768))) {
|
||||
printf("Failed to create exec env.\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* allocate memory with wasm_runtime_shared_heap_malloc and send it
|
||||
to wasm app2 */
|
||||
for (i = 0; i < 5; i++) {
|
||||
uint8 *buf;
|
||||
uint64 offset;
|
||||
|
||||
offset = wasm_runtime_shared_heap_malloc(module_inst, 1024 * (i + 1),
|
||||
(void **)&buf);
|
||||
|
||||
if (offset == 0) {
|
||||
printf("Failed to allocate memory from shared heap\n");
|
||||
break;
|
||||
}
|
||||
|
||||
snprintf(buf, 1024, "Hello, this is buf %u allocated from shared heap",
|
||||
i + 1);
|
||||
|
||||
printf("wasm app1 send buf: %s\n\n", buf);
|
||||
if (!bh_post_msg(queue, 1, buf, 1024 * i)) {
|
||||
printf("Failed to post message to queue\n");
|
||||
wasm_runtime_shared_heap_free(module_inst, offset);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* allocate memory by calling my_shared_malloc function and send it
|
||||
to wasm app2 */
|
||||
for (i = 5; i < 10; i++) {
|
||||
uint8 *buf;
|
||||
|
||||
argv[0] = 1024 * (i + 1);
|
||||
argv[1] = i + 1;
|
||||
wasm_runtime_call_wasm(exec_env, my_shared_malloc_func, 2, argv);
|
||||
|
||||
if (wasm_runtime_get_exception(module_inst)) {
|
||||
printf("Failed to call 'my_shared_malloc` function: %s\n",
|
||||
wasm_runtime_get_exception(module_inst));
|
||||
break;
|
||||
}
|
||||
if (argv[0] == 0) {
|
||||
printf("Failed to allocate memory from shared heap\n");
|
||||
break;
|
||||
}
|
||||
|
||||
buf = wasm_runtime_addr_app_to_native(module_inst, argv[0]);
|
||||
|
||||
printf("wasm app1 send buf: %s\n\n", buf);
|
||||
if (!bh_post_msg(queue, 1, buf, 1024 * i)) {
|
||||
printf("Failed to post message to queue\n");
|
||||
wasm_runtime_shared_heap_free(module_inst, argv[0]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
wasm_runtime_destroy_exec_env(exec_env);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
queue_callback(void *message, void *arg)
|
||||
{
|
||||
bh_message_t msg = (bh_message_t)message;
|
||||
wasm_exec_env_t exec_env = arg;
|
||||
wasm_module_inst_t module_inst = wasm_runtime_get_module_inst(exec_env);
|
||||
wasm_function_inst_t print_buf_func;
|
||||
uint32 argv[2];
|
||||
|
||||
/* lookup wasm function */
|
||||
if (!(print_buf_func =
|
||||
wasm_runtime_lookup_function(module_inst, "print_buf"))) {
|
||||
printf("Failed to lookup function.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
char *buf = bh_message_payload(msg);
|
||||
printf("wasm app's native queue received buf: %s\n\n", buf);
|
||||
|
||||
/* call wasm function */
|
||||
argv[0] = wasm_runtime_addr_native_to_app(module_inst, buf);
|
||||
wasm_runtime_call_wasm(exec_env, print_buf_func, 1, argv);
|
||||
}
|
||||
|
||||
static void *
|
||||
thread2_callback(void *arg)
|
||||
{
|
||||
thread_arg *targ = arg;
|
||||
bh_queue *queue = targ->queue;
|
||||
wasm_module_inst_t module_inst = targ->module_inst;
|
||||
wasm_exec_env_t exec_env;
|
||||
|
||||
/* create exec env */
|
||||
if (!(exec_env = wasm_runtime_create_exec_env(module_inst, 32768))) {
|
||||
printf("Failed to create exec env.\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* enter queue's message loop until bh_queue_exit_loop_run
|
||||
is called */
|
||||
bh_queue_enter_loop_run(queue, queue_callback, exec_env);
|
||||
|
||||
wasm_runtime_destroy_exec_env(exec_env);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static char global_heap_buf[512 * 1024];
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
char *wasm_file1 = NULL, *wasm_file2 = NULL;
|
||||
uint8 *wasm_file1_buf = NULL, *wasm_file2_buf = NULL;
|
||||
uint32 wasm_file1_size, wasm_file2_size;
|
||||
wasm_module_t wasm_module1 = NULL, wasm_module2 = NULL;
|
||||
wasm_module_inst_t module_inst1 = NULL;
|
||||
wasm_module_inst_t module_inst2 = NULL;
|
||||
wasm_shared_heap_t shared_heap = NULL;
|
||||
bh_queue *queue = NULL;
|
||||
RuntimeInitArgs init_args;
|
||||
SharedHeapInitArgs heap_init_args;
|
||||
char error_buf[128] = { 0 };
|
||||
int ret = -1;
|
||||
|
||||
memset(&init_args, 0, sizeof(RuntimeInitArgs));
|
||||
|
||||
init_args.mem_alloc_type = Alloc_With_Pool;
|
||||
init_args.mem_alloc_option.pool.heap_buf = global_heap_buf;
|
||||
init_args.mem_alloc_option.pool.heap_size = sizeof(global_heap_buf);
|
||||
|
||||
/* init wasm runtime */
|
||||
if (!wasm_runtime_full_init(&init_args)) {
|
||||
printf("Init runtime environment failed.\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* create queue */
|
||||
if (!(queue = bh_queue_create())) {
|
||||
printf("Create queue failed.\n");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* read wasm file */
|
||||
wasm_file1 = "./wasm-apps/test1.wasm";
|
||||
if (!(wasm_file1_buf =
|
||||
bh_read_file_to_buffer(wasm_file1, &wasm_file1_size))) {
|
||||
printf("Open wasm file %s failed.\n", wasm_file1);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* load wasm file */
|
||||
wasm_module1 = wasm_runtime_load((uint8 *)wasm_file1_buf, wasm_file1_size,
|
||||
error_buf, sizeof(error_buf));
|
||||
if (!wasm_module1) {
|
||||
printf("Load wasm module failed. error: %s\n", error_buf);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* instantiate module */
|
||||
module_inst1 = wasm_runtime_instantiate(wasm_module1, 65536, 0, error_buf,
|
||||
sizeof(error_buf));
|
||||
if (!module_inst1) {
|
||||
printf("Instantiate wasm module failed. error: %s\n", error_buf);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* read wasm file */
|
||||
wasm_file2 = "./wasm-apps/test2.wasm";
|
||||
if (!(wasm_file2_buf =
|
||||
bh_read_file_to_buffer(wasm_file2, &wasm_file2_size))) {
|
||||
printf("Open wasm file %s failed.\n", wasm_file1);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* load wasm file */
|
||||
wasm_module2 = wasm_runtime_load((uint8 *)wasm_file2_buf, wasm_file2_size,
|
||||
error_buf, sizeof(error_buf));
|
||||
if (!wasm_module2) {
|
||||
printf("Load wasm module failed. error: %s\n", error_buf);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* instantiate module */
|
||||
module_inst2 = wasm_runtime_instantiate(wasm_module2, 65536, 0, error_buf,
|
||||
sizeof(error_buf));
|
||||
if (!module_inst2) {
|
||||
printf("Instantiate wasm module failed. error: %s\n", error_buf);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* create shared heap */
|
||||
memset(&heap_init_args, 0, sizeof(heap_init_args));
|
||||
heap_init_args.size = 65536;
|
||||
shared_heap = wasm_runtime_create_shared_heap(&heap_init_args);
|
||||
if (!shared_heap) {
|
||||
printf("Create shared heap failed. error: %s\n", error_buf);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* attach module instance 1 to the shared heap */
|
||||
if (!wasm_runtime_attach_shared_heap(module_inst1, shared_heap)) {
|
||||
printf("Attach shared heap failed.\n");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* attach module instance 2 to the shared heap */
|
||||
if (!wasm_runtime_attach_shared_heap(module_inst2, shared_heap)) {
|
||||
printf("Attach shared heap failed.\n");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* create thread 1 */
|
||||
struct thread_arg targ1 = { 0 };
|
||||
korp_tid tid1;
|
||||
targ1.queue = queue;
|
||||
targ1.module_inst = module_inst1;
|
||||
if (os_thread_create(&tid1, thread1_callback, &targ1,
|
||||
APP_THREAD_STACK_SIZE_DEFAULT)) {
|
||||
printf("Failed to create thread 1\n");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* create thread 2 */
|
||||
struct thread_arg targ2 = { 0 };
|
||||
korp_tid tid2;
|
||||
targ2.queue = queue;
|
||||
targ2.module_inst = module_inst2;
|
||||
if (os_thread_create(&tid2, thread2_callback, &targ2,
|
||||
APP_THREAD_STACK_SIZE_DEFAULT)) {
|
||||
printf("Failed to create thread 2\n");
|
||||
os_thread_join(tid1, NULL);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* wait until all messages are post to wasm app2 and wasm app2
|
||||
handles all of them, then exit the queue message loop */
|
||||
usleep(2000);
|
||||
bh_queue_exit_loop_run(queue);
|
||||
|
||||
os_thread_join(tid1, NULL);
|
||||
os_thread_join(tid2, NULL);
|
||||
|
||||
ret = 0;
|
||||
|
||||
fail:
|
||||
if (module_inst2)
|
||||
wasm_runtime_deinstantiate(module_inst2);
|
||||
|
||||
if (module_inst1)
|
||||
wasm_runtime_deinstantiate(module_inst1);
|
||||
|
||||
if (wasm_module2)
|
||||
wasm_runtime_unload(wasm_module2);
|
||||
|
||||
if (wasm_module1)
|
||||
wasm_runtime_unload(wasm_module1);
|
||||
|
||||
if (wasm_file2_buf)
|
||||
wasm_runtime_free(wasm_file2_buf);
|
||||
|
||||
if (wasm_file1_buf)
|
||||
wasm_runtime_free(wasm_file1_buf);
|
||||
|
||||
if (queue)
|
||||
bh_queue_destroy(queue);
|
||||
|
||||
wasm_runtime_destroy();
|
||||
|
||||
return ret;
|
||||
}
|
||||
43
samples/shared-heap/wasm-apps/CMakeLists.txt
Normal file
43
samples/shared-heap/wasm-apps/CMakeLists.txt
Normal file
@ -0,0 +1,43 @@
|
||||
# Copyright (C) 2019 Intel Corporation. All rights reserved.
|
||||
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
|
||||
cmake_minimum_required(VERSION 3.14)
|
||||
project(wasm-apps)
|
||||
|
||||
set(WAMR_ROOT_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../../..)
|
||||
|
||||
if (APPLE)
|
||||
set (HAVE_FLAG_SEARCH_PATHS_FIRST 0)
|
||||
set (CMAKE_C_LINK_FLAGS "")
|
||||
set (CMAKE_CXX_LINK_FLAGS "")
|
||||
endif ()
|
||||
|
||||
set (CMAKE_SYSTEM_PROCESSOR wasm32)
|
||||
set (CMAKE_SYSROOT ${WAMR_ROOT_DIR}/wamr-sdk/app/libc-builtin-sysroot)
|
||||
|
||||
if (NOT DEFINED WASI_SDK_DIR)
|
||||
set (WASI_SDK_DIR "/opt/wasi-sdk")
|
||||
endif ()
|
||||
|
||||
set (CMAKE_C_FLAGS "-nostdlib -Qunused-arguments -z stack-size=32768")
|
||||
set (CMAKE_C_COMPILER_TARGET "wasm32")
|
||||
set (CMAKE_C_COMPILER "${WASI_SDK_DIR}/bin/clang")
|
||||
|
||||
set (DEFINED_SYMBOLS "${WAMR_ROOT_DIR}/wamr-sdk/app/libc-builtin-sysroot/share/defined-symbols.txt")
|
||||
|
||||
set (CMAKE_EXE_LINKER_FLAGS
|
||||
"-Wl,--initial-memory=65536, \
|
||||
-Wl,--no-entry,--strip-all, \
|
||||
-Wl,--export=__heap_base,--export=__data_end \
|
||||
-Wl,--export=__wasm_call_ctors \
|
||||
-Wl,--export=my_shared_malloc \
|
||||
-Wl,--export=my_shared_free \
|
||||
-Wl,--export=print_buf \
|
||||
-Wl,--allow-undefined"
|
||||
)
|
||||
|
||||
add_executable(test1.wasm test1.c)
|
||||
target_link_libraries(test1.wasm)
|
||||
|
||||
add_executable(test2.wasm test2.c)
|
||||
target_link_libraries(test2.wasm)
|
||||
30
samples/shared-heap/wasm-apps/test1.c
Normal file
30
samples/shared-heap/wasm-apps/test1.c
Normal file
@ -0,0 +1,30 @@
|
||||
/*
|
||||
* Copyright (C) 2019 Intel Corporation. All rights reserved.
|
||||
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
|
||||
extern void *
|
||||
shared_malloc(uint32_t size);
|
||||
extern void
|
||||
shared_free(void *ptr);
|
||||
|
||||
void *
|
||||
my_shared_malloc(uint32_t size, uint32_t index)
|
||||
{
|
||||
char *buf = shared_malloc(size);
|
||||
|
||||
if (buf)
|
||||
snprintf(buf, 1024, "Hello, this is buf %u allocated from shared heap",
|
||||
index);
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
void
|
||||
my_shared_free(void *ptr)
|
||||
{
|
||||
shared_free(ptr);
|
||||
}
|
||||
18
samples/shared-heap/wasm-apps/test2.c
Normal file
18
samples/shared-heap/wasm-apps/test2.c
Normal file
@ -0,0 +1,18 @@
|
||||
/*
|
||||
* Copyright (C) 2019 Intel Corporation. All rights reserved.
|
||||
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
extern void
|
||||
shared_free(void *ptr);
|
||||
|
||||
void
|
||||
print_buf(char *buf)
|
||||
{
|
||||
printf("wasm app2's wasm func received buf: %s\n\n", buf);
|
||||
shared_free(buf);
|
||||
}
|
||||
Reference in New Issue
Block a user