errval_t start_networking(coreid_t core, struct module_info* driver, char* record) { assert(driver != NULL); errval_t err = SYS_ERR_OK; if (is_started(driver)) { return KALUGA_ERR_DRIVER_ALREADY_STARTED; } if (!is_auto_driver(driver)) { return KALUGA_ERR_DRIVER_NOT_AUTO; } struct module_info* netd = find_module("netd"); if (netd == NULL || !is_auto_driver(netd)) { KALUGA_DEBUG("netd not found or not declared as auto."); return KALUGA_ERR_DRIVER_NOT_AUTO; } struct module_info* ngd_mng = find_module("NGD_mng"); if (ngd_mng == NULL || !is_auto_driver(ngd_mng)) { KALUGA_DEBUG("NGD_mng not found or not declared as auto."); return KALUGA_ERR_DRIVER_NOT_AUTO; } err = spawn_program(core, driver->path, driver->argv + 1, environ, 0, &driver->did); if (err_is_fail(err)) { DEBUG_ERR(err, "Spawning %s failed.", driver->path); return err; } // XXX: Manually add cardname (overwrite first (auto) argument) // +Weird convention, e1000n binary but cardname=e1000 char* cardname = strcmp(driver->binary, "e1000n") == 0 ? "e1000" : driver->binary; size_t name_len = strlen("cardname=") + strlen(cardname) + 1; char* card_argument = malloc(name_len); sprintf(card_argument, "cardname=%s", cardname); printf("############# starting network with argiments %s\n", card_argument); // Spawn netd and ngd_mng netd->argv[0] = card_argument; err = spawn_program(core, netd->path, netd->argv, environ, 0, &netd->did); ngd_mng->argv[0] = card_argument; err = spawn_program(core, ngd_mng->path, ngd_mng->argv, environ, 0, &ngd_mng->did); free(card_argument); return err; }
errval_t default_start_function(coreid_t where, struct module_info* mi, char* record) { assert(mi != NULL); errval_t err = SYS_ERR_OK; coreid_t core; /* * XXX: there may be more device using this driver, so starting it a second time * may be needed. */ if (!can_start(mi)) { return KALUGA_ERR_DRIVER_ALREADY_STARTED; } core = where + get_core_id_offset(mi); if (!is_auto_driver(mi)) { return KALUGA_ERR_DRIVER_NOT_AUTO; } // Construct additional command line arguments containing pci-id. // We need one extra entry for the new argument. uint64_t vendor_id, device_id, bus, dev, fun; char **argv = mi->argv; bool cleanup = false; err = oct_read(record, "_ { bus: %d, device: %d, function: %d, vendor: %d, device_id: %d }", &bus, &dev, &fun, &vendor_id, &device_id); if (err_is_ok(err)) { // We assume that we're starting a device if the query above succeeds // and therefore append the pci vendor and device id to the argument // list. argv = malloc((mi->argc+1) * sizeof(char *)); memcpy(argv, mi->argv, mi->argc * sizeof(char *)); char *pci_id = malloc(26); // Make sure pci vendor and device id fit into our argument assert(vendor_id < 0x9999 && device_id < 0x9999); snprintf(pci_id, 26, "%04"PRIx64":%04"PRIx64":%04"PRIx64":%04" PRIx64":%04"PRIx64, vendor_id, device_id, bus, dev, fun); argv[mi->argc] = pci_id; argv[mi->argc+1] = NULL; cleanup = true; } err = spawn_program(core, mi->path, argv, environ, 0, get_did_ptr(mi)); if (err_is_fail(err)) { DEBUG_ERR(err, "Spawning %s failed.", mi->path); } if (cleanup) { // alloc'd string is the last of our array free(argv[mi->argc]); free(argv); } return err; }
int main(int argc, char *argv[]) { errval_t err; /* Set my core id */ my_core_id = disp_get_core_id(); strcpy(my_name, argv[0]); printf("entered\n"); bench_init(); printf("bench_init done\n"); if (argc == 1) { /* server */ /* 1. spawn domain, 2. setup a server, 3. wait for client to connect, 4. run experiment */ char *xargv[] = { my_name, "dummy", "dummy", "dummy", NULL }; err = spawn_program(1, my_name, xargv, NULL, SPAWN_FLAGS_DEFAULT, NULL); assert(err_is_ok(err)); /* Setup a server */ err = bench_export(NULL, export_cb, connect_cb, get_default_waitset(), IDC_BIND_FLAGS_DEFAULT); assert(err_is_ok(err)); } else { /* Connect to the server */ printf("ns lookup\n"); err = nameservice_blocking_lookup("multihop_server", &iref); if (err_is_fail(err)) { DEBUG_ERR(err, "nameservice_blocking_lookup failed"); abort(); } printf("bench_bind\n"); // bind a first time for signaling err = bench_bind(iref, bind_signal_cb, NULL, get_default_waitset(), IDC_BIND_FLAGS_DEFAULT); if (err_is_fail(err)) { DEBUG_ERR(err, "bind failed"); abort(); } } messages_handler_loop(); return 0; }
int main(int argc, char *argv[]) { errval_t err; coreid_t mycore = disp_get_core_id(); debug_printf("This is mem_bench\n"); if (argc >= 2) { assert(mycore == 0); int num_cores = strtol(argv[1], NULL, 10); debug_printf("spawning on %d cores\n", num_cores); err = init_tracing(); if (err_is_fail(err)) { DEBUG_ERR(err, "initialising tracing"); return EXIT_FAILURE; } prepare_dump(); start_tracing(); char *path = argv[0]; argv[1] = NULL; for (int i = 1; i <= num_cores; i++) { err = spawn_program(i, path, argv, NULL, 0, NULL); if (err_is_fail(err)) { DEBUG_ERR(err, "failed spawn %d", i); return EXIT_FAILURE; } debug_printf("spawned on core %d\n", i); } //start_tracing(); run_benchmark_0(mycore); ns_barrier_master(1, num_cores, "mem_bench"); debug_printf("all benchmarks completed\n"); stop_tracing(); // dump_trace(); } else { run_benchmark(mycore); } return EXIT_SUCCESS; }
errval_t default_start_function(coreid_t where, struct module_info* mi, char* record) { assert(mi != NULL); errval_t err = SYS_ERR_OK; if (is_started(mi)) { return KALUGA_ERR_DRIVER_ALREADY_STARTED; } if (!is_auto_driver(mi)) { return KALUGA_ERR_DRIVER_NOT_AUTO; } // Construct additional command line arguments containing pci-id. // We need one extra entry for the new argument. uint64_t vendor_id, device_id; char **argv = mi->argv; bool cleanup = false; err = oct_read(record, "_ { vendor: %d, device_id: %d }", &vendor_id, &device_id); if (err_is_ok(err)) { // We assume that we're starting a device if the query above succeeds // and therefore append the pci vendor and device id to the argument // list. argv = malloc((mi->argc+1) * sizeof(char *)); memcpy(argv, mi->argv, mi->argc * sizeof(char *)); char *pci_id = malloc(10); // Make sure pci vendor and device id fit into our argument assert(vendor_id < 0x9999 && device_id < 0x9999); snprintf(pci_id, 10, "%04"PRIx64":%04"PRIx64, vendor_id, device_id); argv[mi->argc] = pci_id; mi->argc += 1; argv[mi->argc] = NULL; cleanup = true; } err = spawn_program(where, mi->path, argv, environ, 0, &mi->did); if (err_is_fail(err)) { DEBUG_ERR(err, "Spawning %s failed.", mi->path); } if (cleanup) { // alloc'd string is the last of our array free(argv[mi->argc-1]); free(argv); } return err; }
static errval_t spawn_other_cores(int argc, char *argv[]) { errval_t err; char core_id_char[32]; snprintf(core_id_char, sizeof(core_id_char), "%d", num_cores); core_id_char[sizeof(core_id_char) - 1] = '\0'; char *xargv[] = {argv[0], "client", core_id_char, NULL}; for (int i=1; i<num_cores; i++) { /* XXX: assumes core IDs are 0-based and contiguous */ err = spawn_program(i, xargv[0], xargv, NULL, SPAWN_FLAGS_DEFAULT, NULL); if (err_is_fail(err)) { DEBUG_ERR(err, "error spawning other core"); abort(); } } return SYS_ERR_OK; }
static int execute_program(coreid_t coreid, int argc, char *argv[], domainid_t *retdomainid) { vfs_handle_t vh; errval_t err; // if the name contains a directory separator, assume it is relative to PWD char *prog = argv[0]; if (strchr(argv[0], VFS_PATH_SEP) != NULL) { prog = vfs_path_mkabsolute(cwd, argv[0]); // check it exists err = vfs_open(prog, &vh); if (err_is_fail(err)) { printf("%s: file not found: %s\n", prog, err_getstring(err)); free(prog); return -1; } vfs_close(vh); } assert(retdomainid != NULL); argv[argc] = NULL; err = spawn_program(coreid, prog, argv, NULL, SPAWN_NEW_DOMAIN, retdomainid); if (prog != argv[0]) { free(prog); } if (err_is_fail(err)) { printf("%s: error spawning: %s\n", argv[0], err_getstring(err)); DEBUG_ERR(err, "Spawning Error\n"); return -1; } return 0; }
static void start_run(uint8_t core, uint8_t memory, int payload, int nocache, int read_incoming, int head_idx_wb) { errval_t r; domainid_t new_domain; uint8_t code; char plsz[strlen("payload_size=0000") + 1]; char noca[strlen("elb_nocache=0") + 1]; char rdic[strlen("read_incoming=0") + 1]; char hiwb[strlen("head_idx_wb=0") + 1]; char affmin[64]; char affmax[64]; char prefix[128]; uint64_t aff_min, aff_max; memory_affinity(memory, &aff_min, &aff_max); char* const argv[] = { "e10k_queue_elb", "queue=0", "runs=1000", "dump_each=1", plsz, noca, rdic, hiwb, affmin, affmax, prefix, NULL }; sprintf(plsz, "payload_size=%d", payload); sprintf(plsz, "elb_nocache=%d", nocache); sprintf(rdic, "read_incoming=%d", read_incoming); sprintf(hiwb, "head_idx_wb=%d", head_idx_wb); sprintf(affmin, "affinitymin=%"PRIu64, aff_min); sprintf(affmax, "affinitymax=%"PRIu64, aff_max); sprintf(prefix, "elp_outprefix=%%%d,%d,%d,%d,%d,%d,", core, memory, payload, nocache, read_incoming, head_idx_wb); printf("##### spawning programm %s\n", argv[0]); r = spawn_program(core, argv[0], argv, NULL, SPAWN_FLAGS_NEW_DOMAIN, &new_domain); assert(err_is_ok(r)); r = spawn_wait_core(core, new_domain, &code, false); assert(err_is_ok(r)); }
void setup_routes(int argc, char **argv) { errval_t err; struct monitor_binding *st = get_monitor_binding(); /* printf("%s: setup_routes\n", argv[0]); */ /* Set core id */ my_core_id = disp_get_core_id(); strcpy(my_name, argv[0]); // Get number of cores coreid_t cores = atoi(argv[1]); // Get list of present cores for(int i = 3; i < argc; i++) { set_present(argv[i]); } if (strcmp(argv[argc - 1], "dummy")) { /* bsp core */ // Spawn all copies bsp_id = my_core_id; /* Spawn on all cores */ char *spawnargv[argc + 2]; for (int i = 0; i < argc; i++) { spawnargv[i] = argv[i]; } spawnargv[argc] = "dummy"; spawnargv[argc + 1] = NULL; for(coreid_t i = 0; i < MAX_CPUS; i++) { if(core_present[i] && i != my_core_id) { err = spawn_program(i, my_name, spawnargv, NULL, SPAWN_FLAGS_DEFAULT, NULL); assert(err_is_ok(err)); } } } /* printf("%s: exporting service\n", argv[0]); */ /* Setup a server */ request_done = false; err = rcce_export(NULL, _listening, _connected, get_default_waitset(), IDC_EXPORT_FLAGS_DEFAULT); if (err_is_fail(err)) { DEBUG_ERR(err, "rcce_export failed"); abort(); } while (!request_done) { event_dispatch(get_default_waitset()); } if (strcmp(argv[argc - 1], "dummy")) { /* bsp core */ for (coreid_t i = 0; i < MAX_CPUS; i++) { /* Connect to all cores */ if (core_present[i] && i != my_core_id && barray[i] == NULL) { /* printf("%s: connecting to core %d\n", argv[0], i); */ connect(i); } } } else { /* printf("%s: waiting for connection\n", argv[0]); */ // Wait for an incoming connection request while(connect_request == NULL) { event_dispatch(get_default_waitset()); } /* Connect to all cores to which we have not connected already */ for (coreid_t i = 0; i < MAX_CPUS; i++) { if (core_present[i] && i != my_core_id && barray[i] == NULL) { /* printf("%s: slave connecting to core %d\n", argv[0], i); */ connect(i); } } /* printf("%s: sending connect reply\n", argv[0]); */ // Send the reply back err = connect_request->tx_vtbl. error_reply(connect_request, NOP_CONT, SYS_ERR_OK, connect_state); if (err_is_fail(err)) { DEBUG_ERR(err, "init_reply failed"); abort(); } } /* printf("%s: done\n", argv[0]); */ // Determine maximum core ID coreid_t maxcore = 0; for(coreid_t i = 0; i < MAX_CPUS; i++) { if(core_present[i]) { maxcore = i; } } barriers_init(maxcore + 1); }
errval_t start_networking(coreid_t core, struct module_info* driver, char* record) { assert(driver != NULL); errval_t err = SYS_ERR_OK; uint64_t vendor_id, device_id, bus, dev, fun; /* check if we are using the supplied pci address of eth0 */ if (eth0.bus != 0xff || eth0.device != 0xff || eth0.function != 0xff) { err = oct_read(record, "_ { bus: %d, device: %d, function: %d, vendor: %d, device_id: %d }", &bus, &dev, &fun, &vendor_id, &device_id); assert(err_is_ok(err)); if ((eth0.bus != (uint8_t)bus) | (eth0.device != (uint8_t)dev) | (eth0.function != (uint8_t)fun)) { KALUGA_DEBUG("start_networking: skipping card %" PRIu64 ":% "PRIu64 ":% " PRIu64"\n", bus, dev, fun); return KALUGA_ERR_DRIVER_NOT_AUTO; } } if (is_started(driver)) { return KALUGA_ERR_DRIVER_ALREADY_STARTED; } if (!is_auto_driver(driver)) { return KALUGA_ERR_DRIVER_NOT_AUTO; } struct module_info* netd = find_module("netd"); if (netd == NULL || !is_auto_driver(netd)) { KALUGA_DEBUG("netd not found or not declared as auto."); return KALUGA_ERR_DRIVER_NOT_AUTO; } struct module_info* ngd_mng = find_module("NGD_mng"); if (ngd_mng == NULL || !is_auto_driver(ngd_mng)) { KALUGA_DEBUG("NGD_mng not found or not declared as auto."); return KALUGA_ERR_DRIVER_NOT_AUTO; } err = default_start_function(core, driver, record); if (err_is_fail(err)) { DEBUG_ERR(err, "Spawning %s failed.", driver->path); return err; } // XXX: Manually add cardname (overwrite first (auto) argument) // +Weird convention, e1000n binary but cardname=e1000 char* cardname = strcmp(driver->binary, "e1000n") == 0 ? "e1000" : driver->binary; size_t name_len = strlen("cardname=") + strlen(cardname) + 1; char* card_argument = malloc(name_len); sprintf(card_argument, "cardname=%s", cardname); printf("############# starting network with arguments %s\n", card_argument); // Spawn netd and ngd_mng netd->argv[0] = card_argument; err = spawn_program(core, netd->path, netd->argv, environ, 0, get_did_ptr(netd)); ngd_mng->argv[0] = card_argument; err = spawn_program(core, ngd_mng->path, ngd_mng->argv, environ, 0, get_did_ptr(ngd_mng)); free(card_argument); return err; }
void spawn_bootscript_domains(void) { errval_t err; coreid_t my_coreid = disp_get_core_id(); char *argv[256], *name; // open bootmodules file and read it in FILE *f = fopen("/bootscript", "r"); if(f == NULL) { printf("No bootscript\n"); return; } char line[1024]; while(fgets(line, 1024, f) != NULL) { int argc; // ignore comments (#) and empty lines if (line[0] == '#' || line[0] == '\n') { continue; } argv[0] = strtok(line, " \n"); name = argv[0]; for(argc = 1;; argc++) { argv[argc] = strtok(NULL, " \n"); if(argv[argc] == NULL) { break; } } // get core id if (argc >= 2 && strncmp(argv[1], "core=", 5) == 0) { char *p = strchr(argv[1], '='); assert(p != NULL); p++; while(*p != '\0') { int id_from = strtol(p, (char **)&p, 10), id_to = id_from; if(*p == '-') { p++; id_to = strtol(p, (char **)&p, 10); } assert(*p == ',' || *p == '\0'); if(*p != '\0') { p++; } /* coreid = strtol(p + 1, NULL, 10); */ // discard 'core=x' argument for (int i = 1; i < argc; i++) { argv[i] = argv[i+1]; } argc--; for(int i = id_from; i <= id_to; i++) { debug_printf("starting app %s on core %d\n", name, i); domainid_t new_domain; err = spawn_program(i, name, argv, environ, 0, &new_domain); if (err_is_fail(err)) { DEBUG_ERR(err, "spawn of %s failed", name); } } } } else { debug_printf("starting app %s on core %d\n", name, my_coreid); domainid_t new_domain; err = spawn_program(my_coreid, name, argv, environ, 0, &new_domain); if (err_is_fail(err)) { DEBUG_ERR(err, "spawn of %s failed", name); } } } fclose(f); }
void spawn_app_domains(void) { struct spawn_info si; size_t bmpos = 0; errval_t err; int r; coreid_t my_coreid = disp_get_core_id(); while (true) { bool spawn_here = true; r = prepare_spawn(&bmpos, &si); if (r == 0) { return; } else if (r == -1) { DEBUG_ERR(STARTD_ERR_BOOTMODULES, "failed to read bootmodules entry"); } /* Do not spawn special domains */ if (strncmp(si.shortname, "init", si.shortnamelen) == 0 || strncmp(si.shortname, "cpu", si.shortnamelen) == 0 // Adding following condition for cases like "cpu_omap44xx" || strncmp(si.shortname, "cpu", strlen("cpu")) == 0 || strncmp(si.shortname, "monitor", si.shortnamelen) == 0 || strncmp(si.shortname, "mem_serv", si.shortnamelen) == 0 #ifdef __k1om__ || strncmp(si.shortname, "corectrl", si.shortnamelen) == 0 #endif ) { spawn_here = false; } /* Do not spawn special boot modules, dist-serv modules or nospawn modules */ if (si.argc >= 2 && (strcmp(si.argv[1], "boot") == 0 || strcmp(si.argv[1], "dist-serv") == 0 || strcmp(si.argv[1], "nospawn") == 0 || strcmp(si.argv[1], "arrakis") == 0 || strcmp(si.argv[1], "auto") == 0)) { spawn_here = false; } if (spawn_here) { coreid_t coreid; uint8_t spawn_flags = 0; uint8_t has_spawn_flags = 0; uint8_t has_core = 0; char *core_ptr = NULL; for(int i = 1; i < si.argc && i < 3; ++i) { if(strncmp(si.argv[i], "spawnflags=", 11) == 0) { char *p = strchr(si.argv[i], '=') + 1; spawn_flags = (uint8_t)strtol(p, (char **)&p, 10); has_spawn_flags = 1; } else if (strncmp(si.argv[i], "core=", 5)== 0) { core_ptr = strchr(si.argv[i], '=') + 1; has_core = 1; } else { /* ignore */ } } if (has_core || has_spawn_flags) { for (int i = 1; i < si.argc; i++) { if (has_spawn_flags && has_core) { si.argv[i] = si.argv[i+2]; } else { si.argv[i] = si.argv[i+1]; } } } si.argc -= (has_core + has_spawn_flags); if (has_core) { while(*core_ptr != '\0') { int id_from = strtol(core_ptr, (char **)&core_ptr, 10); int id_to = id_from; if(*core_ptr == '-') { core_ptr++; id_to = strtol(core_ptr, (char **)&core_ptr, 10); } assert(*core_ptr == ',' || *core_ptr == '\0'); if(*core_ptr != '\0') { core_ptr++; } /* coreid = strtol(p + 1, NULL, 10); */ // discard 'core=x' argument for(int i = id_from; i <= id_to; i++) { debug_printf("starting app %s on core %d\n", si.name, i); domainid_t new_domain; err = spawn_program(i, si.name, si.argv, environ, spawn_flags, &new_domain); if (err_is_fail(err)) { DEBUG_ERR(err, "spawn of %s failed", si.name); } } } } else { coreid = my_coreid; debug_printf("starting app %s on core %d\n", si.name, coreid); domainid_t new_domain; err = spawn_program(coreid, si.name, si.argv, environ, spawn_flags, &new_domain); if (err_is_fail(err)) { DEBUG_ERR(err, "spawn of %s failed", si.name); } } } free(si.cmdargs); free(si.name); } }
void spawn_dist_domains(void) { struct spawn_info si; size_t bmpos = 0; errval_t err; int r; coreid_t my_coreid = disp_get_core_id(); while (true) { r = prepare_spawn(&bmpos, &si); if (r == 0) { return; } else if (r == -1) { DEBUG_ERR(STARTD_ERR_BOOTMODULES, "failed to read bootmodules entry"); } /* Only spawn special dist-serv modules */ if (si.argc >= 2 && strcmp(si.argv[1], "dist-serv") == 0) { coreid_t coreid; int extra_args; // get core id if (si.argc >= 3 && strncmp(si.argv[2], "core=", 5) == 0) { char *p = strchr(si.argv[2], '='); assert(p != NULL); coreid = strtol(p + 1, NULL, 10); extra_args = 2; } else { coreid = my_coreid; extra_args = 1; } // discard 'dist-serv' and 'core=x' argument for (int i = 1; i <= si.argc - extra_args; i++) { si.argv[i] = si.argv[i+extra_args]; } si.argc--; debug_printf("starting dist-serv %s on core %d\n", si.name, coreid); domainid_t new_domain; err = spawn_program(coreid, si.name, si.argv, environ, 0, &new_domain); if (err_is_fail(err)) { DEBUG_ERR(err, "spawn of %s failed", si.name); continue; } char c = si.shortname[si.shortnamelen]; si.shortname[si.shortnamelen] = '\0'; // wait until fully started err = nsb_wait_ready(si.shortname); if (err_is_fail(err)) { DEBUG_ERR(err, "nsb_wait_ready on %s failed", si.shortname); } si.shortname[si.shortnamelen] = c; // HACK: make sure we use the local versions of a service if // it was started. Really there needs to be a mechanism for that // service to signal us and others to do this once it has started // up. set_local_bindings(); } free(si.cmdargs); free(si.name); } }
static int run_master(coreid_t mycore, int argc, char *argv[]) { errval_t err; int num_spawn = strtol(argv[1], NULL, 10); int first_core = mycore + 1; debug_printf("spawning on %d cores\n", num_spawn); #ifdef TRACING err = init_tracing(); if (err_is_fail(err)) { DEBUG_ERR(err, "initialising tracing"); return EXIT_FAILURE; } // start_tracing(); prepare_dump(); #endif trace_event(TRACE_SUBSYS_MEMTEST, TRACE_EVENT_MEMTEST_STARTED, 0); // spawn some dispatchers char *path = argv[0]; // reuse argv and path argv[1] = NULL; for (int i = first_core; i <= num_spawn; i++) { err = spawn_program(i, path, argv, NULL, 0, NULL); if (err_is_fail(err)) { DEBUG_ERR(err, "spawning on core %d", i); } else { //debug_printf("dispatcher %d on core %d spawned\n", i, i); } } trace_event(TRACE_SUBSYS_MEMTEST, TRACE_EVENT_MEMTEST_WAIT, 0); // debug_printf("waiting for all spawns to start\n"); err = ns_barrier_master(first_core, num_spawn, "mem_bench_ready"); if (err_is_fail(err)) { DEBUG_ERR(err, "failed barrier_master"); return EXIT_FAILURE; } start_tracing(); trace_event(TRACE_SUBSYS_MEMTEST, TRACE_EVENT_MEMTEST_RUN, 0); // run_benchmark(mycore, MAX_REQUESTS_0); trace_event(TRACE_SUBSYS_MEMTEST, TRACE_EVENT_MEMTEST_WAIT, 0); // debug_printf("waiting for all spawns to complete\n"); err = ns_barrier_master(first_core, num_spawn, "mem_bench_finished"); if (err_is_fail(err)) { DEBUG_ERR(err, "failed barrier_master"); return EXIT_FAILURE; } trace_event(TRACE_SUBSYS_MEMTEST, TRACE_EVENT_MEMTEST_DONE, 0); debug_printf("all benchmarks completed\n"); #ifdef TRACING stop_tracing(); // dump_trace(); #endif return EXIT_SUCCESS; }