static void do_child_1(void) { pid_t pid; int i; for (i = 0; i < MAXKIDS; i++) { pid = SAFE_FORK(); if (pid == 0) { if (i == 0 || i == 1) do_exit(0); if (i == 2 || i == 3) do_compute(); if (i == 4 || i == 5) do_fork(); if (i == 6 || i == 7) do_sleep(); } fork_kid_pid[i] = pid; } TST_CHECKPOINT_WAKE2(0, MAXKIDS); if (TST_TRACE(reap_children(0, 0, fork_kid_pid, MAXKIDS))) return; tst_res(TPASS, "Test PASSED"); }
int main(int ac, char **av) { int kid_count, ret_val, status, nkids; int i, j, k, found; int fork_kid_pid[MAXKIDS], wait_kid_pid[MAXKIDS]; int runtime; /* time(sec) to run this process */ int lc; char *msg; msg = parse_opts(ac, av, NULL, NULL); if (msg != NULL) tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg); #ifdef UCLINUX argv0 = av[0]; maybe_run_child(&do_exit, "n", 1); maybe_run_child(&do_compute, "n", 2); maybe_run_child(&do_fork, "n", 3); maybe_run_child(&do_sleep, "n", 4); maybe_run_child(&do_mkdir, "n", 5); #endif /* * process the arg -- If there is one arg, it is the * number of seconds to run. If there is no arg the program * defaults to 60 sec runtime. */ if (ac == 2) { if (sscanf(av[1], "%d", &runtime) != 1) tst_resm(TFAIL, "%s is an invalid argument", av[1]); } else { runtime = 60; } setup(); for (lc = 0; TEST_LOOPING(lc); lc++) { /* reset tst_count in case we are looping */ tst_count = 0; fail = 0; if (signal(SIGALRM, alrmhandlr) == SIG_ERR) { tst_resm(TFAIL, "signal SIGALRM failed. errno = %d", errno); } alrmintr = 0; /* * Set up to catch SIGINT. The kids will wait till a SIGINT * has been received before they proceed. */ if (signal(SIGINT, inthandlr) == SIG_ERR) { tst_resm(TFAIL, "signal SIGINT failed. errno = %d", errno); } intintr = 0; /* Turn on the real time interval timer. */ if ((alarm(runtime)) < 0) tst_resm(TFAIL, "alarm failed. errno = %d", errno); /* Run the test over and over until the timer expires */ for (;;) { if (alrmintr) break; /* * Fork 8 kids. There will be 4 sets of 2 processes * doing the same thing. Save all kid pid's in an * array for future use. The kids will first wait for * the parent to send SIGINT. Then will proceed to * their assigned tasks. */ kid_count = 0; /* * Clearing the intinitr flag here for all the children. * So that we may not miss any signals ! */ intintr = 0; ret_val = FORK_OR_VFORK(); if (ret_val == 0) { /* child 0 */ #ifdef UCLINUX if (self_exec(argv0, "n", 1) < 0) tst_resm(TFAIL, "self_exec 0 failed"); #else do_exit(); #endif } if (ret_val < 0) { tst_resm(TFAIL, "Fork kid 0 failed. errno = " "%d", errno); } /* parent */ fork_kid_pid[kid_count++] = ret_val; ret_val = FORK_OR_VFORK(); if (ret_val == 0) { /* child 1 */ #ifdef UCLINUX if (self_exec(argv0, "n", 1) < 0) tst_resm(TFAIL, "self_exec 1 failed"); #else do_exit(); #endif } if (ret_val < 0) { tst_resm(TFAIL, "Fork kid 1 failed. errno = " "%d", errno); } /* parent */ fork_kid_pid[kid_count++] = ret_val; ret_val = FORK_OR_VFORK(); if (ret_val == 0) { /* child 2 */ #ifdef UCLINUX if (self_exec(argv0, "n", 2) < 0) tst_resm(TFAIL, "self_exec 2 failed"); #else do_compute(); #endif } if (ret_val < 0) { tst_resm(TFAIL, "Fork kid 2 failed. errno = " "%d", errno); } /* parent */ fork_kid_pid[kid_count++] = ret_val; ret_val = FORK_OR_VFORK(); if (ret_val == 0) { /* child 3 */ #ifdef UCLINUX if (self_exec(argv0, "n", 2) < 0) tst_resm(TFAIL, "self_exec 3 failed"); #else do_compute(); #endif } if (ret_val < 0) { tst_resm(TFAIL, "Fork kid 3 failed. errno = " "%d", errno); } /* parent */ fork_kid_pid[kid_count++] = ret_val; ret_val = FORK_OR_VFORK(); if (ret_val == 0) { /* child 4 */ #ifdef UCLINUX if (self_exec(argv0, "n", 3) < 0) tst_resm(TFAIL, "self_exec 4 failed"); #else do_fork(); #endif } if (ret_val < 0) { tst_resm(TFAIL, "Fork kid 4 failed. errno = " "%d", errno); } /* parent */ fork_kid_pid[kid_count++] = ret_val; ret_val = FORK_OR_VFORK(); if (ret_val == 0) { /* child 5 */ #ifdef UCLINUX if (self_exec(argv0, "n", 3) < 0) tst_resm(TFAIL, "self_exec 5 failed"); #else do_fork(); #endif } if (ret_val < 0) { tst_resm(TFAIL, "Fork kid 5 failed. errno = " "%d", errno); } /* parent */ fork_kid_pid[kid_count++] = ret_val; ret_val = FORK_OR_VFORK(); if (ret_val == 0) { /* child 6 */ #ifdef UCLINUX if (self_exec(argv0, "n", 4) < 0) tst_resm(TFAIL, "self_exec 6 failed"); #else do_sleep(); #endif } if (ret_val < 0) { tst_resm(TFAIL, "Fork kid 6 failed. errno = " "%d", errno); } /* parent */ fork_kid_pid[kid_count++] = ret_val; ret_val = FORK_OR_VFORK(); if (ret_val == 0) { /* child 7 */ #ifdef UCLINUX if (self_exec(argv0, "n", 4) < 0) tst_resm(TFAIL, "self_exec 7 failed"); #else do_sleep(); #endif } if (ret_val < 0) { tst_resm(TFAIL, "Fork kid 7 failed. errno = " "%d", errno); } /* parent */ fork_kid_pid[kid_count++] = ret_val; nkids = kid_count; /* * Now send all the kids a SIGINT to tell them to * proceed. We sleep for a while first to allow the * children to initialize their "intintr" variables * and get set up. */ sleep(15); for (i = 0; i < nkids; i++) { if (kill(fork_kid_pid[i], SIGINT) < 0) { tst_resm(TFAIL, "Kill of child %d " "failed, errno = %d", i, errno); } } /* Wait till all kids have terminated. */ kid_count = 0; errno = 0; for (i = 0; i < nkids; i++) { while (((ret_val = waitpid(fork_kid_pid[i], &status, 0)) != -1) || (errno == EINTR)) { if (ret_val == -1) continue; wait_kid_pid[kid_count++] = ret_val; } } /* * Check that for every entry in the fork_kid_pid * array, there is a matching pid in the * wait_kid_pid array. */ for (i = 0; i < MAXKIDS; i++) { found = 0; for (j = 0; j < MAXKIDS; j++) { if (fork_kid_pid[i] == wait_kid_pid[j]) { found = 1; break; } } if (!found) { tst_resm(TFAIL, "Did not find a " "wait_kid_pid for the " "fork_kid_pid of %d", fork_kid_pid[i]); for (k = 0; k < nkids; k++) { tst_resm(TFAIL, "fork_kid_pid[%d] = " "%d", k, fork_kid_pid[k]); } for (k = 0; k < kid_count; k++) { tst_resm(TFAIL, "wait_kid_pid[%d] = " "%d", k, wait_kid_pid[k]); } fail = 1; } } } /* Kill kids and remove file from do_mkdir */ rmdir("waitpid14.ttt.ttt"); if (fail) tst_resm(TFAIL, "Test FAILED"); else tst_resm(TPASS, "Test PASSED"); } cleanup(); tst_exit(); }
/* ARGSUSED */ static void do_nonl_proc(Widget, XtPointer, XtPointer) { int i, setno, loadset, loadto, graphto, npar, info; double tol, a[MAXPARM]; char fstr[256]; double *y, *yp; set_wait_cursor(); curset = setno = (int)GetChoice(nonl_set_item); loadto = (int)GetChoice(nonl_load_item); graphto = (int)GetChoice(nonl_loadgraph_item) - 1; tol = atof((char *)xv_getstr(nonl_tol_item)); if (graphto < 0) { graphto = cg; } npar = atoi((char *)xv_getstr(nonl_nparm_item)); strcpy(fstr, (char *)xv_getstr(nonl_formula_item)); for (i = 0; i < MAXPARM; i++) { a[i] = 0.0; strcpy(buf, (char *)xv_getstr(nonl_initial_item[i])); sscanf(buf, "%lf", &a[i]); } yp = (double *)calloc(getsetlength(cg, setno), sizeof(double)); if (yp == NULL) { errwin("Memory allocation error, operation cancelled"); unset_wait_cursor(); return; } y = gety(cg, setno); for (i = 0; i < getsetlength(cg, setno); i++) { yp[i] = y[i]; } sprintf(buf, "Fitting: %s\n", fstr); stufftext(buf, 0); sprintf(buf, "Initial guess:\n"); stufftext(buf, 0); for (i = 0; i < npar; i++) { sprintf(buf, "\ta%1d = %.9lf\n", i, a[i]); stufftext(buf, 0); } sprintf(buf, "Tolerance = %.9lf\n", tol); stufftext(buf, 0); lmfit(fstr, getsetlength(cg, setno), getx(cg, setno), yp, y, npar, a, tol, &info); for (i = 0; i < getsetlength(cg, setno); i++) { y[i] = yp[i]; } free(yp); for (i = 0; i < MAXPARM; i++) { sprintf(buf, "%.9lf", a[i]); xv_setstr(nonl_computed_item[i], buf); nonl_parms[i] = a[i]; } if (info > 0 && info < 4) { sprintf(buf, "Computed values:\n"); stufftext(buf, 0); for (i = 0; i < npar; i++) { sprintf(buf, "\ta%1d = %.9lf\n", i, a[i]); stufftext(buf, 0); } loadset = nextset(cg); if (loadset != -1) { do_copyset(cg, setno, cg, loadset); } else { unset_wait_cursor(); return; } switch (loadto) { case 0: sprintf(buf, "Evaluating function and loading result to set %d:\n", loadset); stufftext(buf, 0); do_compute(loadset, 0, graphto, fstr); break; case 1: sprintf(buf, "Evaluating function and loading residuals to set %d:\n", loadset); stufftext(buf, 0); do_compute(loadset, 0, graphto, fstr); break; case 2: sprintf(buf, "Computed function not evaluated\n"); stufftext(buf, 0); break; } } /* if (info >= 4) { do_compute(setno, 1, graphto, fstr); } */ if (info >= 0 && info <= 7) { char *s; switch (info) { case 0: s = (char *)"Improper input parameters.\n"; break; case 1: s = (char *)"Relative error in the sum of squares is at most tol.\n"; break; case 2: s = (char *)"Relative error between A and the solution is at most tol.\n"; break; case 3: s = (char *)"Relative error in the sum of squares and A and the solution is at most tol.\n"; break; case 4: s = (char *)"Fvec is orthogonal to the columns of the jacobian to machine precision.\n"; break; case 5: s = (char *)"Number of calls to fcn has reached or exceeded 200*(n+1).\n"; break; case 6: s = (char *)"Tol is too small. No further reduction in the sum of squares is possible.\n"; break; case 7: s = (char *)"Tol is too small. No further improvement in the approximate solution A is possible.\n"; break; } stufftext(s, 0); stufftext((char *)"\n", 0); } unset_wait_cursor(); }
/* ARGSUSED */ static void do_nonl_proc(Widget w, XtPointer client_data, XtPointer call_data) { int i, npts = 0, info; double delx, *xfit, *y, *yfit; int nsteps = (int) client_data; set_wait_cursor(); curset = nlsetno = GetSelectedSet(nonl_set_item); if (curset == SET_SELECT_ERROR) { errmsg("No set selected"); unset_wait_cursor(); return; } nonl_opts.tolerance = atof((char *) xv_getstr(nonl_tol_item)); nonl_opts.parnum = GetChoice(nonl_nparm_item); strcpy(nonl_opts.formula, (char *) xv_getstr(nonl_formula_item)); for (i = 0; i < nonl_opts.parnum; i++) { strcpy(buf, (char *) xv_getstr(nonl_value_item[i])); if (sscanf(buf, "%lf", &nonl_parms[i].value) != 1) { errmsg("Invalid input in parameter field"); unset_wait_cursor(); return; } nonl_parms[i].constr = XmToggleButtonGetState(nonl_constr_item[i]); if (nonl_parms[i].constr) { strcpy(buf, (char *) xv_getstr(nonl_lowb_item[i])); if (sscanf(buf, "%lf", &nonl_parms[i].min) != 1) { errmsg("Invalid input in low-bound field"); unset_wait_cursor(); return; } strcpy(buf, (char *) xv_getstr(nonl_uppb_item[i])); if (sscanf(buf, "%lf", &nonl_parms[i].max) != 1) { errmsg("Invalid input in upper-bound field"); unset_wait_cursor(); return; } if ((nonl_parms[i].value < nonl_parms[i].min) || (nonl_parms[i].value > nonl_parms[i].max)) { errmsg("Initial values must be within bounds"); unset_wait_cursor(); return; } } } nonl_prefs.autoload = XmToggleButtonGetState(nonl_autol_item); for (i = 0; i < 3; i++) { if (XmToggleButtonGetState(nonl_load_item[i])) { nonl_prefs.load = i; break; } } if (nonl_prefs.load == LOAD_FUNCTION) { strcpy(buf, (char *) xv_getstr(nonl_start_item)); if (sscanf(buf, "%lf", &nonl_prefs.start) != 1) { errmsg("Invalid input in start field"); unset_wait_cursor(); return; } strcpy(buf, (char *) xv_getstr(nonl_stop_item)); if (sscanf(buf, "%lf", &nonl_prefs.stop) != 1) { errmsg("Invalid input in stop field"); unset_wait_cursor(); return; } strcpy(buf, (char *) xv_getstr(nonl_npts_item)); if (sscanf(buf, "%d", &nonl_prefs.npoints) != 1) { errmsg("Invalid input in start field"); unset_wait_cursor(); return; } } if (nsteps) { /* we are asked to fit */ sprintf(buf, "Fitting with formula: %s\n", nonl_opts.formula); stufftext(buf, 0); sprintf(buf, "Initial guesses:\n"); stufftext(buf, 0); for (i = 0; i < nonl_opts.parnum; i++) { sprintf(buf, "\ta%1d = %g\n", i, nonl_parms[i].value); stufftext(buf, 0); } sprintf(buf, "Tolerance = %g\n", nonl_opts.tolerance); stufftext(buf, 0); /* * The fit itself! */ info = do_nonlfit(cg, nlsetno, nsteps); if (info == -1) { errmsg("Memory allocation error in do_nonlfit()"); unset_wait_cursor(); return; } for (i = 0; i < nonl_opts.parnum; i++) { sprintf(buf, "%g", nonl_parms[i].value); xv_setstr(nonl_value_item[i], buf); } if ((info > 0 && info < 4) || (info == 5)) { sprintf(buf, "Computed values:\n"); stufftext(buf, 0); for (i = 0; i < nonl_opts.parnum; i++) { sprintf(buf, "\ta%1d = %g\n", i, nonl_parms[i].value); stufftext(buf, 0); } } if (info >= 0 && info <= 7) { char *s; switch (info) { case 0: s = "Improper input parameters.\n"; break; case 1: s = "Relative error in the sum of squares is at most tol.\n"; break; case 2: s = "Relative error between A and the solution is at most tol.\n"; break; case 3: s = "Relative error in the sum of squares and A and the solution is at most tol.\n"; break; case 4: s = "Fvec is orthogonal to the columns of the jacobian to machine precision.\n"; break; case 5: s = "\n"; break; case 6: s = "Tol is too small. No further reduction in the sum of squares is possible.\n"; break; case 7: s = "Tol is too small. No further improvement in the approximate solution A is possible.\n"; break; default: s = "\n"; errmsg("Internal error in do_nonl_proc(), please report"); break; } stufftext(s, 0); stufftext("\n", 0); } } /* endif (nsteps) */ /* * Select & activate a set to load results to */ if (!nsteps || nonl_prefs.autoload) { /* check if the set is already allocated */ if ((nlloadset == -1) || (nlloadset == nlsetno) || !getsetlength(cg, nlloadset)) { nlloadset = nextset(cg); if (nlloadset == -1) { errmsg("No more sets!"); unset_wait_cursor(); return; } else { activateset(cg, nlloadset); setlength(cg, nlloadset, 1); } } switch (nonl_prefs.load) { case LOAD_VALUES: sprintf(buf, "Evaluating fitted values and loading result to set %d:\n", nlloadset); stufftext(buf, 0); npts = getsetlength(cg, nlsetno); setlength(cg, nlloadset, npts); copycol2(cg, nlsetno, cg, nlloadset, 0); break; case LOAD_RESIDUALS: sprintf(buf, "Evaluating fitted values and loading residuals to set %d:\n", nlloadset); stufftext(buf, 0); npts = getsetlength(cg, nlsetno); setlength(cg, nlloadset, npts); copycol2(cg, nlsetno, cg, nlloadset, 0); break; case LOAD_FUNCTION: sprintf(buf, "Computing fitting function and loading result to set %d:\n", nlloadset); stufftext(buf, 0); npts = nonl_prefs.npoints; if (npts <= 1) { errmsg("Number of points must be > 1"); unset_wait_cursor(); return; } setlength(cg, nlloadset, npts); delx = (nonl_prefs.stop - nonl_prefs.start)/(npts - 1); xfit = getx(cg, nlloadset); for (i = 0; i < npts; i++) { xfit[i] = nonl_prefs.start + i * delx; } break; } setcomment(cg, nlloadset, nonl_opts.formula); do_compute(nlloadset, 0, cg, nonl_opts.formula); if (nonl_prefs.load == LOAD_RESIDUALS) { /* load residuals */ y = gety(cg, nlsetno); yfit = gety(cg, nlloadset); for (i = 0; i < npts; i++) { yfit[i] -= y[i]; } } update_set_lists(cg); drawgraph(); } unset_wait_cursor(); }