diff --git a/.github/workflows/build-ubuntu.yml b/.github/workflows/build-ubuntu.yml index 0809603..2478f9f 100644 --- a/.github/workflows/build-ubuntu.yml +++ b/.github/workflows/build-ubuntu.yml @@ -26,19 +26,25 @@ jobs: - name: Checkout run: git submodule update --init - - name: Install WASI SDK + # - name: Install WASI SDK + # run: | + # cd /opt + # sudo wget https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-20/wasi-sdk-20.0-linux.tar.gz + # sudo tar -xzf wasi-sdk-*.tar.gz + # sudo mv wasi-sdk-20.0 wasi-sdk + + - name: Install Instrumented WASI SDK run: | cd /opt - sudo wget https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-20/wasi-sdk-20.0-linux.tar.gz + sudo wget https://asplos.dev/wasi-sdk-20.0-linux.tar.gz sudo tar -xzf wasi-sdk-*.tar.gz - sudo mv wasi-sdk-20.0 wasi-sdk - - name: Make WASM LD no check features - run: | - sudo mv /opt/wasi-sdk/bin/wasm-ld /opt/wasi-sdk/bin/wasm-ld.bak - echo '#!/bin/bash - /opt/wasi-sdk/bin/wasm-ld.bak --no-check-features "$@"' | sudo tee /opt/wasi-sdk/bin/wasm-ld - sudo chmod +x /opt/wasi-sdk/bin/wasm-ld + # - name: Make WASM LD no check features + # run: | + # sudo mv /opt/wasi-sdk/bin/wasm-ld /opt/wasi-sdk/bin/wasm-ld.bak + # echo '#!/bin/bash + # /opt/wasi-sdk/bin/wasm-ld.bak --no-check-features "$@"' | sudo tee /opt/wasi-sdk/bin/wasm-ld + # sudo chmod +x /opt/wasi-sdk/bin/wasm-ld - name: Make WASI Socket Ext run: | diff --git a/.gitmodules b/.gitmodules index 26d9e2a..ccc4a46 100644 --- a/.gitmodules +++ b/.gitmodules @@ -4,3 +4,12 @@ [submodule "lib/yalantinglibs"] path = lib/yalantinglibs url = https://github.com/alibaba/yalantinglibs +[submodule "bench/gapbs"] + path = bench/gapbs + url = https://github.com/victoryang00/gapbs.git +[submodule "bench/clickhouse"] + path = bench/clickhouse + url = https://github.com/victoryang00/ClickHouse.git +[submodule "bench/llama"] + path = bench/llama + url = https://github.com/second-state/WasmEdge-WASINN-examples diff --git a/CMakeLists.txt b/CMakeLists.txt index 0b6b094..e404aeb 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,11 +1,16 @@ cmake_minimum_required(VERSION 3.22) project(MVVM LANGUAGES C CXX) -set(CMAKE_CXX_STANDARD 23) +set(CMAKE_CXX_STANDARD 20) find_package(FMT REQUIRED) # find_package(LLVM REQUIRED) find_package(cxxopts REQUIRED) include(CTest) +if(WIN32) + set(WASI_SDK_DIR D:/wasi-sdk/) +else() + set(WASI_SDK_DIR /opt/wasi-sdk/) +endif() if(APPLE) set(WAMR_BUILD_PLATFORM "darwin") @@ -57,7 +62,7 @@ set(WAMR_BUILD_JIT 0) set(WAMR_BUILD_DEBUG_INTERP 0) set(WAMR_BUILD_DEBUG_AOT 0) set(WAMR_BUILD_FAST_JIT 0) -set(WAMR_BUILD_WASI_NN 0) +set(WAMR_BUILD_WASI_NN 1) set(WAMR_BUILD_LIBC_BUILTIN 1) set(WAMR_BUILD_LIBC_WASI 1) set(WAMR_BUILD_DUMP_CALL_STACK 1) @@ -98,4 +103,5 @@ add_definitions(-DMVVM_INTERP=1) add_definitions(-DMVVM_DEBUG=1) add_definitions(-DMVVM_WASI=1) add_definitions(-DCXXOPTS_NO_RTTI=1) -add_subdirectory(test) \ No newline at end of file +add_subdirectory(test) +add_subdirectory(bench) diff --git a/bench/CMakeLists.txt b/bench/CMakeLists.txt new file mode 100644 index 0000000..2fc3d5b --- /dev/null +++ b/bench/CMakeLists.txt @@ -0,0 +1,36 @@ +find_package(benchmark REQUIRED) +add_executable(mvvm_benchmark bench.cpp) + +# Link benchmark library to your test target +target_link_libraries(mvvm_benchmark benchmark) +include(ExternalProject) + +# add_subdirectory(gapbs) +# add_subdirectory(clickhouse) +# ExternalProject_Add(gapbs +# SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/gapbs +# UPDATE_COMMAND "" +# PATCH_COMMAND "" +# CONFIGURE_COMMAND ${CMAKE_COMMAND} +# -DCMAKE_C_COMPILER_WORKS=1 -DCMAKE_CXX_COMPILER_WORKS=1 +# -GNinja +# -DWASI_SDK_DIR=${WASI_SDK_DIR} +# -DCMAKE_TOOLCHAIN_FILE=${WASI_SDK_DIR}/share/cmake/wasi-sdk.cmake +# -DCMAKE_SYSROOT=${WASI_SDK_DIR}/share/wasi-sysroot +# ${CMAKE_CURRENT_SOURCE_DIR}/gapbs +# BUILD_COMMAND ${CMAKE_COMMAND} --build . +# ) + +# ExternalProject_Add(clickhouse +# SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/clickhouse +# UPDATE_COMMAND "" +# PATCH_COMMAND "" +# CONFIGURE_COMMAND ${CMAKE_COMMAND} +# -DCMAKE_C_COMPILER_WORKS=1 -DCMAKE_CXX_COMPILER_WORKS=1 +# -GNinja +# -DWASI_SDK_DIR=${WASI_SDK_DIR} +# -DCMAKE_TOOLCHAIN_FILE=${WASI_SDK_DIR}/share/cmake/wasi-sdk.cmake +# -DCMAKE_SYSROOT=${WASI_SDK_DIR}/share/wasi-sysroot +# ${CMAKE_CURRENT_SOURCE_DIR}/clickhouse +# BUILD_COMMAND ${CMAKE_COMMAND} --build . +# ) \ No newline at end of file diff --git a/bench/bench.cpp b/bench/bench.cpp new file mode 100644 index 0000000..019d6ee --- /dev/null +++ b/bench/bench.cpp @@ -0,0 +1,25 @@ +#include +#include + +static void BM_gapbs(benchmark::State& state) { + for (auto _ : state) { + // Your code to benchmark goes here + } +} +BENCHMARK(BM_gapbs); + +static void BM_clickhouse(benchmark::State& state) { + for (auto _ : state) { + // Your code to benchmark goes here + } +} +BENCHMARK(BM_clickhouse); + +static void BM_llama(benchmark::State& state) { + for (auto _ : state) { + // Your code to benchmark goes here + } +} +BENCHMARK(BM_llama); + +BENCHMARK_MAIN(); \ No newline at end of file diff --git a/bench/clickhouse b/bench/clickhouse new file mode 160000 index 0000000..5359dcc --- /dev/null +++ b/bench/clickhouse @@ -0,0 +1 @@ +Subproject commit 5359dcc014e0c3ee96122e2ac4a92231ce40d21d diff --git a/bench/gapbs b/bench/gapbs new file mode 160000 index 0000000..62258d0 --- /dev/null +++ b/bench/gapbs @@ -0,0 +1 @@ +Subproject commit 62258d0edb4fce97d1080a41444fb7abc987a123 diff --git a/bench/llama b/bench/llama new file mode 160000 index 0000000..b825987 --- /dev/null +++ b/bench/llama @@ -0,0 +1 @@ +Subproject commit b825987c4813d153f1d11b96aa7734c52408faf4 diff --git a/include/logging.h b/include/logging.h index b7836f1..4c69b72 100644 --- a/include/logging.h +++ b/include/logging.h @@ -18,7 +18,7 @@ #include #include #include -#include +#include #include using std::list; diff --git a/include/wamr.h b/include/wamr.h index a47fe08..0e91331 100644 --- a/include/wamr.h +++ b/include/wamr.h @@ -37,8 +37,6 @@ class WAMRInstance { uint32 buf_size{}, stack_size = 8092, heap_size = 8092; typedef struct ThreadArgs { wasm_exec_env_t exec_env; - wasm_thread_callback_t callback; - void *arg; } ThreadArgs; std::vector thread_arg; std::vector tid; diff --git a/include/wamr_export.h b/include/wamr_export.h index ac26524..2a87e54 100644 --- a/include/wamr_export.h +++ b/include/wamr_export.h @@ -21,7 +21,14 @@ void insert_lock(char const *, int); void insert_sem(char const *, int); void remove_lock(char const *); void remove_sem(char const *); +void wasm_thread_restart(); + void restart_execution(uint32 targs); +extern int pthread_create_wrapper(wasm_exec_env_t exec_env, uint32 *thread, /* thread_handle */ + const void *attr, /* not supported */ + uint32 elem_index, /* entry function */ + uint32 arg) /* arguments buffer */ + ; #ifdef __cplusplus } -#endif \ No newline at end of file +#endif diff --git a/src/checkpoint.cpp b/src/checkpoint.cpp index 1a91e8a..8a4cce7 100644 --- a/src/checkpoint.cpp +++ b/src/checkpoint.cpp @@ -18,8 +18,8 @@ WAMRInstance *wamr = nullptr; std::ostringstream re{}; auto writer = FwriteStream("test.bin"); -std::vector> as; -std::mutex as_mtx; +constinit std::vector> as; +constinit std::mutex as_mtx; /**fopen, fseek*/ void insert_fd(int fd, const char *path, int flags, int offset) { printf("\n #insert_fd(fd,filename,flags, offset) %d %s %d %d \n\n",fd, path,flags, offset); @@ -129,8 +129,6 @@ void serialize_to_file(WASMExecEnv *instance) { } stdoutput.close(); - // - std::cout<<"dasfasdfasf"<< re.str()<<"dasfasdfasf\n"; auto cluster = wasm_exec_env_get_cluster(instance); if (bh_list_length(&cluster->exec_env_list) > 1) { auto elem = (WASMExecEnv *)bh_list_first_elem(&cluster->exec_env_list); diff --git a/src/wamr.cpp b/src/wamr.cpp index a729e32..52945fe 100644 --- a/src/wamr.cpp +++ b/src/wamr.cpp @@ -4,9 +4,13 @@ #include "wamr.h" #include "thread_manager.h" +#include "wasm_exec_env.h" #include "wasm_interp.h" +#include "wasm_runtime.h" #include +WAMRInstance::ThreadArgs** argptr; + WAMRInstance::WAMRInstance(const char *wasm_path, bool is_jit) : is_jit(is_jit) { RuntimeInitArgs wasm_args; memset(&wasm_args, 0, sizeof(RuntimeInitArgs)); @@ -153,12 +157,26 @@ WASMModuleInstance *WAMRInstance::get_module_instance() { WASMModule *WAMRInstance::get_module() { return reinterpret_cast(reinterpret_cast(exec_env->module_inst)->module); } -void WAMRInstance::recover( - std::vector> *execEnv) { // will call pthread create wrapper if needed? + +void restart_execution(uint32 id){ + WAMRInstance::ThreadArgs* targs = argptr[id]; + wasm_interp_call_func_bytecode( + (WASMModuleInstance*)targs->exec_env->module_inst, + targs->exec_env, + targs->exec_env->cur_frame->function, + targs->exec_env->cur_frame->prev_frame); + +} + +// will call pthread create wrapper if needed? +void WAMRInstance::recover(std::vector> *execEnv) { + // order threads by id (descending) std::sort(execEnv->begin(), execEnv->end(), [](const std::unique_ptr &a, const std::unique_ptr &b) { return a->cur_count > b->cur_count; }); + argptr = (ThreadArgs**) malloc(sizeof(void*) * execEnv->size()); + uint32 id = 0; for (auto &&exec_ : *execEnv) { if (exec_->cur_count != 0) { @@ -168,14 +186,27 @@ void WAMRInstance::recover( // first get the deserializer message, here just hard code this->instantiate(); restore(exec_.get(), cur_env); + get_exec_env()->is_restore = true; cur_env->is_restore = true; if (exec_->cur_count != 0) { - auto thread_arg = - ThreadArgs{cur_env, nullptr, nullptr}; // requires to record the args and callback for the pthread. + + // requires to record the args and callback for the pthread. + auto thread_arg = ThreadArgs{cur_env}; + + argptr[id] = &thread_arg; + + // restart thread execution + pthread_create_wrapper(exec_env, nullptr, nullptr, id, id); + id++; + continue; } - get_exec_env()->is_restore = true; - wasm_interp_call_func_bytecode(get_module_instance(), get_exec_env(), get_exec_env()->cur_frame->function, - get_exec_env()->cur_frame->prev_frame); + if (exec_->cur_count == 0) { + // restart main thread execution + wasm_interp_call_func_bytecode(get_module_instance(), get_exec_env(), get_exec_env()->cur_frame->function, + get_exec_env()->cur_frame->prev_frame); + break; + } + assert(false); // main thread at end should be the } // every pthread has a semaphore for main thread to set all break point to start. } WASMFunction *WAMRInstance::get_func() { return static_cast(func); } @@ -209,45 +240,6 @@ void WAMRInstance::set_wasi_args(const std::vector &dir_list, const } void restart_execution(uint32 id) {} void WAMRInstance::set_wasi_args(WAMRWASIContext &context) { - // some handmade directory after recovery dir - // std::vector to_close; - // for (auto [fd, stat] : context.fd_map) { - // while (true) { - // // if the time is not socket - // int fd_; - // if (stat.second == 0) { - // auto dir_name = opendir(stat.first.c_str()); - // fd_ = dirfd(dir_name); - // } else { - // fd_ = open(stat.first.c_str(), O_RDWR); - // } - // if (fd > fd_) { - // // close(fd_); - // to_close.emplace_back(fd_); - // continue; - // } - // if (fd < fd_) { - // throw std::runtime_error("restore fd overflow"); - // } - // // remain socket. - // break; - // } - // } - // for (auto fd : to_close) { - // close(fd); - // } - /** refer to wasm bpf call function */ - - // auto get_dir_from_context = [](const WAMRWASIContext &wasiContext, bool is_map_dir = false) { - // auto cstrArray = std::vector(wasiContext.prestats.size); - // std::regex dir_replacer(".+?/"); - // std::transform(wasiContext.prestats.prestats.begin(), wasiContext.prestats.prestats.end(), - // cstrArray.begin(), - // [&is_map_dir, &dir_replacer](const WAMRFDPrestat &str) { - // return is_map_dir ? std::regex_replace(str.dir, dir_replacer, "") : str.dir; - // }); - // return cstrArray; - // }; auto get_addr_from_context = [](const WAMRWASIContext &wasiContext) { auto addr_pool = std::vector(wasiContext.addr_pool.size()); std::transform(wasiContext.addr_pool.begin(), wasiContext.addr_pool.end(), addr_pool.begin(), @@ -284,4 +276,4 @@ void WAMRInstance::instantiate() { throw; } cur_env = exec_env = wasm_runtime_create_exec_env(module_inst, stack_size); -} \ No newline at end of file +} diff --git a/src/wamr_wasi_context.cpp b/src/wamr_wasi_context.cpp index ebcf0de..ade43c5 100644 --- a/src/wamr_wasi_context.cpp +++ b/src/wamr_wasi_context.cpp @@ -13,8 +13,43 @@ void WAMRWASIContext::dump_impl(WASIContext *env) { } this->exit_code = env->exit_code; } -void WAMRWASIContext::restore_impl(WASIContext *env) { - for (auto [fd, res] : wamr->fd_map_) { +void WAMRWASIContext::git checkout main(WASIContext *env) { +#if 0 + // Need to open the file and reinitialize the file descripter by map. + env->curfds->size = this->curfds.size; + env->curfds->used = this->curfds.used; + env->curfds->entries = (fd_entry *)malloc(sizeof(wasi_fd_entry) * this->curfds.size); + + auto i = 0; + auto entries = (wasi_fd_entry *)env->curfds->entries; + for (auto &&entry : this->curfds.entries) { + entries[i].object = (wasi_fd_object *)malloc(sizeof(wasi_fd_object)); + if (entry.number) { + entries[i].object->type = entry.type; + entries[i].object->number = entry.number; + // need to open to this number + } + if (!entry.dir.empty()) { + entries[i].object->directory.handle = opendir(entry.dir.c_str()); + entries[i].object->directory.offset = entry.offset; + } + entries[i].rights_base = entry.rights_base; + entries[i].rights_inheriting = entry.rights_inheriting; + i++; + } + env->prestats->size = this->prestats.size; + env->prestats->used = this->prestats.used; + i = 0; + env->prestats->prestats = (fd_prestat *)malloc(sizeof(wasi_fd_prestat) * this->prestats.size); + auto prestats_ = (wasi_fd_prestat *)env->prestats->prestats; + for (auto &&pre : this->prestats.prestats) { + if (!pre.dir.empty()) { + prestats_[i].dir = pre.dir.c_str(); + } + i++; + } +#endif + for (auto [fd, res] : this->fd_map) { // differ from path from file wamr->invoke_fopen(fd, std::get<0>(res),std::get<1>(res)); wamr->invoke_fseek(fd, std::get<2>(res)); diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 56466b0..15ce21d 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -1,14 +1,9 @@ -if(WIN32) - set(HOST_PREFIX D:/wasi-sdk/bin/) -else() - set(HOST_PREFIX /opt/wasi-sdk/bin/) -endif() set(WAMR_DIR ${PROJECT_SOURCE_DIR}/lib/wasm-micro-runtime/) enable_testing() function(wamr_app input) - add_custom_target(${input}_wamr ALL COMMAND ${HOST_PREFIX}clang -Wno-implicit-function-declaration -Wno-int-conversion --target=wasm32-unknown-wasi -g -pthread -Wl,--allow-undefined-file=${WAMR_DIR}/wamr-sdk/app/libc-builtin-sysroot/share/defined-symbols.txt --sysroot=${HOST_PREFIX}/../share/wasi-sysroot ${CMAKE_CURRENT_SOURCE_DIR}/${input}.c -o ${CMAKE_CURRENT_BINARY_DIR}/${input}.wasm) + add_custom_target(${input}_wamr ALL COMMAND ${WASI_SDK_DIR}/bin/clang -Wno-implicit-function-declaration -Wno-int-conversion --target=wasm32-unknown-wasi -g -pthread -Wl,--allow-undefined-file=${WAMR_DIR}/wamr-sdk/app/libc-builtin-sysroot/share/defined-symbols.txt --sysroot=${WASI_SDK_DIR}/share/wasi-sysroot ${CMAKE_CURRENT_SOURCE_DIR}/${input}.c -o ${CMAKE_CURRENT_BINARY_DIR}/${input}.wasm) add_test(NAME ${input}_checkpoint COMMAND ${CMAKE_CURRENT_BINARY_DIR}/../MVVM_checkpoint --target ${CMAKE_CURRENT_BINARY_DIR}/${input}.wasm) - # add_test(NAME ${input}_restore COMMAND ${CMAKE_CURRENT_BINARY_DIR}/../MVVM_restore --target ${CMAKE_CURRENT_BINARY_DIR}/${input}.wasm) + add_test(NAME ${input}_restore COMMAND ${CMAKE_CURRENT_BINARY_DIR}/../MVVM_restore --target ${CMAKE_CURRENT_BINARY_DIR}/${input}.wasm) endfunction() wamr_app(counter) @@ -17,9 +12,9 @@ wamr_app(read-file) wamr_app(gups) function(wamr_socket_app input) - add_custom_target(${input}_wamr ALL COMMAND ${HOST_PREFIX}clang --target=wasm32-unknown-wasi -g -pthread -Wl,--allow-undefined-file=${WAMR_DIR}/wamr-sdk/app/libc-builtin-sysroot/share/defined-symbols.txt --sysroot=${HOST_PREFIX}/../share/wasi-sysroot ${WAMR_DIR}/samples/socket-api/wasm-app-prefix/src/wasm-app-build/libsocket_wasi_ext.a -I${WAMR_DIR}/core/iwasm/libraries/lib-socket/inc/ ${CMAKE_CURRENT_SOURCE_DIR}/${input}.c -o ${CMAKE_CURRENT_BINARY_DIR}/${input}.wasm) + add_custom_target(${input}_wamr ALL COMMAND ${WASI_SDK_DIR}/bin/clang --target=wasm32-unknown-wasi -g -pthread -Wl,--allow-undefined-file=${WAMR_DIR}/wamr-sdk/app/libc-builtin-sysroot/share/defined-symbols.txt --sysroot=${WASI_SDK_DIR}/share/wasi-sysroot ${WAMR_DIR}/samples/socket-api/wasm-app-prefix/src/wasm-app-build/libsocket_wasi_ext.a -I${WAMR_DIR}/core/iwasm/libraries/lib-socket/inc/ ${CMAKE_CURRENT_SOURCE_DIR}/${input}.c -o ${CMAKE_CURRENT_BINARY_DIR}/${input}.wasm) add_test(NAME ${input}_checkpoint COMMAND ${CMAKE_CURRENT_BINARY_DIR}/../MVVM_checkpoint --target ${CMAKE_CURRENT_BINARY_DIR}/${input}.wasm) - # add_test(NAME ${input}_restore COMMAND ${CMAKE_CURRENT_BINARY_DIR}/../MVVM_restore --target ${CMAKE_CURRENT_BINARY_DIR}/${input}.wasm) + add_test(NAME ${input}_restore COMMAND ${CMAKE_CURRENT_BINARY_DIR}/../MVVM_restore --target ${CMAKE_CURRENT_BINARY_DIR}/${input}.wasm) endfunction() wamr_socket_app(server) diff --git a/test/read-file.c b/test/read-file.c index bdaf628..fd966a2 100644 --- a/test/read-file.c +++ b/test/read-file.c @@ -7,6 +7,7 @@ #include #include #include +// #include FILE *fopen_test(const char *restrict filename, const char *restrict mode) { @@ -48,8 +49,6 @@ FILE *fopen_test(const char *restrict filename, const char *restrict mode) return 0; } - - int main() { FILE *file = fopen_test("./text.txt", "w"); @@ -58,6 +57,7 @@ int main() { // fseek(file,1,1); /** Test fread*/ + volatile int c = 0; FILE *file3 = fopen_test("./test.txt", "a"); const char* line1 = "This is line 1\n"; const char* line2 = "This is line 2\n"; @@ -66,17 +66,14 @@ int main() { fwrite(line1, sizeof(char), len1, file3); - - // volatile int c = 0; - // for( int i =0;i<10000;i++){ - // c++; - // } - + for( int i =0;i<10000;i++){ + c++; + } fwrite(line2, sizeof(char), len2, file3); - fprintf(file, "Successfully wrote to the file."); fclose(file); fclose(file1); fclose(file2); fclose(file3); -} \ No newline at end of file +} +