[Sheepdog] [PATCH 2/2] sheep: use timerfd for the timer implementation
MORITA Kazutaka
morita.kazutaka at lab.ntt.co.jp
Wed Mar 30 12:49:34 CEST 2011
Signed-off-by: MORITA Kazutaka <morita.kazutaka at lab.ntt.co.jp>
---
include/event.h | 2 -
lib/event.c | 60 +++++++++++++++++++++++++-----------------------------
2 files changed, 28 insertions(+), 34 deletions(-)
diff --git a/include/event.h b/include/event.h
index b16c97a..39dfb7e 100644
--- a/include/event.h
+++ b/include/event.h
@@ -14,10 +14,8 @@ int modify_event(int fd, unsigned int events);
void event_loop(int timeout);
struct timer {
- struct list_head entry;
void (*callback)(void *);
void *data;
- unsigned int when;
};
void add_timer(struct timer *t, unsigned int seconds);
diff --git a/lib/event.c b/lib/event.c
index dd4d777..fd9e866 100644
--- a/lib/event.c
+++ b/lib/event.c
@@ -12,7 +12,9 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <unistd.h>
#include <sys/epoll.h>
+#include <sys/timerfd.h>
#include "list.h"
#include "util.h"
@@ -22,49 +24,44 @@
static int efd;
static LIST_HEAD(events_list);
-static LIST_HEAD(active_timer_list);
-static LIST_HEAD(inactive_timer_list);
-
-static int jiffies;
-
#define TICK 1
-void add_timer(struct timer *t, unsigned int seconds)
+static void timer_handler(int fd, int events, void *data)
{
- struct timer *n;
+ struct timer *t = data;
+ uint64_t val;
- if (seconds) {
- t->when = roundup(seconds, TICK) + jiffies;
+ if (read(fd, &val, sizeof(val)) < 0)
+ return;
- list_for_each_entry(n, &inactive_timer_list, entry) {
- if (before(t->when, n->when))
- break;
- }
+ t->callback(t->data);
- list_add_tail(&t->entry, &n->entry);
- } else
- list_add_tail(&t->entry, &active_timer_list);
+ unregister_event(fd);
+ close(fd);
}
-static void do_timer(void)
+void add_timer(struct timer *t, unsigned int seconds)
{
- struct timer *t, *n;
-
- list_for_each_entry_safe(t, n, &inactive_timer_list, entry) {
- if (after(jiffies, t->when)) {
- list_del(&t->entry);
- list_add_tail(&t->entry, &active_timer_list);
- } else
- break;
+ struct itimerspec it;
+ int tfd;
+
+ tfd = timerfd_create(CLOCK_MONOTONIC, TFD_NONBLOCK);
+ if (tfd < 0) {
+ eprintf("timerfd_create, %m\n");
+ return;
}
- while (!list_empty(&active_timer_list)) {
- t = list_first_entry(&active_timer_list, struct timer, entry);
- list_del_init(&t->entry);
- t->callback(t->data);
+ memset(&it, 0, sizeof(it));
+ it.it_value.tv_sec = seconds;
+
+ if (timerfd_settime(tfd, 0, &it, NULL) < 0) {
+ eprintf("timerfd_settime, %m\n");
+ return;
}
- jiffies++;
+ if (register_event(tfd, timer_handler, t) < 0) {
+ eprintf("failed to register timer fd\n");
+ }
}
struct event_info {
@@ -183,6 +180,5 @@ void event_loop(int timeout)
ei = (struct event_info *)events[i].data.ptr;
ei->handler(ei->fd, events[i].events, ei->data);
}
- } else
- do_timer();
+ }
}
--
1.5.6.5
More information about the sheepdog
mailing list