Example #1
0
main()
{
	uint64	enough;
	double	timing, loop;

	enough = get_enough(0);
	printf("ENOUGH=%lu\n", (unsigned long)enough); fflush(stdout);
	timing = t_overhead();
	printf("TIMING_OVERHEAD=%f\n", timing); fflush(stdout);
	loop = l_overhead();
	printf("LOOP_OVERHEAD=%f\n", loop);
	printf("# version %d.%d\n", MAJOR, MINOR);
	exit(0);
}
Example #2
0
iter_t
benchmp_interval(void* _state)
{
	char		c;
	iter_t		iterations;
	double		result;
	fd_set		fds;
	struct timeval	timeout;
	benchmp_child_state* state = (benchmp_child_state*)_state;

	iterations = (state->state == timing_interval ? state->iterations : state->iterations_batch);

	if (state->need_warmup) {
		/* remove spurious compilation warning */
		result = state->enough;
	} else {
		result = stop(0,0);
		if (state->cleanup) {
			if (benchmp_sigchld_handler == SIG_DFL)
				signal(SIGCHLD, SIG_DFL);
			(*state->cleanup)(iterations, state->cookie);
		}
		save_n(state->iterations);
		result -= t_overhead() + get_n() * l_overhead();
		settime(result >= 0. ? (uint64)result : 0.);
	}

	/* if the parent died, then give up */
	if (getppid() == 1 && state->cleanup) {
		if (benchmp_sigchld_handler == SIG_DFL)
			signal(SIGCHLD, SIG_DFL);
		(*state->cleanup)(0, state->cookie);
		exit(0);
	}

	timeout.tv_sec = 0;
	timeout.tv_usec = 0;
	FD_ZERO(&fds);

	switch (state->state) {
	case warmup:
		iterations = state->iterations_batch;
		FD_SET(state->start_signal, &fds);
		select(state->start_signal+1, &fds, NULL,
		       NULL, &timeout);
		if (FD_ISSET(state->start_signal, &fds)) {
			state->state = timing_interval;
			read(state->start_signal, &c, sizeof(char));
			iterations = state->iterations;
		}
		if (state->need_warmup) {
			state->need_warmup = 0;
			/* send 'ready' */
			write(state->response, &c, sizeof(char));
		}
		break;
	case timing_interval:
		iterations = state->iterations;
		if (state->parallel > 1 || result > 0.95 * state->enough) {
			insertsort(gettime(), get_n(), get_results());
			state->i++;
			/* we completed all the experiments, return results */
			if (state->i >= state->repetitions) {
				state->state = cooldown;
			}
		}
		if (state->parallel == 1 
		    && (result < 0.99 * state->enough || result > 1.2 * state->enough)) {
			if (result > 150.) {
				double tmp = iterations / result;
				tmp *= 1.1 * state->enough;
				iterations = (iter_t)(tmp + 1);
			} else {
				iterations <<= 3;
				if (iterations > 1<<27
				    || (result < 0. && iterations > 1<<20)) {
					state->state = cooldown;
				}
			}
		}
		state->iterations = iterations;
		if (state->state == cooldown) {
			/* send 'done' */
			write(state->response, (void*)&c, sizeof(char));
			iterations = state->iterations_batch;
		}
		break;
	case cooldown:
		iterations = state->iterations_batch;
		FD_SET(state->result_signal, &fds);
		select(state->result_signal+1, &fds, NULL, NULL, &timeout);
		if (FD_ISSET(state->result_signal, &fds)) {
			/* 
			 * At this point all children have stopped their
			 * measurement loops, so we can block waiting for
			 * the parent to tell us to send our results back.
			 * From this point on, we will do no more "work".
			 */
			read(state->result_signal, (void*)&c, sizeof(char));
			write(state->response, (void*)get_results(), state->r_size);
			if (state->cleanup) {
				if (benchmp_sigchld_handler == SIG_DFL)
					signal(SIGCHLD, SIG_DFL);
				(*state->cleanup)(0, state->cookie);
			}

			/* Now wait for signal to exit */
			read(state->exit_signal, (void*)&c, sizeof(char));
			exit(0);
		}
	};
	if (state->initialize) {
		(*state->initialize)(iterations, state->cookie);
	}
	start(0);
	return (iterations);
}