proc_mgmt: implementation spawn_wait() with nohang flag
[barrelfish] / usr / tests / proc_mgmt_test / main.c
1 /** \file
2  *  \brief Process Management test.
3  */
4
5 /*
6  * Copyright (c) 2017, ETH Zurich.
7  * All rights reserved.
8  *
9  * This file is distributed under the terms in the attached LICENSE file.
10  * If you do not find this file, copies can be found by writing to:
11  * ETH Zurich D-INFK, Haldeneggsteig 4, CH-8092 Zurich. Attn: Systems Group.
12  */
13
14 #include <stdlib.h>
15
16 #include <barrelfish/barrelfish.h>
17 #include <barrelfish/deferred.h>
18 #include <barrelfish/sys_debug.h>
19 #include <barrelfish/spawn_client.h>
20 #include <bench/bench.h>
21
22 #define PROC_MGMT_BENCH 1
23 #define PROC_MGMT_BENCH_MIN_RUNS 20
24
25 static errval_t test_spawn(coreid_t core_id, char *argv[],
26                                struct capref *ret_domain_cap)
27 {
28         assert(ret_domain_cap != NULL);
29
30         errval_t err = spawn_program(core_id, "/x86_64/sbin/proc_mgmt_test",
31                                          argv, NULL, 0, ret_domain_cap);
32         if (err_is_fail(err)) {
33         return err;
34         }
35     return SYS_ERR_OK;
36 }
37
38 /*
39 static void test_span(coreid_t core_id)
40 {
41         errval_t err = proc_mgmt_span(core_id);
42         if (err_is_fail(err)) {
43     }
44 }
45
46 static void test_kill(struct capref domain_cap)
47 {
48         errval_t err = proc_mgmt_kill(domain_cap);
49         if (err_is_ok(err)) {
50         USER_PANIC("Failed killing domain")
51     }
52 }
53
54 static void test_wait(struct capref domain_cap)
55 {
56         uint8_t code;
57         errval_t err = proc_mgmt_wait(domain_cap, &code);
58         if (err_is_fail(err)) {
59         USER_PANIC("Failed waiting for domain");
60         }
61 }
62 */
63
64 static inline cycles_t calculate_time(cycles_t tsc_start, cycles_t tsc_end)
65 {
66     cycles_t result;
67     if (tsc_end < tsc_start) {
68         result = (LONG_MAX - tsc_start) + tsc_end - bench_tscoverhead();
69     } else {
70         result = (tsc_end - tsc_start - bench_tscoverhead());
71     }
72     return result;
73 }
74
75 static void run_benchmark_spawn(coreid_t target_core)
76 {
77     bench_init();
78
79     cycles_t tsc_start, tsc_end;
80     cycles_t result;
81     uint64_t tscperus;
82
83     bench_ctl_t *ctl = calloc(1, sizeof(*ctl));
84     ctl->mode = BENCH_MODE_FIXEDRUNS;
85     ctl->result_dimensions = 1;
86     ctl->min_runs = PROC_MGMT_BENCH_MIN_RUNS;
87     ctl->data = calloc(ctl->min_runs * ctl->result_dimensions,
88                        sizeof(*ctl->data));
89
90     errval_t err = sys_debug_get_tsc_per_ms(&tscperus);
91     assert(err_is_ok(err));
92     tscperus /= 1000;
93
94     struct capref domain_cap;
95
96     char *spawn_argv[] = { "proc_mgmt_test", "0", "norun", NULL};
97     do {
98         tsc_start = bench_tsc();
99
100         test_spawn(target_core, spawn_argv, &domain_cap);
101
102         tsc_end = bench_tsc();
103         result = calculate_time(tsc_start, tsc_end);
104     } while (!bench_ctl_add_run(ctl, &result));    
105
106     cap_destroy(domain_cap);
107     bench_ctl_dump_analysis(ctl, 0, "client", tscperus);
108
109     bench_ctl_destroy(ctl);
110 }
111
112 int main(int argc, char **argv)
113 {   
114     errval_t err;
115         if (argc == 3) {
116         if (strcmp("starter", argv[2]) == 0) {
117             // just continue;
118         } else if (strcmp("norun", argv[2]) == 0) {
119             // directly return
120             return 0;
121         } else if (strcmp("run", argv[2]) == 0) {   
122             // Run infinite loop
123             printf("Running infinite Loop");
124             while(true) {
125                 printf("Running infinite Loop");
126                 barrelfish_usleep(1000*1000);
127                 event_dispatch_non_block(get_default_waitset());
128             }
129         } else if (strcmp("sleeper", argv[2]) == 0) {
130             // Process that we wait for to finish
131             printf("Running for a few seconds \n");
132             barrelfish_usleep(10*1000*1000);
133             printf("Sleeper exit\n");
134             return 0;
135         } else if (strcmp("span", argv[2]) == 0) {
136             // Process that spans domains
137             if (disp_get_core_id() == 0) {
138                 spawn_span(1);
139             } else {
140                 spawn_span(0);
141             }
142             while(true) {
143                 event_dispatch(get_default_waitset());
144             }
145         } else {
146             USER_PANIC("Unknown Role \n ");
147         }
148
149         } else {
150         USER_PANIC("Not enough arguments to run test \n ");
151     }
152
153     struct capref domain_cap;
154     printf("Testing kill on same core\n");
155     char *spawn_argv[] = { "proc_mgmt_test", "0", "run", NULL};
156     err = test_spawn(2, spawn_argv, &domain_cap);
157     if (err_is_fail(err)) {
158         USER_PANIC("Failed spawning program proc_mgmt_test \n");
159     }  
160
161     //starting a process takes some time ...
162     barrelfish_usleep(5*1000*1000);
163
164     printf("Killing process \n");
165         err = spawn_kill(domain_cap);
166         if (err_is_fail(err)) {
167         USER_PANIC("Failed waiting for domain \n");
168         }
169  
170     // Killing a process takes some time ...
171     barrelfish_usleep(5*1000*1000);
172
173     printf("Testing kill on other core\n");
174     err = test_spawn(1, spawn_argv, &domain_cap);
175     if (err_is_fail(err)) {
176         USER_PANIC("Failed spawning program proc_mgmt_test \n");
177     }  
178
179     barrelfish_usleep(5*1000*1000);
180
181     printf("Killing process \n");
182         err = spawn_kill(domain_cap);
183         if (err_is_fail(err)) {
184         USER_PANIC("Failed waiting for domain \n");
185         }
186
187     // TODO check if process was killed
188     printf("Testing spaning on different core\n");
189     char *spawn_argv3[] = { "proc_mgmt_test", "0", "span", NULL};
190     err = test_spawn(0, spawn_argv3, &domain_cap);
191     if (err_is_fail(err)) {
192         USER_PANIC("Failed spawning program proc_mgmt_test \n");
193     }
194
195     printf("Testing spaning on same core\n");
196     err = test_spawn(2, spawn_argv3, &domain_cap);
197     if (err_is_fail(err)) {
198         USER_PANIC("Failed spawning program proc_mgmt_test \n");
199     }  
200
201     printf("Testing wait on different core process\n");
202     char *spawn_argv2[] = { "proc_mgmt_test", "0", "sleeper"};
203     err = test_spawn(0, spawn_argv2, &domain_cap);
204     if (err_is_fail(err)) {
205         USER_PANIC("Failed spawning program proc_mgmt_test \n");
206     }  
207  
208     barrelfish_usleep(5*1000*1000);
209     
210         uint8_t code;
211     printf("Waiting for process on different core to finish \n");
212         err = spawn_wait(domain_cap, &code, false);
213         if (err_is_fail(err)) {
214         USER_PANIC("Failed waiting for domain \n");
215         }
216     printf("Unblocked \n");
217
218     printf("Testing wait on same core process\n");
219     err = test_spawn(2, spawn_argv2, &domain_cap);
220     if (err_is_fail(err)) {
221         USER_PANIC("Failed spawning program proc_mgmt_test \n");
222     }  
223  
224     barrelfish_usleep(5*1000*1000);
225     
226     printf("Waiting for process on same core to finish \n");
227         err = spawn_wait(domain_cap, &code, true);
228         if (err_is_fail(err)) {
229         USER_PANIC("Failed waiting for domain \n");
230         }
231     printf("Nowait hang return code %d \n", code);
232         err = spawn_wait(domain_cap, &code, false);
233         if (err_is_fail(err)) {
234         USER_PANIC("Failed waiting for domain \n");
235         }
236     printf("Unblocked \n");
237
238         err = spawn_wait(domain_cap, &code, true);
239         if (err_is_fail(err)) {
240         USER_PANIC("Failed waiting for domain \n");
241         }
242     printf("Nowait hang return code %d \n", code);
243     printf("Running benchmarks core 0 \n");
244     run_benchmark_spawn(0);
245     printf("Running benchmarks core 3 \n");
246     run_benchmark_spawn(3);
247
248     printf("TEST DONE\n");
249     return 0;
250 }