Wenyong Huang 1 год назад
Родитель
Сommit
c4aa1deda5

+ 30 - 0
.github/scripts/codeql_buildscript.sh

@@ -126,6 +126,16 @@ if [[ $? != 0 ]]; then
     exit 1;
 fi
 
+# build iwasm with multi-memory enabled
+cd ${WAMR_DIR}/product-mini/platforms/linux
+rm -rf build && mkdir build && cd build
+cmake .. -DCMAKE_BUILD_TYPE=Debug -DWAMR_BUILD_MULTI_MEMORY=1
+make -j
+if [[ $? != 0 ]]; then
+    echo "Failed to build iwasm with multi-memory enabled!"
+    exit 1;
+fi
+
 # build iwasm with hardware boundary check disabled
 cd ${WAMR_DIR}/product-mini/platforms/linux
 rm -rf build && mkdir build && cd build
@@ -280,3 +290,23 @@ if [[ $? != 0 ]]; then
     echo "Failed to build iwasm with linux perf support enabled!"
     exit 1;
 fi
+
+# build iwasm with shared heap enabled
+cd ${WAMR_DIR}/product-mini/platforms/linux
+rm -rf build && mkdir build && cd build
+cmake .. -DCMAKE_BUILD_TYPE=Debug -DWAMR_BUILD_SHARED_HEAP=1
+make -j
+if [[ $? != 0 ]]; then
+    echo "Failed to build iwasm with shared heap enabled!"
+    exit 1;
+fi
+
+# build iwasm with dynamic aot debug enabled
+cd ${WAMR_DIR}/product-mini/platforms/linux
+rm -rf build && mkdir build && cd build
+cmake .. -DCMAKE_BUILD_TYPE=Debug -DWAMR_BUILD_DYNAMIC_AOT_DEBUG=1
+make -j
+if [[ $? != 0 ]];
+    echo "Failed to build iwasm dynamic aot debug enabled!"
+    exit 1;
+fi

+ 8 - 0
.github/workflows/compilation_on_android_ubuntu.yml

@@ -578,6 +578,14 @@ jobs:
           ./run.sh test1
           ./run.sh test2
 
+      - name: Build Sample [shared-heap]
+        run: |
+          cd samples/shared-heap
+          mkdir build && cd build
+          cmake ..
+          cmake --build . --config Debug --parallel 4
+          ./shared_heap_test
+
   test:
     needs:
       [

+ 8 - 0
.github/workflows/compilation_on_macos.yml

@@ -386,3 +386,11 @@ jobs:
           ./build.sh
           ./run.sh test1
           ./run.sh test2
+
+      - name: Build Sample [shared-heap]
+        run: |
+          cd samples/shared-heap
+          mkdir build && cd build
+          cmake ..
+          cmake --build . --config Debug --parallel 4
+          ./shared_heap_test

+ 8 - 0
.github/workflows/nightly_run.yml

@@ -593,6 +593,14 @@ jobs:
           exit $?
         working-directory: ./wamr-app-framework/samples/simple
 
+      - name: Build Sample [shared-heap]
+        run: |
+          cd samples/shared-heap
+          mkdir build && cd build
+          cmake ..
+          cmake --build . --config Debug --parallel 4
+          ./shared_heap_test
+
   test:
     needs:
       [

+ 1 - 1
build-scripts/config_common.cmake

@@ -498,7 +498,7 @@ if (WAMR_BUILD_MODULE_INST_CONTEXT EQUAL 1)
   message ("     Module instance context enabled")
 endif ()
 if (WAMR_BUILD_GC_HEAP_VERIFY EQUAL 1)
-  add_definitions (-DWASM_ENABLE_GC_VERIFY=1)
+  add_definitions (-DBH_ENABLE_GC_VERIFY=1)
   message ("     GC heap verification enabled")
 endif ()
 if ("$ENV{COLLECT_CODE_COVERAGE}" STREQUAL "1" OR COLLECT_CODE_COVERAGE EQUAL 1)

+ 1 - 1
core/iwasm/libraries/shared-heap/shared_heap_wrapper.c

@@ -54,4 +54,4 @@ get_lib_shared_heap_export_apis(NativeSymbol **p_shared_heap_apis)
 {
     *p_shared_heap_apis = native_symbols_shared_heap;
     return sizeof(native_symbols_shared_heap) / sizeof(NativeSymbol);
-}
+}

+ 92 - 0
samples/shared-heap/CMakeLists.txt

@@ -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 - 0
samples/shared-heap/src/main.c

@@ -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 - 0
samples/shared-heap/wasm-apps/CMakeLists.txt

@@ -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 - 0
samples/shared-heap/wasm-apps/test1.c

@@ -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 - 0
samples/shared-heap/wasm-apps/test2.c

@@ -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);
+}