Skip to content
Browse files

postpone registration of epoll flags very agressively

git-svn-id: http://svn.coderepos.org/share/lang/c/picoev/trunk@35015 d0d07461-0603-4401-acd4-de1884942a52
  • Loading branch information...
1 parent b7a830e commit c32d52deffcba72f53487ec8cd255a9401bf95e7 kazuho committed
Showing with 71 additions and 38 deletions.
  1. +32 −15 picoev.h
  2. +39 −23 picoev_epoll.c
View
47 picoev.h
@@ -41,6 +41,7 @@ extern "C" {
#include <assert.h>
#include <limits.h>
#include <stdlib.h>
+#include <string.h>
#include <time.h>
#define PICOEV_IS_INITED (picoev.max_fd != 0)
@@ -82,7 +83,7 @@ extern "C" {
picoev_loop_id_t loop_id;
char events;
unsigned char timeout_idx; /* PICOEV_TIMEOUT_IDX_UNUSED if not used */
- int _backend; /* can be used by the backend (inited to -1) */
+ int _backend; /* can be used by the backend (never ever touched by core) */
} picoev_fd;
struct picoev_loop_st {
@@ -111,6 +112,24 @@ extern "C" {
extern picoev_globals picoev;
+ /* creates a new event loop (defined by each backend) */
+ picoev_loop* picoev_create_loop(int max_timeout);
+
+ /* destroys a loop (defined by each backend) */
+ int picoev_destroy_loop(picoev_loop* loop);
+
+ /* internal: initializes the backend */
+ int picoev_init_backend(void);
+
+ /* internal: destroys the backend */
+ int picoev_deinit_backend(void);
+
+ /* internal: updates events to be watched (defined by each backend) */
+ int picoev_update_events_internal(picoev_loop* loop, int fd, int events);
+
+ /* internal: poll once and call the handlers (defined by each backend) */
+ int picoev_poll_once_internal(picoev_loop* loop, int max_wait);
+
/* internal, aligned allocator */
PICOEV_INLINE
void* picoev_memalign(size_t sz, void** orig_addr) {
@@ -118,6 +137,7 @@ extern "C" {
if ((*orig_addr = malloc(sz)) == NULL) {
return NULL;
}
+ memset(*orig_addr, 0, sz);
return
(void*)PICOEV_RND_UP((unsigned long)*orig_addr, PICOEV_CACHE_LINE_SIZE);
}
@@ -139,32 +159,30 @@ extern "C" {
picoev.timeout_vec_of_vec_size
= PICOEV_RND_UP(picoev.timeout_vec_size, PICOEV_SIMD_BITS)
/ PICOEV_SHORT_BITS;
+ if (picoev_init_backend() != 0) {
+ free(picoev.fds);
+ picoev.fds = NULL;
+ picoev.max_fd = 0;
+ return -1;
+ }
return 0;
}
/* deinitializes picoev */
PICOEV_INLINE
- void picoev_deinit(void) {
+ int picoev_deinit(void) {
assert(PICOEV_IS_INITED);
+ if (picoev_deinit_backend() != 0) {
+ return -1;
+ }
free(picoev._fds_free_addr);
picoev.fds = NULL;
picoev._fds_free_addr = NULL;
picoev.max_fd = 0;
picoev.num_loops = 0;
+ return 0;
}
- /* creates a new event loop (defined by each backend) */
- picoev_loop* picoev_create_loop(int max_timeout);
-
- /* destroys a loop (defined by each backend) */
- int picoev_destroy_loop(picoev_loop* loop);
-
- /* internal: updates events to be watched (defined by each backend) */
- int picoev_update_events_internal(picoev_loop* loop, int fd, int events);
-
- /* internal: poll once and call the handlers (defined by each backend) */
- int picoev_poll_once_internal(picoev_loop* loop, int max_wait);
-
/* updates timeout */
PICOEV_INLINE
void picoev_set_timeout(picoev_loop* loop, int fd, int secs) {
@@ -214,7 +232,6 @@ extern "C" {
target->loop_id = loop->loop_id;
target->events = 0;
target->timeout_idx = PICOEV_TIMEOUT_IDX_UNUSED;
- target->_backend = -1;
if (events != 0
&& picoev_update_events_internal(loop, fd, events) != 0) {
target->loop_id = 0;
View
62 picoev_epoll.c
@@ -38,7 +38,7 @@ typedef struct picoev_loop_epoll_st {
struct epoll_event events[1024];
} picoev_loop_epoll;
-#define BACKEND_GET_NEXT_FD(backend) ((backend) >> 24)
+#define BACKEND_GET_NEXT_FD(backend) ((backend) >> 8)
#define BACKEND_GET_OLD_EVENTS(backend) ((char)backend)
#define BACKEND_BUILD(nextfd, oldevents) (((nextfd) << 8) | (oldevents))
@@ -55,7 +55,7 @@ __inline void picoev_call_epoll(picoev_loop_epoll* loop, int fd,
if (loop->loop.loop_id != target->loop_id) {
/* now used by another thread, disable */
CALL_EPOLL(loop->epfd, EPOLL_CTL_DEL, fd, 0);
- } else {
+ } else if (target->_backend != -1) {
int old_events = BACKEND_GET_OLD_EVENTS(target->_backend);
if (old_events != target->events) {
/* apply changes */
@@ -76,27 +76,6 @@ __inline void picoev_call_epoll(picoev_loop_epoll* loop, int fd,
}
}
-int picoev_update_events_internal(picoev_loop* _loop, int fd, int events)
-{
- picoev_loop_epoll* loop = (picoev_loop_epoll*)_loop;
- picoev_fd* target = picoev.fds + fd;
-
- assert(PICOEV_FD_BELONGS_TO_LOOP(&loop->loop, fd));
-
- if (target->events == events) {
- return 0;
- }
-
- /* update chain */
- if (target->_backend == -1) {
- target->_backend = BACKEND_BUILD(loop->changed_fds, target->events);
- loop->changed_fds = fd;
- }
- target->events = events;
-
- return 0;
-}
-
picoev_loop* picoev_create_loop(int max_timeout)
{
picoev_loop_epoll* loop;
@@ -134,6 +113,43 @@ int picoev_destroy_loop(picoev_loop* _loop)
return 0;
}
+int picoev_init_backend()
+{
+ int i;
+
+ for (i = 0; i < picoev.max_fd; ++i) {
+ picoev.fds[i]._backend = -1;
+ }
+
+ return 0;
+}
+
+int picoev_deinit_backend()
+{
+ return 0;
+}
+
+int picoev_update_events_internal(picoev_loop* _loop, int fd, int events)
+{
+ picoev_loop_epoll* loop = (picoev_loop_epoll*)_loop;
+ picoev_fd* target = picoev.fds + fd;
+
+ assert(PICOEV_FD_BELONGS_TO_LOOP(&loop->loop, fd));
+
+ if (target->events == events) {
+ return 0;
+ }
+
+ /* update chain */
+ if (target->_backend == -1) {
+ target->_backend = BACKEND_BUILD(loop->changed_fds, target->events);
+ loop->changed_fds = fd;
+ }
+ target->events = events;
+
+ return 0;
+}
+
int picoev_poll_once_internal(picoev_loop* _loop, int max_wait)
{
picoev_loop_epoll* loop = (picoev_loop_epoll*)_loop;

0 comments on commit c32d52d

Please sign in to comment.
Something went wrong with that request. Please try again.