1 /* 2 Example of instantiating of the WebAssembly module and invoking its exported 3 function in a separate thread. 4 5 You can build the example using CMake: 6 7 mkdir build && (cd build && cmake .. && \ 8 cmake --build . --target wasmtime-threads-cpp) 9 10 And then run it: 11 12 build/wasmtime-threads-cpp 13 */ 14 15 #include <fstream> 16 #include <iostream> 17 #include <mutex> 18 #include <sstream> 19 #include <thread> 20 #include <unordered_map> 21 #include <vector> 22 #include <wasmtime.hh> 23 24 using namespace wasmtime; 25 26 std::string readFile(const char *name) { 27 std::ifstream watFile; 28 watFile.open(name); 29 std::stringstream strStream; 30 strStream << watFile.rdbuf(); 31 return strStream.str(); 32 } 33 34 #if defined(WASMTIME_ASAN) 35 const int N_THREADS = 1; 36 const int N_REPS = 1; 37 #else 38 const int N_THREADS = 10; 39 const int N_REPS = 3; 40 #endif 41 42 std::mutex print_mutex; 43 44 void run_worker(Engine engine, Module module) { 45 std::thread::id id = std::this_thread::get_id(); 46 Store store(engine); 47 for (int i = 0; i < N_REPS; i++) { 48 { 49 std::lock_guard<std::mutex> lock(print_mutex); 50 std::cout << "Instantiating module...\n"; 51 } 52 Func hello_func = Func::wrap(store, []() { 53 std::lock_guard<std::mutex> lock(print_mutex); 54 std::thread::id id = std::this_thread::get_id(); 55 std::cout << "> Hello from ThreadId(" << id << ")\n"; 56 }); 57 auto instance_res = Instance::create(store, module, {hello_func}); 58 if (!instance_res) { 59 std::cout << "> Error instantiating module!\n"; 60 return; 61 } 62 Instance instance = instance_res.unwrap(); 63 Func run = std::get<Func>(*instance.get(store, "run")); 64 { 65 std::lock_guard<std::mutex> lock(print_mutex); 66 std::cout << "Executing...\n"; 67 } 68 run.call(store, {}).unwrap(); 69 std::this_thread::sleep_for(std::chrono::milliseconds(100)); 70 } 71 72 // Move store to a new thread once. 73 { 74 std::lock_guard<std::mutex> lock(print_mutex); 75 std::cout << "> Moving (" << id << ") to a new thread\n"; 76 } 77 auto handle = std::thread([store = std::move(store), module]() mutable { 78 Func hello_func = Func::wrap(store, []() { 79 std::lock_guard<std::mutex> lock(print_mutex); 80 std::thread::id id = std::this_thread::get_id(); 81 std::cout << "> Hello from ThreadId(" << id << ")\n"; 82 }); 83 Instance instance = Instance::create(store, module, {hello_func}).unwrap(); 84 Func run = std::get<Func>(*instance.get(store, "run")); 85 run.call(store, {}).unwrap(); 86 }); 87 handle.join(); 88 } 89 90 int main() { 91 std::cout << "Initializing...\n"; 92 93 Engine engine; 94 auto wat = readFile("examples/threads.wat"); 95 Module module = Module::compile(engine, wat).unwrap(); 96 97 std::vector<std::thread> threads; 98 threads.reserve(N_THREADS); 99 for (int i = 0; i < N_THREADS; i++) 100 threads.emplace_back(run_worker, engine, module); 101 for (auto &t : threads) 102 t.join(); 103 return 0; 104 } 105