xref: /wasmtime-44.0.1/examples/threads.cc (revision 192f2fcd)
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