Exemplo n.º 1
0
static void start_jobs(void)
{
	CronFile *file;
	CronLine *line;

	for (file = G.cron_files; file; file = file->cf_next) {
		if (!file->cf_wants_starting)
			continue;

		file->cf_wants_starting = 0;
		for (line = file->cf_lines; line; line = line->cl_next) {
			pid_t pid;
			if (line->cl_pid >= 0)
				continue;

			start_one_job(file->cf_username, line);
			pid = line->cl_pid;
			log8("USER %s pid %3d cmd %s",
				file->cf_username, (int)pid, line->cl_cmd);
			if (pid < 0) {
				file->cf_wants_starting = 1;
			}
			if (pid > 0) {
				file->cf_has_running = 1;
			}
		}
	}
}
/* Estimate number of operations based on formula derived in
   "A Practical Comparison of N-Body Algorithms" (Blelloc, Narlikar 1995)

   Should be more accurate for more uniform distributions.  Does not
   include the flops from the external potential. However, the effect
   of the potential actually reduces the total number of flops by
   tearing apart the system in general.

   Does not account for newer opening criteria.
 */
real nbEstimateNumberFlops(const NBodyCtx* ctx, int nbody)
{
    real quadTerm, baseTerm;

    real n = (real) nbody;
    real nSteps = ctx->timeEvolve / ctx->timestep;

    /* Cost of interaction for a cell using a quadrupole moment. */
    const real cQ = ctx->useQuad ? 50.0 : 0;

    /* Cost of a direct interaction */
    const real d = 13;

    /* Based on BH86 opening criterion. */
    real f = 28.0 * M_PI / (3.0 * cube(ctx->theta));

    /* FIXME: Don't be lazy and try rederiving for these. It should be
     * some number larger than for BH86. Somewhere I remember
     * something saying about 3x more operations for SW93
     */
    if (ctx->criterion != BH86)
    {
        f *= 3.0;
    }

    quadTerm = cQ * n * f * (log8(n / f) - 1.0);
    baseTerm = d * n * f;

    /* Total flops is then this times the number of timesteps */
    return nSteps * (quadTerm + baseTerm - worstFlops(cQ, d, f));
}
Exemplo n.º 3
0
/*
 * Determine which jobs need to be run.  Under normal conditions, the
 * period is about a minute (one scan).  Worst case it will be one
 * hour (60 scans).
 */
static void flag_starting_jobs(time_t t1, time_t t2)
{
	time_t t;

	/* Find jobs > t1 and <= t2 */

	for (t = t1 - t1 % 60; t <= t2; t += 60) {
		struct tm *ptm;
		CronFile *file;
		CronLine *line;

		if (t <= t1)
			continue;

		ptm = localtime(&t);
		for (file = G.cron_files; file; file = file->cf_next) {
			log5("file %s:", file->cf_username);
			if (file->cf_deleted)
				continue;
			for (line = file->cf_lines; line; line = line->cl_next) {
				log5(" line %s", line->cl_cmd);
				if (line->cl_Mins[ptm->tm_min]
				 && line->cl_Hrs[ptm->tm_hour]
				 && (line->cl_Days[ptm->tm_mday] || line->cl_Dow[ptm->tm_wday])
				 && line->cl_Mons[ptm->tm_mon]
				) {
					log5(" job: %d %s",
							(int)line->cl_pid, line->cl_cmd);
					if (line->cl_pid > 0) {
						log8("user %s: process already running: %s",
							file->cf_username, line->cl_cmd);
					} else if (line->cl_pid == 0) {
						line->cl_pid = -1;
						file->cf_wants_starting = 1;
					}
				}
			}
		}
	}
}
Exemplo n.º 4
0
int crond_main(int argc UNUSED_PARAM, char **argv)
{
	time_t t2;
	unsigned rescan;
	unsigned sleep_time;
	unsigned opts;

	INIT_G();

	/* "-b after -f is ignored", and so on for every pair a-b */
	opt_complementary = "f-b:b-f:S-L:L-S" IF_FEATURE_CROND_D(":d-l")
			/* -l and -d have numeric param */
			":l+" IF_FEATURE_CROND_D(":d+");
	opts = getopt32(argv, "l:L:fbSc:" IF_FEATURE_CROND_D("d:"),
			&G.log_level, &G.log_filename, &G.crontab_dir_name
			IF_FEATURE_CROND_D(,&G.log_level));
	/* both -d N and -l N set the same variable: G.log_level */

	if (!(opts & OPT_f)) {
		/* close stdin, stdout, stderr.
		 * close unused descriptors - don't need them. */
		bb_daemonize_or_rexec(DAEMON_CLOSE_EXTRA_FDS, argv);
	}

	if (!(opts & OPT_d) && G.log_filename == NULL) {
		/* logging to syslog */
		openlog(applet_name, LOG_CONS | LOG_PID, LOG_CRON);
		logmode = LOGMODE_SYSLOG;
	}

	//signal(SIGHUP, SIG_IGN); /* ? original crond dies on HUP... */

	reopen_logfile_to_stderr();
	xchdir(G.crontab_dir_name);
	log8("crond (busybox "BB_VER") started, log level %d", G.log_level);
	rescan_crontab_dir();
	write_pidfile(CONFIG_PID_FILE_PATH "/crond.pid");

	/* Main loop */
	t2 = time(NULL);
	rescan = 60;
	sleep_time = 60;
	for (;;) {
		struct stat sbuf;
		time_t t1;
		long dt;

		/* Synchronize to 1 minute, minimum 1 second */
		t1 = t2;
		sleep(sleep_time - (time(NULL) % sleep_time));
		t2 = time(NULL);
		dt = (long)t2 - (long)t1;

		reopen_logfile_to_stderr();

		/*
		 * The file 'cron.update' is checked to determine new cron
		 * jobs.  The directory is rescanned once an hour to deal
		 * with any screwups.
		 *
		 * Check for time jump.  Disparities over an hour either way
		 * result in resynchronization.  A negative disparity
		 * less than an hour causes us to effectively sleep until we
		 * match the original time (i.e. no re-execution of jobs that
		 * have just been run).  A positive disparity less than
		 * an hour causes intermediate jobs to be run, but only once
		 * in the worst case.
		 *
		 * When running jobs, the inequality used is greater but not
		 * equal to t1, and less then or equal to t2.
		 */
		if (stat(G.crontab_dir_name, &sbuf) != 0)
			sbuf.st_mtime = 0; /* force update (once) if dir was deleted */
		if (G.crontab_dir_mtime != sbuf.st_mtime) {
			G.crontab_dir_mtime = sbuf.st_mtime;
			rescan = 1;
		}
		if (--rescan == 0) {
			rescan = 60;
			rescan_crontab_dir();
		}
		process_cron_update_file();
		log5("wakeup dt=%ld", dt);
		if (dt < -60 * 60 || dt > 60 * 60) {
			bb_error_msg("time disparity of %ld minutes detected", dt / 60);
			/* and we do not run any jobs in this case */
		} else if (dt > 0) {
			/* Usual case: time advances forward, as expected */
			flag_starting_jobs(t1, t2);
			start_jobs();
			sleep_time = 60;
			if (check_completions() > 0) {
				/* some jobs are still running */
				sleep_time = 10;
			}
		}
		/* else: time jumped back, do not run any jobs */
	} /* for (;;) */

	return 0; /* not reached */
}