Exemplo n.º 1
0
Arquivo: time.c Projeto: goovdl/akaros
void tsc2timespec(uint64_t tsc_time, struct timespec *ts)
{
	ts->tv_sec = tsc2sec(tsc_time);
	/* subtract off everything but the remainder */
	tsc_time -= sec2tsc(ts->tv_sec);
	ts->tv_nsec = tsc2nsec(tsc_time);
}
Exemplo n.º 2
0
uint64_t msec2tsc(uint64_t msec)
{
	if (mult_will_overflow_u64(msec, get_tsc_freq()))
		return sec2tsc(msec / 1000);
	else
		return (msec * get_tsc_freq()) / 1000;
}
Exemplo n.º 3
0
Arquivo: time.c Projeto: goovdl/akaros
uint64_t msec2tsc(uint64_t msec)
{
	if (mult_will_overflow_u64(msec, system_timing.tsc_freq))
		return sec2tsc(msec / 1000);
	else
		return (msec * system_timing.tsc_freq) / 1000;
}
Exemplo n.º 4
0
Arquivo: time.c Projeto: goovdl/akaros
uint64_t epoch_tsc(void)
{
	return read_tsc() + sec2tsc(boot_sec);
}
Exemplo n.º 5
0
int main(int argc, char **argv)
{
	int ctlfd, timerfd, alarm_nr, ret, srvfd;
	char buf[20];
	char path[32];
	struct event_queue *ev_q;

	printf("Starting alarm test\n");
	/* standard 9ns stuff: clone and read it to get our path, ending up with the
	 * ctlfd and timerfd for #A/aN/{ctl,timer}.  if you plan to fork, you can
	 * open CLOEXEC. */
	ctlfd = open("#A/clone", O_RDWR | O_CLOEXEC);
	if (ctlfd < 0) {
		perror("Can't clone an alarm");
		exit(-1);
	}
	ret = read(ctlfd, buf, sizeof(buf) - 1);
	if (ret <= 0) {
		if (!ret)
			printf("Got early EOF from ctl\n");
		else
			perror("Can't read ctl");
		exit(-1);
	}
	buf[ret] = 0;
	snprintf(path, sizeof(path), "#A/a%s/timer", buf);
	/* Don't open CLOEXEC if you want to post it to srv later */
	timerfd = open(path, O_RDWR);
	if (timerfd < 0) {
		perror("Can't open timer");
		exit(-1);
	}
	/* Since we're doing SPAM_PUBLIC later, we actually don't need a big ev_q.
	 * But someone might copy/paste this and change a flag. */
	register_ev_handler(EV_ALARM, handle_alarm, 0);
	if (!(ev_q = get_big_event_q())) {
		perror("Failed ev_q");	/* it'll actually PF if malloc fails */
		exit(-1);
	}
	ev_q->ev_vcore = 0;
	/* I think this is all the flags we need; gotta write that dissertation
	 * chapter (and event how-to)!  We may get more than one event per alarm, if
	 * we have concurrent preempts/yields. */
	ev_q->ev_flags = EVENT_IPI | EVENT_SPAM_PUBLIC;
	/* Register the ev_q for our alarm */
	ret = snprintf(path, sizeof(path), "evq %llx", ev_q);
	ret = write(ctlfd, path, ret);
	if (ret <= 0) {
		perror("Failed to write ev_q");
		exit(-1);
	}
	/* Try to set, then cancel before it should go off */
	ret = snprintf(buf, sizeof(buf), "%llx", read_tsc() + sec2tsc(1));
	ret = write(timerfd, buf, ret);
	if (ret <= 0) {
		perror("Failed to set timer");
		exit(-1);
	}
	ret = snprintf(buf, sizeof(buf), "cancel");
	ret = write(ctlfd, buf, ret);
	if (ret <= 0) {
		perror("Failed to cancel timer");
		exit(-1);
	}
	uthread_sleep(2);
	printf("No alarm should have fired yet\n");
	/* Try to set and receive */
	ret = snprintf(buf, sizeof(buf), "%llx", read_tsc() + sec2tsc(1));
	ret = write(timerfd, buf, ret);
	if (ret <= 0) {
		perror("Failed to set timer");
		exit(-1);
	}
	uthread_sleep(2);
	close(ctlfd);
	/* get crazy: post the timerfd to #s, then sleep (or even try to exit), and
	 * then echo into it remotely!  A few limitations:
	 * - if the process is DYING, you won't be able to send an event to it.
	 * - the process won't leave DYING til the srv file is removed. */
	srvfd = open("#s/alarmtest", O_WRONLY | O_CREAT | O_EXCL, 0666);
	if (srvfd < 0) {
		perror("Failed to open srv file");
		exit(-1);
	}
	ret = snprintf(buf, sizeof(buf), "%d", timerfd);
	ret = write(srvfd, buf, ret);
	if (ret <= 0) {
		perror("Failed to post timerfd");
		exit(-1);
	}
	printf("Sleeping for 10 sec, try to echo 111 > '#s/alarmtest' now!\n");
	uthread_sleep(10);
	ret = unlink("#s/alarmtest");
	if (ret < 0) {
		perror("Failed to remove timerfd from #s, proc will never be freed");
		exit(-1);
	}
	printf("Done\n");
	return 0;
}