9f9d5894a668c7579cd91462d72be28acfd8b142
[platform/framework/web/lwnode.git] /
1 #include <inttypes.h>
2 #include <stdio.h>
3 #include <stdlib.h>
4 #include <string.h>
5 #include <pthread.h>
6 #include <unistd.h>
7
8 #include "wasm.h"
9
10 #define own
11
12 const int N_THREADS = 10;
13 const int N_REPS = 3;
14
15 // A function to be called from Wasm code.
16 own wasm_trap_t* callback(const wasm_val_t args[], wasm_val_t results[]) {
17   assert(args[0].kind == WASM_I32);
18   printf("> Thread %d running\n", args[0].of.i32);
19   return NULL;
20 }
21
22
23 typedef struct {
24   wasm_engine_t* engine;
25   wasm_shared_module_t* module;
26   int id;
27 } thread_args;
28
29 void* run(void* args_abs) {
30   thread_args* args = (thread_args*)args_abs;
31
32   // Rereate store and module.
33   own wasm_store_t* store = wasm_store_new(args->engine);
34   own wasm_module_t* module = wasm_module_obtain(store, args->module);
35
36   // Run the example N times.
37   for (int i = 0; i < N_REPS; ++i) {
38     usleep(100000);
39
40     // Create imports.
41     own wasm_functype_t* func_type = wasm_functype_new_1_0(wasm_valtype_new_i32());
42     own wasm_func_t* func = wasm_func_new(store, func_type, callback);
43     wasm_functype_delete(func_type);
44
45     wasm_val_t val = {.kind = WASM_I32, .of = {.i32 = (int32_t)args->id}};
46     own wasm_globaltype_t* global_type =
47       wasm_globaltype_new(wasm_valtype_new_i32(), WASM_CONST);
48     own wasm_global_t* global = wasm_global_new(store, global_type, &val);
49     wasm_globaltype_delete(global_type);
50
51     // Instantiate.
52     const wasm_extern_t* imports[] = {
53       wasm_func_as_extern(func), wasm_global_as_extern(global),
54     };
55     own wasm_instance_t* instance =
56       wasm_instance_new(store, module, imports, NULL);
57     if (!instance) {
58       printf("> Error instantiating module!\n");
59       return NULL;
60     }
61
62     wasm_func_delete(func);
63     wasm_global_delete(global);
64
65     // Extract export.
66     own wasm_extern_vec_t exports;
67     wasm_instance_exports(instance, &exports);
68     if (exports.size == 0) {
69       printf("> Error accessing exports!\n");
70       return NULL;
71     }
72     const wasm_func_t *run_func = wasm_extern_as_func(exports.data[0]);
73     if (run_func == NULL) {
74       printf("> Error accessing export!\n");
75       return NULL;
76     }
77
78     wasm_instance_delete(instance);
79
80     // Call.
81     if (wasm_func_call(run_func, NULL, NULL)) {
82       printf("> Error calling function!\n");
83       return NULL;
84     }
85
86     wasm_extern_vec_delete(&exports);
87   }
88
89   wasm_module_delete(module);
90   wasm_store_delete(store);
91
92   free(args_abs);
93
94   return NULL;
95 }
96
97 int main(int argc, const char *argv[]) {
98   // Initialize.
99   wasm_engine_t* engine = wasm_engine_new();
100
101   // Load binary.
102   FILE* file = fopen("threads.wasm", "r");
103   if (!file) {
104     printf("> Error loading module!\n");
105     return 1;
106   }
107   fseek(file, 0L, SEEK_END);
108   size_t file_size = ftell(file);
109   fseek(file, 0L, SEEK_SET);
110   wasm_byte_vec_t binary;
111   wasm_byte_vec_new_uninitialized(&binary, file_size);
112   if (fread(binary.data, file_size, 1, file) != 1) {
113     printf("> Error loading module!\n");
114     return 1;
115   }
116   fclose(file);
117
118   // Compile and share.
119   own wasm_store_t* store = wasm_store_new(engine);
120   own wasm_module_t* module = wasm_module_new(store, &binary);
121   if (!module) {
122     printf("> Error compiling module!\n");
123     return 1;
124   }
125
126   wasm_byte_vec_delete(&binary);
127
128   own wasm_shared_module_t* shared = wasm_module_share(module);
129
130   wasm_module_delete(module);
131   wasm_store_delete(store);
132
133   // Spawn threads.
134   pthread_t threads[N_THREADS];
135   for (int i = 0; i < N_THREADS; i++) {
136     thread_args* args = malloc(sizeof(thread_args));
137     args->id = i;
138     args->engine = engine;
139     args->module = shared;
140     printf("Initializing thread %d...\n", i);
141     pthread_create(&threads[i], NULL, &run, args);
142   }
143
144   for (int i = 0; i < N_THREADS; i++) {
145     printf("Waiting for thread: %d\n", i);
146     pthread_join(threads[i], NULL);
147   }
148
149   wasm_shared_module_delete(shared);
150   wasm_engine_delete(engine);
151
152   return 0;
153 }