static void * con(void *arg) { struct args *c; while(1){ c = malloc(sizeof(struct args)); copy_args(arg, c); /* Try to get exclusive access to count */ pthread_mutex_lock(c->mutex_count); while(*(c->count) >= CONCURRENT_OPS){ pthread_cond_wait(c->cv_consumer, c->mutex_count); } pthread_mutex_unlock(c->mutex_count); consume(*(c->count), (c->queue) , (c->queue_lock)); pthread_mutex_lock(c->mutex_count); *(c->count) = *(c->count) + 1; pthread_cond_signal(c->cv_producer); pthread_mutex_unlock(c->mutex_count); /* wakeup other threads that may be waiting on the queue */ free(c); } return NULL; }
static int common_prog(int nargs, char **args) { int result; char **args_copy; #if OPT_SYNCHPROBS kprintf("Warning: this probably won't work with a " "synchronization-problems kernel.\n"); #endif /* demke: Make a copy of arguments to pass to new thread, * so that we aren't depending on parent's stack! */ args_copy = copy_args(nargs, args); if (!args_copy) { return ENOMEM; } /* demke: and now call thread_fork with the copy */ result = thread_fork(args_copy[0] /* thread name */, cmd_progthread /* thread function */, args_copy /* thread arg */, nargs /* thread arg */, NULL); if (result) { kprintf("thread_fork failed: %s\n", strerror(result)); /* demke: need to free copy of args if fork fails */ free_args(nargs, args_copy); return result; } return 0; }
static void * prod(void *arg) { struct args *p; int i; int loop; for(loop = 0 ; loop < 50 ; loop++){ p = malloc(sizeof(struct args)); copy_args(arg, p); /* try getting exclusive access to p.count variable */ pthread_mutex_lock(p->mutex_count); while(*(p->count) <= 0){ pthread_cond_wait(p->cv_producer, p->mutex_count); } req_no++; *(p->count) = *(p->count)- 1; /* One more queue element filled */ produce(*(p->count), req_no, (p->queue) , (p->queue_lock)); pthread_cond_signal(p->cv_consumer); pthread_mutex_unlock(p->mutex_count); free(p); } return NULL; }
void init_args(int argc, char *argv[]) { copy_args(argc, argv); // Default: start in interactive mode args.command = 0; args.interactive = TRUE; int opt; while ((opt = getopt(argc, argv, "he:x:")) != -1) { switch (opt) { case 'h': usage(argv[0]); exit(0); case 'e': args.command = (cell)optarg; args.interactive = FALSE; break; case 'x': args.command = (cell)optarg; args.interactive = TRUE; break; default: exit(-1); } } // The words `argv` and `argc` then contain the remaining // arguments, to be processed by the program. args.argc = argc - optind; args.argv = args.raw_argv + optind; }
char *str_cons(int count, ...) { return_unless(count >= 0, empty, "count must not be negative"); if (!count) { return empty; } va_list args1; va_list args2; va_start(args1, count); va_copy(args2, args1); /*> The calculation of the length is straight forward. We only have to watch out for `NULL` strings, that will be silently ignored. <*/ size_t length = 0; for (int i = count; i; --i) { const char *current = va_arg(args1, const char *); if (current) length += strlen(current); } va_end(args1); /*> The result buffer must be one byte bigger to store the terminating null byte. <*/ char *result = malloc(length + 1); /*> The `copy_args` function may throw an error. We put it in a different function, so we can free the second argument list, even, if an error is raised. <*/ copy_args(result, count, args2); va_end(args2); return result ? : empty; }
void start_core(int argc, char **argv) { int orig_argc = argc; char **orig_argv = copy_args(argc, argv); FLAGS_stderrthreshold = 0; FLAGS_logbuflevel = -1; google::ParseCommandLineFlags(&argc, &argv, true); google::InitGoogleLogging(argv[0]); auto conf = create_config(); ld_environment(orig_argv, conf.rules_directory); free_args(orig_argc, orig_argv); log_config(conf); g_core = make_real_core(conf); g_core->start(); g_core.reset(); free_thread_ns(); }
static int common_prog(int nargs, char **args) { int result; char **args_copy; #if OPT_SYNCHPROBS kprintf("Warning: this probably won't work with a " "synchronization-problems kernel.\n"); #endif /* * Implementation of & option for menu when running programs. * By default, menu will wait for user program to end before running. * If on menu command line has a '&' at the end, * it will not wait for the user program to end * before continuing to run. */ bool toDetach; toDetach = false; pid_t childpid; if (*args[nargs - 1] == '&'){ nargs--; // So we don't pass on & toDetach = true; } /* demke: Make a copy of arguments to pass to new thread, * so that we aren't depending on parent's stack! */ args_copy = copy_args(nargs, args); if (!args_copy) { return ENOMEM; } /* demke: and now call thread_fork with the copy */ result = thread_fork(args_copy[0] /* thread name */, cmd_progthread /* thread function */, args_copy /* thread arg */, nargs /* thread arg */, &childpid); if (result) { kprintf("thread_fork failed: %s\n", strerror(result)); /* demke: need to free copy of args if fork fails */ free_args(nargs, args_copy); return result; } // If toDetach, then wont wait for program to end before continuing menu. if (toDetach) { pid_detach(childpid); } // Wait for program to end before continuing // (unless it's detached, in which case join will do nothing.) pid_join(childpid, NULL, (int)NULL); return 0; }
static int common_prog(int nargs, char **args) { int result; int join_result; int *status; char **args_copy; pid_t *ret; #if OPT_SYNCHPROBS kprintf("Warning: this probably won't work with a " "synchronization-problems kernel.\n"); #endif /* demke: Make a copy of arguments to pass to new thread, * so that we aren't depending on parent's stack! */ args_copy = copy_args(nargs, args); if (!args_copy) { return ENOMEM; } if(strcmp(args[nargs-2], "&") == 0) { ret = NULL; //This will cause thread_fork to detach the child } /* demke: and now call thread_fork with the copy */ result = thread_fork(args_copy[0] /* thread name */, cmd_progthread /* thread function */, args_copy /* thread arg */, nargs /* thread arg */, ret); if (result) { kprintf("thread_fork failed: %s\n", strerror(result)); /* demke: need to free copy of args if fork fails */ free_args(nargs, args_copy); return result; } else if (result != 0 && ret != NULL) { join_result = pid_join(result, status, 0); if (status != 0 || join_result < 0) { return join_result; } } return 0; }
/* * Convert six control points marked as CS_FLEX_CTRL to a flex path. */ static void do_othersubr0 (t1_chardesc *cd) { t1_cpath *flex, *cur, *next; if (ps_stack_top < 1) { status = CS_PARSE_ERROR; return; } /* Seek first CS_FLEX_CTRL mark */ for (cur = cd->charpath; cur != NULL && cur->type != CS_FLEX_CTRL; cur = cur->next); flex = cur; { int i; cur = cur->next; for (i = 1; i < 7; i++) { if (cur == NULL || cur->type != CS_FLEX_CTRL || cur->num_args != 2) { status = CS_PARSE_ERROR; return; } if (i == 1) { flex->args[0] += cur->args[0]; flex->args[1] += cur->args[1]; } else { copy_args(&(flex->args[2*i-2]), cur->args, 2); } next = cur->next; RELEASE(cur); cur = next; } } if (cur != NULL) { status = CS_PARSE_ERROR; return; } /* * Now 'flex' have all six control points, the first pair is relative * from starting point. */ flex->type = cs_flex; flex->args[12] = ps_arg_stack[--ps_stack_top]; /* flex depth */ flex->num_args = 13; flex->next = NULL; cd->lastpath = flex; phase = T1_CS_PHASE_PATH; }
int argify(const char *line, char ***argv_ptr) { int argc; char ** argv; argc = count_args (line); if (argc == 0) return -1; argv = (char **)malloc (sizeof (char *) * argc); if (!argv) return -1; if (copy_args (line, argc, argv) < 0) return -1; *argv_ptr = argv; return argc; }
static int do_bootm_plan9(int flag, int argc, char * const argv[], bootm_headers_t *images) { void (*entry_point)(void); char *s; if (flag & BOOTM_STATE_OS_PREP) return 0; if ((flag != 0) && (flag != BOOTM_STATE_OS_GO)) return 1; #if defined(CONFIG_FIT) if (!images->legacy_hdr_valid) { fit_unsupported_reset("Plan 9"); return 1; } #endif /* See README.plan9 */ s = getenv("confaddr"); if (s != NULL) { char *confaddr = (char *)simple_strtoul(s, NULL, 16); if (argc > 0) { copy_args(confaddr, argc, argv, '\n'); } else { s = getenv("bootargs"); if (s != NULL) strcpy(confaddr, s); } } entry_point = (void (*)(void))images->ep; printf("## Transferring control to Plan 9 (at address %08lx) ...\n", (ulong)entry_point); bootstage_mark(BOOTSTAGE_ID_RUN_OS); /* * Plan 9 Parameters: * None */ (*entry_point)(); return 1; }
static int common_prog(int nargs, char **args) { int result; char **args_copy; #if OPT_SYNCHPROBS kprintf("Warning: this probably won't work with a " "synchronization-problems kernel.\n"); #endif /* demke: Make a copy of arguments to pass to new thread, * so that we aren't depending on parent's stack! */ args_copy = copy_args(nargs, args); if (!args_copy) { return ENOMEM; } /* demke: and now call thread_fork with the copy */ result = thread_fork(args_copy[0] /* thread name */, cmd_progthread /* thread function */, args_copy /* thread arg */, nargs /* thread arg */, NULL); if (result) { kprintf("thread_fork failed: %s\n", strerror(result)); /* demke: need to free copy of args if fork fails */ free_args(nargs, args_copy); return result; } /* BEGIN A3 SETUP */ /* This is not needed if you have a working pid_join - * that should be used instead. */ /* Wait for progthread to finish and send a V() */ P(cmd_sem); /* END A3 SETUP */ return 0; }
static int do_bootm_netbsd(int flag, int argc, char * const argv[], bootm_headers_t *images) { void (*loader)(bd_t *, image_header_t *, char *, char *); image_header_t *os_hdr, *hdr; ulong kernel_data, kernel_len; char *consdev; char *cmdline; if (flag != BOOTM_STATE_OS_GO) return 0; #if defined(CONFIG_FIT) if (!images->legacy_hdr_valid) { fit_unsupported_reset("NetBSD"); return 1; } #endif hdr = images->legacy_hdr_os; /* * Booting a (NetBSD) kernel image * * This process is pretty similar to a standalone application: * The (first part of an multi-) image must be a stage-2 loader, * which in turn is responsible for loading & invoking the actual * kernel. The only differences are the parameters being passed: * besides the board info strucure, the loader expects a command * line, the name of the console device, and (optionally) the * address of the original image header. */ os_hdr = NULL; if (image_check_type(&images->legacy_hdr_os_copy, IH_TYPE_MULTI)) { image_multi_getimg(hdr, 1, &kernel_data, &kernel_len); if (kernel_len) os_hdr = hdr; } consdev = ""; #if defined(CONFIG_8xx_CONS_SMC1) consdev = "smc1"; #elif defined(CONFIG_8xx_CONS_SMC2) consdev = "smc2"; #elif defined(CONFIG_8xx_CONS_SCC2) consdev = "scc2"; #elif defined(CONFIG_8xx_CONS_SCC3) consdev = "scc3"; #endif if (argc > 0) { ulong len; int i; for (i = 0, len = 0; i < argc; i += 1) len += strlen(argv[i]) + 1; cmdline = malloc(len); copy_args(cmdline, argc, argv, ' '); } else if ((cmdline = getenv("bootargs")) == NULL) { cmdline = ""; } loader = (void (*)(bd_t *, image_header_t *, char *, char *))images->ep; printf("## Transferring control to NetBSD stage-2 loader " "(at address %08lx) ...\n", (ulong)loader); bootstage_mark(BOOTSTAGE_ID_RUN_OS); /* * NetBSD Stage-2 Loader Parameters: * arg[0]: pointer to board info data * arg[1]: image load address * arg[2]: char pointer to the console device to use * arg[3]: char pointer to the boot arguments */ (*loader)(gd->bd, os_hdr, consdev, cmdline); return 1; }
int main(int argc, char **argv) { int i, do_precache = 0, valgrind_mode = 0; int valgrind_tool = 0; char buf[16384], **args, *p; char valgrind_path[PATH_MAX] = ""; const char *valgrind_log = NULL; eina_init(); prefix_determine(argv[0]); env_set("E_START", argv[0]); p = getenv("PATH"); if (p) snprintf(buf, sizeof(buf), "%s:%s", eina_prefix_bin_get(pfx), p); else snprintf(buf, sizeof(buf), "%s", eina_prefix_bin_get(pfx)); env_set("PATH", buf); p = getenv("LD_LIBRARY_PATH"); if (p) snprintf(buf, sizeof(buf), "%s:%s", eina_prefix_lib_get(pfx), p); else snprintf(buf, sizeof(buf), "%s", eina_prefix_lib_get(pfx)); env_set("LD_LIBRARY_PATH", buf); for (i = 1; i < argc; i++) { if (!strcmp(argv[i], "-no-precache")) do_precache = 0; else if (!strncmp(argv[i], "-valgrind", sizeof("-valgrind") - 1)) { const char *val = argv[i] + sizeof("-valgrind") - 1; if (*val == '\0') valgrind_mode = 1; else if (*val == '-') { val++; if (!strncmp(val, "log-file=", sizeof("log-file=") - 1)) { valgrind_log = val + sizeof("log-file=") - 1; if (*valgrind_log == '\0') valgrind_log = NULL; } } else if (*val == '=') { val++; if (!strcmp(val, "all")) valgrind_mode = VALGRIND_MODE_ALL; else valgrind_mode = atoi(val); } else printf("Unknown valgrind option: %s\n", argv[i]); } else if (!strcmp(argv[i], "-massif")) valgrind_tool = 1; else if (!strcmp(argv[i], "-callgrind")) valgrind_tool = 2; else if ((!strcmp(argv[i], "-h")) || (!strcmp(argv[i], "-help")) || (!strcmp(argv[i], "--help"))) { printf ( "Options:\n" "\t-no-precache\n" "\t\tDisable pre-caching of files\n" "\t-valgrind[=MODE]\n" "\t\tRun enlightenment from inside valgrind, mode is OR of:\n" "\t\t 1 = plain valgrind to catch crashes (default)\n" "\t\t 2 = trace children (thumbnailer, efm slaves, ...)\n" "\t\t 4 = check leak\n" "\t\t 8 = show reachable after processes finish.\n" "\t\t all = all of above\n" "\t-massif\n" "\t\tRun enlightenment from inside massif valgrind tool.\n" "\t-callgrind\n" "\t\tRun enlightenment from inside callgrind valgrind tool.\n" "\t-valgrind-log-file=<FILENAME>\n" "\t\tSave valgrind log to file, see valgrind's --log-file for details.\n" "\n" "Please run:\n" "\tenlightenment %s\n" "for more options.\n", argv[i]); exit(0); } } if (valgrind_mode || valgrind_tool) { if (!find_valgrind(valgrind_path, sizeof(valgrind_path))) { printf("E - valgrind required but no binary found! Ignoring request.\n"); valgrind_mode = 0; } } printf("E - PID=%i, do_precache=%i, valgrind=%d", getpid(), do_precache, valgrind_mode); if (valgrind_mode) { printf(" valgrind-command='%s'", valgrind_path); if (valgrind_log) printf(" valgrind-log-file='%s'", valgrind_log); } putchar('\n'); if (do_precache) { void *lib, *func; /* sanity checks - if precache might fail - check here first */ lib = dlopen("libeina.so", RTLD_GLOBAL | RTLD_LAZY); if (!lib) dlopen("libeina.so.1", RTLD_GLOBAL | RTLD_LAZY); if (!lib) goto done; func = dlsym(lib, "eina_init"); if (!func) goto done; lib = dlopen("libecore.so", RTLD_GLOBAL | RTLD_LAZY); if (!lib) dlopen("libecore.so.1", RTLD_GLOBAL | RTLD_LAZY); if (!lib) goto done; func = dlsym(lib, "ecore_init"); if (!func) goto done; lib = dlopen("libecore_file.so", RTLD_GLOBAL | RTLD_LAZY); if (!lib) dlopen("libecore_file.so.1", RTLD_GLOBAL | RTLD_LAZY); if (!lib) goto done; func = dlsym(lib, "ecore_file_init"); if (!func) goto done; lib = dlopen("libecore_x.so", RTLD_GLOBAL | RTLD_LAZY); if (!lib) dlopen("libecore_x.so.1", RTLD_GLOBAL | RTLD_LAZY); if (!lib) goto done; func = dlsym(lib, "ecore_x_init"); if (!func) goto done; lib = dlopen("libevas.so", RTLD_GLOBAL | RTLD_LAZY); if (!lib) dlopen("libevas.so.1", RTLD_GLOBAL | RTLD_LAZY); if (!lib) goto done; func = dlsym(lib, "evas_init"); if (!func) goto done; lib = dlopen("libedje.so", RTLD_GLOBAL | RTLD_LAZY); if (!lib) dlopen("libedje.so.1", RTLD_GLOBAL | RTLD_LAZY); if (!lib) goto done; func = dlsym(lib, "edje_init"); if (!func) goto done; lib = dlopen("libeet.so", RTLD_GLOBAL | RTLD_LAZY); if (!lib) dlopen("libeet.so.0", RTLD_GLOBAL | RTLD_LAZY); if (!lib) goto done; func = dlsym(lib, "eet_init"); if (!func) goto done; /* precache SHOULD work */ snprintf(buf, sizeof(buf), "%s/enlightenment/preload/e_precache.so", eina_prefix_lib_get(pfx)); env_set("LD_PRELOAD", buf); printf("E - PRECACHE GOING NOW...\n"); fflush(stdout); precache(); } done: /* mtrack memory tracker support */ p = getenv("HOME"); if (p) { FILE *f; /* if you have ~/.e-mtrack, then the tracker will be enabled * using the content of this file as the path to the mtrack.so * shared object that is the mtrack preload */ snprintf(buf, sizeof(buf), "%s/.e-mtrack", p); f = fopen(buf, "r"); if (f) { if (fgets(buf, sizeof(buf), f)) { int len = strlen(buf); if ((len > 1) && (buf[len - 1] == '\n')) { buf[len - 1] = 0; len--; } env_set("LD_PRELOAD", buf); env_set("MTRACK", "track"); env_set("E_START_MTRACK", "track"); snprintf(buf, sizeof(buf), "%s/.e-mtrack.log", p); env_set("MTRACK_TRACE_FILE", buf); } fclose(f); } } /* try dbus-launch */ snprintf(buf, sizeof(buf), "%s/enlightenment", eina_prefix_bin_get(pfx)); args = alloca((argc + 2 + VALGRIND_MAX_ARGS) * sizeof(char *)); if ((!getenv("DBUS_SESSION_BUS_ADDRESS")) && (!getenv("DBUS_LAUNCHD_SESSION_BUS_SOCKET"))) { args[0] = "dbus-launch"; args[1] = "--exit-with-session"; i = 2 + valgrind_append(args + 2, valgrind_mode, valgrind_tool, valgrind_path, valgrind_log); args[i++] = buf; copy_args(args + i, argv + 1, argc - 1); args[i + argc - 1] = NULL; execvp("dbus-launch", args); } /* dbus-launch failed - run e direct */ i = valgrind_append(args, valgrind_mode, valgrind_tool, valgrind_path, valgrind_log); args[i++] = buf; copy_args(args + i, argv + 1, argc - 1); args[i + argc - 1] = NULL; execv(args[0], args); printf("FAILED TO RUN:\n"); printf(" %s\n", buf); perror("execv"); return -1; }
/* * -- do_config * * Apply the configuration on the map. It expects each useful line to * start with a known keyword. Note the unconventional return values. * It returns NULL if successful or an error string in case of error. * */ static char * do_config(struct _como * m, int argc, char *argv[]) { static char errstr[1024]; static int scope = CTX_GLOBAL; /* scope of current keyword */ static module_t * mdl = NULL; /* module currently open */ static int node_id = 0; /* current node */ static alias_t * alias = NULL; /* alias currently open */ keyword_t *t; /* * run some checks on the token (i.e., that it exists * and that we have all the arguments it needs). */ t = match_token(argv[0], keywords); if (t == NULL) { sprintf(errstr, "unknown token \"%s\"\n", argv[0]); return errstr; } if (argc < t->nargs) { sprintf(errstr, "\"%s\", requires at least %d arguments\n", argv[0], t->nargs); return errstr; } /* * Check if the keyword is ok in the current scope. */ if (!(t->scope & scope)) { sprintf(errstr, "\"%s\" out of scope\n", argv[0]); return errstr; } /* * configuration actions */ switch (t->action) { case TOK_DBDIR: if (m->cli_args.dbdir_set == 0) { safe_dup(&m->dbdir, argv[1]); } break; case TOK_QUERYPORT: if (m->cli_args.query_port_set == 0 || node_id > 0) { m->node[node_id].query_port = atoi(argv[1]); } break; case TOK_DESCRIPTION: if (scope == CTX_MODULE) safe_dup(&mdl->description, argv[1]); else safe_dup(&alias->description, argv[1]); break; case TOK_END: if (scope == CTX_MODULE) { /* * "end" of a module configuration. run some checks depending * on context to make sure that all mandatory fields are there * and set default values */ if (check_module(m, mdl)) { remove_module(m, mdl); scope = CTX_GLOBAL; break; } if (m->runmode == RUNMODE_INLINE) m->inline_mdl = mdl; logmsg(LOGUI, "... module%s %s [%d][%d] ", (mdl->running == RUNNING_ON_DEMAND) ? " on-demand" : "", mdl->name, mdl->node, mdl->priority); logmsg(LOGUI, " filter %s; out %s (%uMB)\n", mdl->filter_str, mdl->output, mdl->streamsize/(1024*1024)); } else if (scope == CTX_VIRTUAL) { /* * we are done with this virtual node. let's go back to * the master node (i.e. node_id == 0) */ node_id = 0; } scope = CTX_GLOBAL; break; case TOK_FILTER: if (scope == CTX_MODULE) safe_dup(&mdl->filter_str, argv[1]); else if (scope == CTX_VIRTUAL) safe_dup(&m->node[node_id].filter_str, argv[1]); break; case TOK_HASHSIZE: mdl->ex_hashsize = mdl->ca_hashsize = atoi(argv[1]); break; case TOK_SOURCE: if (scope == CTX_MODULE) { safe_dup(&mdl->source, argv[1]); } else { safe_dup(&m->node[node_id].source, argv[1]); } break; case TOK_LIBRARYDIR: if (m->cli_args.libdir_set == 0) { safe_dup(&m->libdir, argv[1]); } break; case TOK_LOGFLAGS: if (m->cli_args.logflags_set == 0) { m->logflags = set_flags(0, argv[1]); } break; case TOK_MEMSIZE: /* this keyword can be used in two contexts */ if (m->cli_args.mem_size_set == 0) { m->mem_size = atoi(argv[1]); } break; case TOK_MODULE: if (scope == CTX_GLOBAL) { int node = (m->runmode == RUNMODE_INLINE? -1 : 0); mdl = new_module(m, argv[1], node, -1); scope = CTX_MODULE; /* change scope */ } else { safe_dup(&alias->module, argv[1]); } break; case TOK_MODULE_MAX: m->module_max = atoi(argv[1]); m->modules = safe_realloc(m->modules, sizeof(module_t)*m->module_max); break; case TOK_OUTPUT: safe_dup(&mdl->output, argv[1]); break; case TOK_SNIFFER: add_sniffer(m, argv[1], argv[2], argc > 3 ? argv[3] : NULL); break; case TOK_STREAMSIZE: mdl->streamsize = parse_size(argv[1]); break; case TOK_MAXFILESIZE: m->maxfilesize = parse_size(argv[1]); if (m->maxfilesize > 1024*1024*1024) { m->maxfilesize = DEFAULT_FILESIZE; sprintf(errstr, "'filesize' should be < 1GB --> set to %dMB\n", (int)(m->maxfilesize / (1024*1024))); return errstr; } break; case TOK_ARGS: /* copy the arguments. one line may have multiple arguments * starting from argv[1]. that's why we pass the pointer to * argv[1] and reduce argc by one. */ if (scope == CTX_MODULE) mdl->args = copy_args(mdl->args, &argv[1], argc - 1); else if (scope == CTX_VIRTUAL) m->node[node_id].args = copy_args(m->node->args, &argv[1], argc-1); else if (scope == CTX_ALIAS) { alias->args = copy_args(alias->args, &argv[1], argc - 1); alias->ac += argc - 1; } break; case TOK_ARGSFILE: if (scope == CTX_MODULE) { mdl->args = copy_args_from_file(mdl->args, argv[1], NULL); } else if (scope == CTX_VIRTUAL) { m->node[node_id].args = copy_args_from_file(m->node[node_id].args, argv[1], NULL); } else if (scope == CTX_ALIAS) { int count; alias->args = copy_args_from_file(alias->args, argv[1], &count); alias->ac += count; } break; case TOK_PRIORITY: mdl->priority = atoi(argv[1]); break; case TOK_RUNNING: mdl->running = (strcmp(argv[1], "on-demand") == 0) ? RUNNING_ON_DEMAND : RUNNING_NORMAL; break; case TOK_NAME: safe_dup(&m->node[node_id].name, argv[1]); break; case TOK_LOCATION: safe_dup(&m->node[node_id].location, argv[1]); break; case TOK_TYPE: safe_dup(&m->node[node_id].type, argv[1]); break; case TOK_COMMENT: safe_dup(&m->node[node_id].comment, argv[1]); break; case TOK_VIRTUAL: m->node = safe_realloc(m->node, (m->node_count + 1) * sizeof(node_t)); node_id = m->node_count; bzero(&m->node[node_id], sizeof(node_t)); safe_dup(&m->node[node_id].name, argv[1]); m->node[node_id].location = strdup("Unknown"); m->node[node_id].type = strdup("Unknown"); m->node_count++; scope = CTX_VIRTUAL; break; case TOK_ALIAS: alias = safe_calloc(1, sizeof(alias_t)); safe_dup(&alias->name, argv[1]); alias->next = m->aliases; m->aliases = alias; scope = CTX_ALIAS; break; case TOK_ASNFILE: safe_dup(&m->asnfile, argv[1]); break; case TOK_LIVE_THRESH: m->live_thresh = TIME2TS(0, atoi(argv[1])); break; default: sprintf(errstr, "unknown keyword %s\n", argv[0]); return errstr; } return NULL; }
/* * -- configure * * do a first pass of the command line parameters to find all * configuration files. the options in those files are processed * before any other command line parameter. command line will * overwrite any other configuration, as well as the last config * file will overwrite previous config files. * */ void configure(struct _como * m, int argc, char ** argv) { cli_args_t cli_args; int config_file_exists; int c, i, j; DIR *d; if (m->cli_args.done_flag == 0) { parse_cmdline(&cli_args, argc, argv); if (cli_args.logflags != -1) { m->logflags = cli_args.logflags; m->cli_args.logflags_set = 1; } if (cli_args.dbdir != NULL) { safe_dup(&m->dbdir, cli_args.dbdir); m->cli_args.dbdir_set = 1; } if (cli_args.libdir != NULL) { safe_dup(&m->libdir, cli_args.libdir); m->cli_args.libdir_set = 1; } if (cli_args.query_port != -1) { m->node->query_port = cli_args.query_port; m->cli_args.query_port_set = 1; } if (cli_args.mem_size != 0) { m->mem_size = cli_args.mem_size; m->cli_args.mem_size_set = 1; } m->exit_when_done = cli_args.exit_when_done; } m->runmode = cli_args.runmode; m->inline_fd = (m->runmode == RUNMODE_INLINE) ? 1 /* stdout */ : -1; m->debug = cli_args.debug; /* * build list of config files */ config_file_exists = 0; for (c = 0; c < cli_args.cfg_files_count; c++) { config_file_exists = 1; parse_cfgfile(m, cli_args.cfg_files[c]); } if (!config_file_exists && m->runmode != RUNMODE_INLINE) parse_cfgfile(m, DEFAULT_CFGFILE); /* add default config file */ if (m->runmode == RUNMODE_INLINE) { char *conf_argv[2]; m->exit_when_done = 1; if (cli_args.sniffer != NULL) { add_sniffer(m, cli_args.sniffer, NULL, NULL); } /* prepare the arguments for do_config() */ conf_argv[0] = "module"; conf_argv[1] = cli_args.module; do_config(m, 2, conf_argv); if (cli_args.module_args != NULL) { conf_argv[0] = "args"; conf_argv[1] = cli_args.module_args; do_config(m, 2, conf_argv); } if (cli_args.filter != NULL) { conf_argv[0] = "filter"; conf_argv[1] = cli_args.filter; do_config(m, 2, conf_argv); } conf_argv[0] = "end"; do_config(m, 1, conf_argv); } /* * now look into the virtual nodes and replicate * all modules that have been found in the config file(s) * * these new modules will have the same name but will be * running the additional filter associated with the virtual * node and save data in the virtual node dbdir. * * XXX all virtual nodes will be running on demand and * the source is defined in the configuration (or assumed to * be a trace module). later there shouldn't be a need * for defining the source module anyway... * */ for (i = 0, j = m->module_last; i <= j; i++) { module_t * orig; int node_id; orig = &m->modules[i]; for (node_id = 1; node_id < m->node_count; node_id++) { module_t * mdl; char * nm; /* create a new module and copy it from new module */ mdl = copy_module(m, orig, node_id, -1, m->node[node_id].args); mdl->running = RUNNING_ON_DEMAND; /* append node id to module's output file */ asprintf(&nm, "%s-%d", mdl->output, mdl->node); safe_dup(&mdl->output, nm); free(nm); /* add the node filter to the module filter */ if (m->node[node_id].filter_str) { char * flt; if (!strcmp(mdl->filter_str, "all")) asprintf(&flt, "%s", m->node[node_id].filter_str); else asprintf(&flt,"(%s) and (%s)", m->node[node_id].filter_str, mdl->filter_str); mdl->filter_str = flt; /* FIXME: possible leak */ } /* add the node arguments to the module arguments */ if (m->node[node_id].args) { int k; for (k = 0; m->node[node_id].args[k]; k++) { /* * XXX we copy one argument at a time to avoid * having to count them first. FIX THIS */ mdl->args = copy_args(mdl->args, &m->node[node_id].args[k], 1); } } logmsg(LOGUI, "... module%s %s [%d][%d] ", (mdl->running == RUNNING_ON_DEMAND) ? " on-demand" : "", mdl->name, mdl->node, mdl->priority); logmsg(LOGUI, " filter %s; out %s (%uMB)\n", mdl->filter_str, mdl->output, mdl->streamsize/(1024*1024)); if (mdl->description != NULL) logmsg(LOGUI, " -- %s\n", mdl->description); } } /* * open the dbdir for all nodes (virtual ones included) */ if (m->runmode == RUNMODE_NORMAL) { if (m->dbdir == NULL) panicx("missing db-path"); d = opendir(m->dbdir); if (d == NULL) createdir(m->dbdir); else closedir(d); } /* * process the AS file */ asn_readfile(m->asnfile); }
int sys_execv( userptr_t upname, userptr_t uargs ) { struct addrspace *as_new = NULL; struct addrspace *as_old = NULL; struct vnode *vn = NULL; vaddr_t entry_ptr; vaddr_t stack_ptr; int err; char kpname[MAX_PROG_NAME]; int nargs; int buflen; KASSERT( curthread != NULL ); KASSERT( curthread->td_proc != NULL ); (void)uargs; //lock the execv args lock_acquire( lk_exec ); //copy the old addrspace just in case. as_old = curthread->t_addrspace; //copyin the program name. err = copyinstr( upname, kpname, sizeof( kpname ), NULL ); if( err ) { lock_release( lk_exec ); return err; } //try to open the given executable. err = vfs_open( kpname, O_RDONLY, 0, &vn ); if( err ) { lock_release( lk_exec ); return err; } //copy the arguments into the kernel buffer. err = copy_args( uargs, &nargs, &buflen ); if( err ) { lock_release( lk_exec ); vfs_close( vn ); return err; } //create the new addrspace. as_new = as_create(); if( as_new == NULL ) { lock_release( lk_exec ); vfs_close( vn ); return ENOMEM; } //activate the new addrspace. as_activate( as_new ); //temporarily switch the addrspaces. curthread->t_addrspace = as_new; //load the elf executable. err = load_elf( vn, &entry_ptr ); if( err ) { curthread->t_addrspace = as_old; as_activate( as_old ); as_destroy( as_new ); vfs_close( vn ); lock_release( lk_exec ); return err; } //create a stack for the new addrspace. err = as_define_stack( as_new, &stack_ptr ); if( err ) { curthread->t_addrspace = as_old; as_activate( as_old ); as_destroy( as_new ); vfs_close( vn ); lock_release( lk_exec ); return err; } //adjust the stackptr to reflect the change stack_ptr -= buflen; err = adjust_kargbuf( nargs, stack_ptr ); if( err ) { curthread->t_addrspace = as_old; as_activate( as_old ); as_destroy( as_new ); vfs_close( vn ); lock_release( lk_exec ); return err; } //copy the arguments into the new user stack. err = copyout( kargbuf, (userptr_t)stack_ptr, buflen ); if( err ) { curthread->t_addrspace = as_old; as_activate( as_old ); as_destroy( as_new ); vfs_close( vn ); lock_release( lk_exec ); return err; } //reelase lk_exec lock_release( lk_exec ); //no need for it anymore. vfs_close( vn ); //we are good to go. as_destroy( as_old ); //off we go to userland. enter_new_process( nargs-1, (userptr_t)stack_ptr, stack_ptr, entry_ptr ); panic( "execv: we should not be here." ); return EINVAL; }
/* simulate_set performs the required piping to setup and run a simulation with the given parameters parameters: parameters: the parameters to pass as a parameter set to the simulation returns: the score the simulation received notes: todo: */ void simulate_set (parameters& pr) { ostream& v = term->verbose(); for (int i = 0 ; i < pr.num_sets/NUM_SETS_PER_SIM; i++){ // Create a pipe int sim_in[2]; int sim_out[2]; v << " "; v << term->blue << "Creating a pipe " << term->reset << ". . . "; if (pipe(sim_in) == -1 || pipe(sim_out) == -1) { term->failed_pipe_create(); exit(EXIT_PIPE_CREATE_ERROR); } v << term->blue << "Done: " << term->reset << "parent_read " << sim_out[0] << " parent_write " << sim_in[1] << " child_write " << sim_out[1] << " child_read "<< sim_in[0] << endl; int parent_read = sim_out[0]; int parent_write = sim_in[1]; int child_write = sim_out[1]; int child_read = sim_in[0]; cout << ip.sim_args[0] << ip.sim_args[1] << ip.sim_args[2]<< endl; // Copy the user-specified simulation arguments and fill the copy with the pipe's file descriptors char** sim_args = copy_args(ip.sim_args, ip.num_sim_args); cout << "after storing pipe"<< endl; store_pipe(sim_args, ip.num_sim_args - 4, child_read); store_pipe(sim_args, ip.num_sim_args - 2, child_write); // Fork the process so the child can run the simulation v << " "; v << term->blue << "Forking the process " << term->reset << ". . . "; pid_t pid = fork(); if (pid == -1) { term->failed_fork(); exit(EXIT_FORK_ERROR); } if (pid == 0) { // The child runs the simulation v << " "; v << term->blue << "Checking that the simulation file exists and can be executed " << term->reset << ". . . "; if (access(ip.sim_file, X_OK) == -1) { term->failed_exec(); exit(EXIT_EXEC_ERROR); } term->done(v); if (execv(ip.sim_file, sim_args) == -1) { term->failed_exec(); exit(EXIT_EXEC_ERROR); } } else { // The parent pipes in the parameter set to run v << term->blue << "Done: " << term->reset << "the child process's PID is " << pid << endl; v << " "; v << term->blue << "Writing to the pipe " << term->reset << "(file descriptor " << parent_write << ") . . . "; write_pipe(parent_write, pr, i); term->done(v); } // Wait for the child to finish simulating int status = 0; waitpid(pid, &status, WUNTRACED); if (WIFEXITED(status) == 0) { term->failed_child(); exit(EXIT_CHILD_ERROR); } // Pipe in the simulation's score double* score; v << " "; v << term->blue << "Reading the pipe " << term->reset << "(file descriptor " << parent_read << ") . . . "; read_pipe(parent_read, &score); v << term->blue << "Done: " << term->reset << "(raw score " << score << " / " << 1 << ")" << endl; // CLOSE PIPES v << " "; v << term->blue << "Closing the the pipes " << term->reset << "(file descriptor " << parent_read << ", "<< parent_write << ", " << child_read << ", " << child_write<< ") . . . "; if (close(parent_read) == -1) { term->failed_pipe_read(); exit(EXIT_PIPE_WRITE_ERROR); } if (close(parent_write) == -1) { term->failed_pipe_write(); exit(EXIT_PIPE_WRITE_ERROR); } if (close(child_read) == -1) { term->failed_pipe_write(); exit(EXIT_PIPE_WRITE_ERROR); } if (close(child_write) == -1) { term->failed_pipe_write(); exit(EXIT_PIPE_WRITE_ERROR); } term->done(v); print_good_set(pr, &score, i); // Free the simulation arguments for (int i = 0; sim_args[i] != NULL; i++) { mfree(sim_args[i]); } mfree(sim_args); } }
/* simulate_set performs the required piping to setup and run a simulation with the given parameters parameters: parameters: the parameters to pass as a parameter set to the simulation returns: the score the simulation received notes: todo: */ double simulate_set (double parameters[]) { // Get the MPI rank of the process int rank = get_rank(); ostream& v = term->verbose(); // Create a pipe int sim_in[2]; int sim_out[2]; v << " "; term->rank(rank, v); v << term->blue << "Creating a pipe " << term->reset << ". . . "; if (pipe(sim_in) == -1 || pipe(sim_out) == -1) { term->failed_pipe_create(); exit(EXIT_PIPE_CREATE_ERROR); } v << term->blue << "Done: " << term->reset << "parent_read " << sim_out[0] << " parent_write " << sim_in[1] << " child_write " << sim_out[1] << " child_read "<< sim_in[0] << endl; int parent_read = sim_out[0]; int parent_write = sim_in[1]; int child_write = sim_out[1]; int child_read = sim_in[0]; // Copy the user-specified simulation arguments and fill the copy with the pipe's file descriptors char** sim_args = copy_args(ip.sim_args, ip.num_sim_args); store_pipe(sim_args, ip.num_sim_args - 4, child_read); store_pipe(sim_args, ip.num_sim_args - 2, child_write); // Fork the process so the child can run the simulation v << " "; term->rank(rank, v); v << term->blue << "Forking the process " << term->reset << ". . . "; pid_t pid = fork(); if (pid == -1) { term->failed_fork(); exit(EXIT_FORK_ERROR); } if (pid == 0) { // The child runs the simulation v << " "; term->rank(rank, v); v << term->blue << "Checking that the simulation file exists and can be executed " << term->reset << ". . . "; if (access(ip.sim_file, X_OK) == -1) { term->failed_exec(); exit(EXIT_EXEC_ERROR); } term->done(v); if (execv(ip.sim_file, sim_args) == -1) { term->failed_exec(); exit(EXIT_EXEC_ERROR); } } else { // The parent pipes in the parameter set to run v << term->blue << "Done: " << term->reset << "the child process's PID is " << pid << endl; v << " "; term->rank(rank, v); v << term->blue << "Writing to the pipe " << term->reset << "(file descriptor " << parent_write << ") . . . "; write_pipe(parent_write, parameters); term->done(v); } // Wait for the child to finish simulating int status = 0; waitpid(pid, &status, WUNTRACED); if (WIFEXITED(status) == 0) { term->failed_child(); exit(EXIT_CHILD_ERROR); } // Pipe in the simulation's score //double max_score; double score; double cond_score; double exp_score; v << " "; term->rank(rank, v); v << term->blue << "Reading the pipe " << term->reset << "(file descriptor " << parent_read << ") . . . "; read_pipe(parent_read, &score, &cond_score, &exp_score); v << term->blue << "Done: " << term->reset << "(raw score " << score << ")" << endl; /////PRINT OUT GOOD SETS print_good_set(parameters, score, cond_score, exp_score); // CLOSE PIPES v << " "; term->rank(rank, v); v << term->blue << "Closing the the pipes " << term->reset << "(file descriptor " << parent_read << ", "<< parent_write << ", " << child_read << ", " << child_write<< ") . . . "; if (close(parent_read) == -1) { term->failed_pipe_read(); exit(EXIT_PIPE_WRITE_ERROR); } if (close(parent_write) == -1) { term->failed_pipe_write(); exit(EXIT_PIPE_WRITE_ERROR); } if (close(child_read) == -1) { term->failed_pipe_write(); exit(EXIT_PIPE_WRITE_ERROR); } if (close(child_write) == -1) { term->failed_pipe_write(); exit(EXIT_PIPE_WRITE_ERROR); } term->done(v); // Free the simulation arguments for (int i = 0; sim_args[i] != NULL; i++) { mfree(sim_args[i]); } mfree(sim_args); // libSRES requires scores from 0 to 1 with 0 being a perfect score so convert the simulation's score format into libSRES's return score; }
/* simulate_set performs the required piping to setup and run a simulation with the given parameters parameters: parameters: the parameters to pass as a parameter set to the simulation returns: the score the simulation received notes: todo: */ double simulate_set (double parameters[]) { // Get the MPI rank of the process int rank = get_rank(); ostream& v = term->verbose(); // Create a pipe int pipes[2]; v << " "; term->rank(rank, v); v << term->blue << "Creating a pipe " << term->reset << ". . . "; if (pipe(pipes) == -1) { term->failed_pipe_create(); exit(EXIT_PIPE_CREATE_ERROR); } v << term->blue << "Done: " << term->reset << "using file descriptors " << pipes[0] << " and " << pipes[1] << endl; // Fork the process so the child can run the simulation v << " "; term->rank(rank, v); v << term->blue << "Forking the process " << term->reset << ". . . "; pid_t pid = fork(); if (pid == -1) { term->failed_fork(); exit(EXIT_FORK_ERROR); } int child_pid; if (pid == 0) { child_pid = getpid(); } else { child_pid = pid; v << term->blue << "Done: " << term->reset << "the child process's PID is " << child_pid << endl; } int rank_strlen = INT_STRLEN(rank); char* grad_fname = (char*)mallocate(sizeof(char) * (strlen("input-.gradients") + rank_strlen + 1)); sprintf(grad_fname, "input-%d.gradients", rank); if (pid == 0) { char** sim_args = copy_args(ip.sim_args, ip.num_sim_args); store_pipe(sim_args, ip.num_sim_args - 6, pipes[0]); store_pipe(sim_args, ip.num_sim_args - 4, pipes[1]); sim_args[ip.num_sim_args - 2] = grad_fname; ofstream grad_file; v << " "; term->rank(rank, v); open_file(&grad_file, grad_fname, false); if (ip.base_gradients != NULL) { grad_file << ip.base_gradients << "\n"; } int loc_start = parameters[0]; int loc_end = parameters[1]; int val = parameters[2]; gradient_index* gi = ip.gradient_indices; while (gi != NULL) { grad_file << gi->index << " (" << loc_start << " 100) (" << loc_end << " " << val << ")\n"; gi = gi->next; } grad_file.close(); v << " "; term->rank(rank, v); v << term->blue << "Checking that the simulation file exists and can be executed " << term->reset << ". . . "; if (access(ip.sim_file, X_OK) == -1) { term->failed_exec(); exit(EXIT_EXEC_ERROR); } term->done(v); if (execv(ip.sim_file, sim_args) == -1) { term->failed_exec(); exit(EXIT_EXEC_ERROR); } } else { v << " "; term->rank(rank, v); v << term->blue << "Writing to the pipe " << term->reset << "(file descriptor " << pipes[1] << ") . . . "; write_pipe(pipes[1], ip.sets, ip.num_sets); term->done(v); } // Wait for the child to finish simulating int status = 0; waitpid(pid, &status, WUNTRACED); if (WIFEXITED(status) == 0) { term->failed_child(); exit(EXIT_CHILD_ERROR); } // Close the writing end of the pipe if (close(pipes[1]) == -1) { term->failed_pipe_write(); exit(EXIT_PIPE_WRITE_ERROR); } // Pipe in the simulation's score int max_score; int scores[ip.num_sets]; memset(scores, 0, sizeof(int) * ip.num_sets); v << " "; term->rank(rank, v); v << term->blue << "Reading the pipe " << term->reset << "(file descriptor " << pipes[0] << ") . . . "; read_pipe(pipes[0], &max_score, scores, ip.num_sets); v << term->blue << "Done: " << term->reset << "(raw score of set 0: " << scores[0] << " / " << max_score << ")" << endl; // Close the reading end of the pipe v << " "; term->rank(rank, v); v << term->blue << "Closing the reading end of the pipe " << term->reset << "(file descriptor " << pipes[0] << ") . . . "; if (close(pipes[0]) == -1) { term->failed_pipe_read(); exit(EXIT_PIPE_WRITE_ERROR); } term->done(v); // Remove the gradient file v << " "; term->rank(rank, v); v << term->blue << "Removing " << term->reset << grad_fname << " . . . "; if (remove(grad_fname) != 0) { term->failed_file_remove(grad_fname); exit(EXIT_FILE_REMOVE_ERROR); } mfree(grad_fname); term->done(v); // Calculate the average score of all the runs int avg_score = 0; for (int i = 0; i < ip.num_sets; i++) { avg_score += scores[i]; } avg_score /= ip.num_sets; // libSRES requires scores from 0 to 1 with 0 being a perfect score so convert the simulation's score format into libSRES's return 1 - ((double)avg_score / max_score); }