[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