* Barret Rhoden <brho@cs.berkeley.edu>
* See LICENSE for details.
*
- * alarm: basic functionality test for the #A device */
+ * alarm: basic functionality test for the #alarm device */
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <parlib/event.h>
#include <benchutil/measure.h>
+#include <parlib/alarm.h>
#include <parlib/uthread.h>
#include <parlib/timing.h>
void *data)
{
assert(ev_type == EV_ALARM);
- printf("\tAlarm fired!, id %d\n", ev_msg ? ev_msg->ev_arg2 : 55555);
+ printf("\tAlarm fired!, id %p\n", devalarm_get_id(ev_msg));
}
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");
+ if (devalarm_get_fds(&ctlfd, &timerfd, 0)) {
+ perror("Alarm setup");
exit(-1);
}
/* Since we're doing SPAM_PUBLIC later, we actually don't need a big ev_q.
* we have concurrent preempts/yields. */
ev_q->ev_flags = EVENT_IPI | EVENT_SPAM_PUBLIC | EVENT_WAKEUP;
/* 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");
+ if (devalarm_set_evq(timerfd, ev_q, 0xdeadbeef)) {
+ perror("Failed to set evq");
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) {
+ if (devalarm_set_time(timerfd, read_tsc() + sec2tsc(1))) {
perror("Failed to set timer");
exit(-1);
}
- ret = snprintf(buf, sizeof(buf), "cancel");
- ret = write(ctlfd, buf, ret);
- if (ret <= 0) {
+ if (devalarm_disable(timerfd)) {
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) {
+ if (devalarm_set_time(timerfd, read_tsc() + sec2tsc(1))) {
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
+ /* get crazy: post the timerfd to #srv, 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);
+ srvfd = open("#srv/alarmtest", O_WRONLY | O_CREAT | O_EXCL, 0666);
if (srvfd < 0) {
perror("Failed to open srv file");
exit(-1);
perror("Failed to post timerfd");
exit(-1);
}
- printf("Sleeping for 10 sec, try to echo 111 > '#s/alarmtest' now!\n");
+ printf("Sleeping for 10 sec, try to echo 111 > '#srv/alarmtest' now!\n");
uthread_sleep(10);
- ret = unlink("#s/alarmtest");
+ ret = unlink("#srv/alarmtest");
if (ret < 0) {
- perror("Failed to remove timerfd from #s, proc will never be freed");
+ perror("Failed to remove timerfd from #srv, proc will never be freed");
exit(-1);
}
printf("Done\n");