akaros/tests/alarm.c
<<
>>
Prefs
   1/* Copyright (c) 2013 The Regents of the University of California
   2 * Barret Rhoden <brho@cs.berkeley.edu>
   3 * See LICENSE for details.
   4 *
   5 * alarm: basic functionality test for the #alarm device */
   6
   7#include <stdlib.h>
   8#include <parlib/stdio.h>
   9#include <parlib/parlib.h>
  10#include <unistd.h>
  11#include <parlib/event.h>
  12#include <benchutil/measure.h>
  13#include <parlib/alarm.h>
  14#include <parlib/uthread.h>
  15#include <parlib/timing.h>
  16
  17/* Am I the only one annoyed at how open has different includes than
  18 * close/read/write? */
  19/* NO. Ron. */
  20#include <sys/types.h>
  21#include <sys/stat.h>
  22#include <fcntl.h>
  23
  24static void handle_alarm(struct event_msg *ev_msg, unsigned int ev_type,
  25                         void *data)
  26{
  27        assert(ev_type == EV_ALARM);
  28        printf("\tAlarm fired!, id %p\n", devalarm_get_id(ev_msg));
  29}
  30
  31int main(int argc, char **argv)
  32{
  33        int ctlfd, timerfd, alarm_nr, ret, srvfd;
  34        char buf[20];
  35        struct event_queue *ev_q;
  36
  37        printf("Starting alarm test\n");
  38        if (devalarm_get_fds(&ctlfd, &timerfd, 0)) {
  39                perror("Alarm setup");
  40                exit(-1);
  41        }
  42        /* Since we're doing SPAM_PUBLIC later, we actually don't need a big
  43         * ev_q.  But someone might copy/paste this and change a flag. */
  44        register_ev_handler(EV_ALARM, handle_alarm, 0);
  45        if (!(ev_q = get_eventq(EV_MBOX_UCQ))) {
  46                perror("Failed ev_q");  /* it'll actually PF if malloc fails */
  47                exit(-1);
  48        }
  49        ev_q->ev_vcore = 0;
  50        /* I think this is all the flags we need; gotta write that dissertation
  51         * chapter (and event how-to)!  We may get more than one event per
  52         * alarm, if we have concurrent preempts/yields. */
  53        ev_q->ev_flags = EVENT_IPI | EVENT_SPAM_PUBLIC | EVENT_WAKEUP;
  54        /* Register the ev_q for our alarm */
  55        if (devalarm_set_evq(timerfd, ev_q, 0xdeadbeef)) {
  56                perror("Failed to set evq");
  57                exit(-1);
  58        }
  59        /* Try to set, then cancel before it should go off */
  60        if (devalarm_set_time(timerfd, read_tsc() + sec2tsc(1))) {
  61                perror("Failed to set timer");
  62                exit(-1);
  63        }
  64        if (devalarm_disable(timerfd)) {
  65                perror("Failed to cancel timer");
  66                exit(-1);
  67        }
  68        uthread_sleep(2);
  69        printf("No alarm should have fired yet\n");
  70        /* Try to set and receive */
  71        if (devalarm_set_time(timerfd, read_tsc() + sec2tsc(1))) {
  72                perror("Failed to set timer");
  73                exit(-1);
  74        }
  75        uthread_sleep(2);
  76        close(ctlfd);
  77        /* get crazy: post the timerfd to #srv, then sleep (or even try to
  78         * exit), and then echo into it remotely!  A few limitations:
  79         * - if the process is DYING, you won't be able to send an event to it.
  80         * - the process won't leave DYING til the srv file is removed. */
  81        srvfd = open("#srv/alarmtest", O_WRONLY | O_CREAT | O_EXCL, 0666);
  82        if (srvfd < 0) {
  83                perror("Failed to open srv file");
  84                exit(-1);
  85        }
  86        ret = snprintf(buf, sizeof(buf), "%d", timerfd);
  87        ret = write(srvfd, buf, ret);
  88        if (ret <= 0) {
  89                perror("Failed to post timerfd");
  90                exit(-1);
  91        }
  92        printf("Sleeping for 10 sec, try to echo 111 > '#srv/alarmtest' now\n");
  93        uthread_sleep(10);
  94        ret = unlink("#srv/alarmtest");
  95        if (ret < 0) {
  96                perror("Failed to remove timerfd from #srv, proc will never be freed");
  97                exit(-1);
  98        }
  99        printf("Done\n");
 100        return 0;
 101}
 102