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 const int N_THREADS = 10; 35 const int N_REPS = 3; 36 37 std::mutex print_mutex; 38 39 void run_worker(Engine engine, Module module) { 40 std::thread::id id = std::this_thread::get_id(); 41 Store store(engine); 42 for (int i = 0; i < N_REPS; i++) { 43 { 44 std::lock_guard<std::mutex> lock(print_mutex); 45 std::cout << "Instantiating module...\n"; 46 } 47 Func hello_func = Func::wrap(store, []() { 48 std::lock_guard<std::mutex> lock(print_mutex); 49 std::thread::id id = std::this_thread::get_id(); 50 std::cout << "> Hello from ThreadId(" << id << ")\n"; 51 }); 52 auto instance_res = Instance::create(store, module, {hello_func}); 53 if (!instance_res) { 54 std::cout << "> Error instantiating module!\n"; 55 return; 56 } 57 Instance instance = instance_res.unwrap(); 58 Func run = std::get<Func>(*instance.get(store, "run")); 59 { 60 std::lock_guard<std::mutex> lock(print_mutex); 61 std::cout << "Executing...\n"; 62 } 63 run.call(store, {}).unwrap(); 64 std::this_thread::sleep_for(std::chrono::milliseconds(100)); 65 } 66 67 // Move store to a new thread once. 68 { 69 std::lock_guard<std::mutex> lock(print_mutex); 70 std::cout << "> Moving (" << id << ") to a new thread\n"; 71 } 72 auto handle = std::thread([store = std::move(store), module]() mutable { 73 Func hello_func = Func::wrap(store, []() { 74 std::lock_guard<std::mutex> lock(print_mutex); 75 std::thread::id id = std::this_thread::get_id(); 76 std::cout << "> Hello from ThreadId(" << id << ")\n"; 77 }); 78 Instance instance = Instance::create(store, module, {hello_func}).unwrap(); 79 Func run = std::get<Func>(*instance.get(store, "run")); 80 run.call(store, {}).unwrap(); 81 }); 82 handle.join(); 83 } 84 85 int main() { 86 std::cout << "Initializing...\n"; 87 88 Engine engine; 89 auto wat = readFile("examples/threads.wat"); 90 Module module = Module::compile(engine, wat).unwrap(); 91 92 std::vector<std::thread> threads; 93 threads.reserve(N_THREADS); 94 for (int i = 0; i < N_THREADS; i++) 95 threads.emplace_back(run_worker, engine, module); 96 for (auto &t : threads) 97 t.join(); 98 return 0; 99 } 100