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 25static 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/* 39static 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 46static 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 54static 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 64static 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 75static void print_ps(domainid_t* domains, size_t len) 76{ 77 errval_t err; 78 for(size_t i = 0; i < len; i++) { 79 struct spawn_ps_entry pse; 80 char *argbuf, status; 81 size_t arglen; 82 errval_t reterr; 83 84 err = spawn_get_status(domains[i], &pse, &argbuf, &arglen, &reterr); 85 if (err_is_fail(err)) { 86 USER_PANIC("PS FAILED \n"); 87 } 88 if(err_is_fail(reterr)) { 89 USER_PANIC("PS FAILED \n"); 90 } 91 92 switch(pse.status) { 93 case 0: 94 status = 'N'; 95 break; 96 97 case 1: 98 status = 'R'; 99 break; 100 101 case 2: 102 status = 'S'; 103 break; 104 105 case 3: 106 status = 'S'; 107 break; 108 109 default: 110 status = '?'; 111 break; 112 } 113 114 printf("%-8u\t%c\t", domains[i], status); 115 size_t pos = 0; 116 for(int p = 0; pos < arglen && p < MAX_CMDLINE_ARGS;) { 117 printf("%s ", &argbuf[pos]); 118 char *end = memchr(&argbuf[pos], '\0', arglen - pos); 119 assert(end != NULL); 120 pos = end - argbuf + 1; 121 } 122 printf("\n"); 123 124 free(argbuf); 125 } 126} 127 128static void run_benchmark_spawn(coreid_t target_core) 129{ 130 bench_init(); 131 132 cycles_t tsc_start, tsc_end; 133 cycles_t result; 134 uint64_t tscperus; 135 136 bench_ctl_t *ctl = calloc(1, sizeof(*ctl)); 137 ctl->mode = BENCH_MODE_FIXEDRUNS; 138 ctl->result_dimensions = 1; 139 ctl->min_runs = PROC_MGMT_BENCH_MIN_RUNS; 140 ctl->data = calloc(ctl->min_runs * ctl->result_dimensions, 141 sizeof(*ctl->data)); 142 143 errval_t err = sys_debug_get_tsc_per_ms(&tscperus); 144 assert(err_is_ok(err)); 145 tscperus /= 1000; 146 147 struct capref domain_cap; 148 149 char *spawn_argv[] = { "proc_mgmt_test", "0", "norun", NULL}; 150 do { 151 tsc_start = bench_tsc(); 152 153 test_spawn(target_core, spawn_argv, &domain_cap); 154 155 tsc_end = bench_tsc(); 156 result = calculate_time(tsc_start, tsc_end); 157 } while (!bench_ctl_add_run(ctl, &result)); 158 159 cap_destroy(domain_cap); 160 bench_ctl_dump_analysis(ctl, 0, "client", tscperus); 161 162 bench_ctl_destroy(ctl); 163} 164 165int main(int argc, char **argv) 166{ 167 errval_t err; 168 if (argc == 3) { 169 if (strcmp("starter", argv[2]) == 0) { 170 // just continue; 171 } else if (strcmp("norun", argv[2]) == 0) { 172 // directly return 173 return 0; 174 } else if (strcmp("run", argv[2]) == 0) { 175 // Run infinite loop 176 printf("Running infinite Loop"); 177 while(true) { 178 printf("Running infinite Loop"); 179 barrelfish_usleep(1000*1000); 180 event_dispatch_non_block(get_default_waitset()); 181 } 182 } else if (strcmp("sleeper", argv[2]) == 0) { 183 // Process that we wait for to finish 184 printf("Running for a few seconds \n"); 185 barrelfish_usleep(10*1000*1000); 186 printf("Sleeper exit\n"); 187 return 0; 188 } else if (strcmp("span", argv[2]) == 0) { 189 // Process that spans domains 190 if (disp_get_core_id() == 0) { 191 spawn_span(1); 192 } else { 193 spawn_span(0); 194 } 195 while(true) { 196 event_dispatch(get_default_waitset()); 197 } 198 } else { 199 USER_PANIC("Unknown Role \n "); 200 } 201 202 } else { 203 USER_PANIC("Not enough arguments to run test \n "); 204 } 205 206 struct capref domain_cap; 207 printf("Testing kill on same core\n"); 208 char *spawn_argv[] = { "proc_mgmt_test", "0", "run", NULL}; 209 err = test_spawn(disp_get_core_id(), spawn_argv, &domain_cap); 210 if (err_is_fail(err)) { 211 USER_PANIC("Failed spawning program proc_mgmt_test \n"); 212 } 213 214 //starting a process takes some time ... 215 barrelfish_usleep(5*1000*1000); 216 217 printf("Killing process \n"); 218 err = spawn_kill(domain_cap); 219 if (err_is_fail(err)) { 220 USER_PANIC("Failed waiting for domain \n"); 221 } 222 223 // Killing a process takes some time ... 224 barrelfish_usleep(5*1000*1000); 225 226 printf("Testing kill on other core\n"); 227 err = test_spawn(disp_get_core_id()+1, spawn_argv, &domain_cap); 228 if (err_is_fail(err)) { 229 USER_PANIC("Failed spawning program proc_mgmt_test \n"); 230 } 231 232 barrelfish_usleep(5*1000*1000); 233 234 printf("Killing process \n"); 235 err = spawn_kill(domain_cap); 236 if (err_is_fail(err)) { 237 USER_PANIC("Failed waiting for domain \n"); 238 } 239 240 // TODO check if process was killed 241 printf("Testing spaning on different core\n"); 242 char *spawn_argv3[] = { "proc_mgmt_test", "0", "span", NULL}; 243 err = test_spawn(disp_get_core_id()+1, spawn_argv3, &domain_cap); 244 if (err_is_fail(err)) { 245 USER_PANIC("Failed spawning program proc_mgmt_test \n"); 246 } 247 248 printf("Testing spaning on same core\n"); 249 err = test_spawn(disp_get_core_id(), spawn_argv3, &domain_cap); 250 if (err_is_fail(err)) { 251 USER_PANIC("Failed spawning program proc_mgmt_test \n"); 252 } 253 254 printf("Testing wait on different core process\n"); 255 char *spawn_argv2[] = { "proc_mgmt_test", "0", "sleeper"}; 256 err = test_spawn(disp_get_core_id()+1, spawn_argv2, &domain_cap); 257 if (err_is_fail(err)) { 258 USER_PANIC("Failed spawning program proc_mgmt_test \n"); 259 } 260 261 barrelfish_usleep(5*1000*1000); 262 263 uint8_t code; 264 printf("Waiting for process on different core to finish \n"); 265 err = spawn_wait(domain_cap, &code, false); 266 if (err_is_fail(err)) { 267 USER_PANIC("Failed waiting for domain \n"); 268 } 269 printf("Unblocked \n"); 270 271 printf("Testing wait on same core process\n"); 272 err = test_spawn(disp_get_core_id(), spawn_argv2, &domain_cap); 273 if (err_is_fail(err)) { 274 USER_PANIC("Failed spawning program proc_mgmt_test \n"); 275 } 276 277 barrelfish_usleep(5*1000*1000); 278 279 printf("Waiting for process on same core to finish \n"); 280 err = spawn_wait(domain_cap, &code, true); 281 if (err_is_fail(err)) { 282 USER_PANIC("Failed waiting for domain \n"); 283 } 284 printf("Nowait hang return code %d \n", code); 285 err = spawn_wait(domain_cap, &code, false); 286 if (err_is_fail(err)) { 287 USER_PANIC("Failed waiting for domain \n"); 288 } 289 printf("Unblocked \n"); 290 291 err = spawn_wait(domain_cap, &code, true); 292 if (err_is_fail(err)) { 293 USER_PANIC("Failed waiting for domain \n"); 294 } 295 printf("Nowait hang return code %d \n", code); 296 printf("Running benchmarks core 0 \n"); 297 run_benchmark_spawn(disp_get_core_id()); 298 printf("Running benchmarks core 1 \n"); 299 run_benchmark_spawn(disp_get_core_id()+1); 300 301 for (int j = 0; j < 10; j++) { 302 domainid_t* domains; 303 size_t len; 304 printf("Get domain list sorted \n"); 305 err = spawn_get_domain_list(true, &domains, &len); 306 if (err_is_fail(err)){ 307 USER_PANIC("Failed getting domain ids \n"); 308 } 309 310 print_ps(domains, len); 311 free(domains); 312 313 printf("Get domain list unsorted \n"); 314 err = spawn_get_domain_list(false, &domains, &len); 315 if (err_is_fail(err)){ 316 USER_PANIC("Failed getting domain ids \n"); 317 } 318 319 print_ps(domains, len); 320 321 free(domains); 322 } 323 printf("TEST DONE\n"); 324 return 0; 325} 326