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