Skip to content

Commit

Permalink
optimize performance by decrease calling gettimeofday();
Browse files Browse the repository at this point in the history
optimize performance in the hooked API for poll and epoll;
  • Loading branch information
root committed Mar 6, 2022
1 parent 47ce35a commit c532379
Show file tree
Hide file tree
Showing 6 changed files with 101 additions and 25 deletions.
2 changes: 1 addition & 1 deletion lib_fiber/c/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,9 @@ CFLAGS = -c -g -W \
-Wcast-qual \
-DUSE_FAST_RING \
-DUSE_JMP_DEF \
#-DUSE_FAST_TIME \
#-DUSE_VALGRIND \
#-DUSE_BOOST_JMP \
#-DUSE_FAST_TIME \
#-Waggregate-return \
#-DDEBUG_MEM \
#-I/usr/local/include
Expand Down
56 changes: 56 additions & 0 deletions lib_fiber/c/src/event.c
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ EVENT *event_create(int size)
ev->maxfd = -1;
ev->waiter = 0;

SET_TIME(ev->stamp); // init the event's stamp when create each event
#ifdef HAS_POLL
ring_init(&ev->poll_list);
#endif
Expand Down Expand Up @@ -97,6 +98,17 @@ void event_free(EVENT *ev)
ev->free(ev);
}

long long event_set_stamp(EVENT *ev)
{
SET_TIME(ev->stamp); // decrease the SET_TIME's calling count.
return ev->stamp;
}

long long event_get_stamp(EVENT *ev)
{
return ev->stamp;
}

#ifdef SYS_WIN
int event_checkfd(EVENT *ev, FILE_EVENT *fe)
{
Expand Down Expand Up @@ -374,6 +386,7 @@ static void event_prepare(EVENT *ev)
#ifdef HAS_POLL
static void event_process_poll(EVENT *ev)
{
#if 0
while (1) {
POLL_EVENT *pe;
RING *head = ring_pop_head(&ev->poll_list);
Expand All @@ -387,12 +400,32 @@ static void event_process_poll(EVENT *ev)
}

ring_init(&ev->poll_list);
#else
POLL_EVENT *pe;
RING *next, *curr;
long long now;

now = event_get_stamp(ev);

for (next = ring_succ(&ev->poll_list); next != &ev->poll_list;) {
pe = ring_to_appl(next, POLL_EVENT, me);
if (pe->nready != 0 || (pe->expire >= 0 && now >= pe->expire)) {
curr = next;
next = ring_succ(next);
ring_detach(curr);
pe->proc(ev, pe);
} else {
next = ring_succ(next);
}
}
#endif
}
#endif

#ifdef HAS_EPOLL
static void event_process_epoll(EVENT *ev)
{
#if 0
while (1) {
EPOLL_EVENT *ee;
RING *head = ring_pop_head(&ev->epoll_list);
Expand All @@ -402,6 +435,25 @@ static void event_process_epoll(EVENT *ev)
ee = TO_APPL(head, EPOLL_EVENT, me);
ee->proc(ev, ee);
}
#else
EPOLL_EVENT *ee;
RING *next, *curr;
long long now;

now = event_get_stamp(ev);

for (next = ring_succ(&ev->epoll_list); next != &ev->epoll_list;) {
ee = ring_to_appl(next, EPOLL_EVENT, me);
if (ee->nready != 0 || (ee->expire >= 0 && now >= ee->expire)) {
curr = next;
next = ring_succ(next);
ring_detach(curr);
ee->proc(ev, ee);
} else {
next = ring_succ(next);
}
}
#endif
}
#endif

Expand All @@ -427,8 +479,12 @@ int event_process(EVENT *ev, int timeout)
}

event_prepare(ev);

// call the system event waiting API for any event arriving.
ret = ev->event_wait(ev, timeout);

(void) event_set_stamp(ev); // reset the stamp after event waiting.

#ifdef HAS_POLL
event_process_poll(ev);
#endif
Expand Down
5 changes: 5 additions & 0 deletions lib_fiber/c/src/event.h
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,7 @@ struct POLL_EVENT {
RING me;
ACL_FIBER *fiber;
poll_proc *proc;
long long expire;
int nready;
int nfds;
POLLFD *fds;
Expand All @@ -181,6 +182,7 @@ struct EPOLL_EVENT {
ACL_FIBER *fiber;
epoll_proc *proc;
size_t nfds;
long long expire;
EPOLL_CTX **fds;
int epfd;

Expand All @@ -197,6 +199,7 @@ struct EVENT {
ssize_t setsize;
socket_t maxfd;

long long stamp; // the stamp of the current fiber scheduler
unsigned flag;
#define EVENT_F_IOCP (1 << 0)
#define EVENT_IS_IOCP(x) ((x)->flag & EVENT_F_IOCP)
Expand Down Expand Up @@ -237,6 +240,8 @@ acl_handle_t event_handle(EVENT *ev);
ssize_t event_size(EVENT *ev);
void event_free(EVENT *ev);
void event_close(EVENT *ev, FILE_EVENT *fe);
long long event_set_stamp(EVENT *ev);
long long event_get_stamp(EVENT *ev);

// check if the fd in fe is a valid socket, return 1 if yes, -1 if the fd
// is not a valid fd, 0 if the fd is valid but not a socket.
Expand Down
26 changes: 15 additions & 11 deletions lib_fiber/c/src/fiber_io.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ typedef struct {
int nsleeping;
int io_stop;
#ifdef SYS_WIN
HTABLE *events;
HTABLE *events;
#else
FILE_EVENT **events;
#endif
Expand Down Expand Up @@ -162,6 +162,12 @@ EVENT *fiber_io_event(void)
return __thread_fiber->event;
}

static long long fiber_io_stamp(void)
{
EVENT *ev = fiber_io_event();
return event_get_stamp(ev);
}

static void fiber_io_loop(ACL_FIBER *self fiber_unused, void *ctx)
{
EVENT *ev = (EVENT *) ctx;
Expand All @@ -177,7 +183,7 @@ static void fiber_io_loop(ACL_FIBER *self fiber_unused, void *ctx)
if (timer == NULL) {
left = -1;
} else {
SET_TIME(now);
now = event_get_stamp(__thread_fiber->event);
last = now;
if (now >= timer->when) {
left = 0;
Expand Down Expand Up @@ -205,8 +211,7 @@ static void fiber_io_loop(ACL_FIBER *self fiber_unused, void *ctx)
break;
}

SET_TIME(now);

now = event_get_stamp(__thread_fiber->event);
if (now - last < left) {
continue;
}
Expand All @@ -220,7 +225,6 @@ static void fiber_io_loop(ACL_FIBER *self fiber_unused, void *ctx)

acl_fiber_ready(timer);
timer = FIRST_FIBER(&__thread_fiber->ev_timer);

} while (timer != NULL && now >= timer->when);
}

Expand Down Expand Up @@ -263,7 +267,7 @@ unsigned int acl_fiber_delay(unsigned int milliseconds)

ev = fiber_io_event();

SET_TIME(now);
now = event_get_stamp(ev);
when = now + milliseconds;

/* The timers in the ring were stored from small to large in ascending
Expand Down Expand Up @@ -309,7 +313,7 @@ unsigned int acl_fiber_delay(unsigned int milliseconds)
ev->timeout = -1;
}

SET_TIME(now);
now = event_get_stamp(ev);
if (now < when) {
return 0;
}
Expand All @@ -321,7 +325,7 @@ static void fiber_timer_callback(ACL_FIBER *fiber, void *ctx)
{
long long now, left;

SET_TIME(now);
now = fiber_io_stamp();

for (;;) {
left = fiber->when > now ? fiber->when - now : 0;
Expand All @@ -331,7 +335,7 @@ static void fiber_timer_callback(ACL_FIBER *fiber, void *ctx)

acl_fiber_delay((unsigned int) left);

SET_TIME(now);
now = fiber_io_stamp();
if (fiber->when <= now) {
break;
}
Expand All @@ -349,7 +353,7 @@ ACL_FIBER *acl_fiber_create_timer(unsigned int milliseconds, size_t size,

fiber_io_check();

SET_TIME(when);
when = fiber_io_stamp();
when += milliseconds;

fiber = acl_fiber_create(fiber_timer_callback, ctx, size);
Expand All @@ -364,7 +368,7 @@ void acl_fiber_reset_timer(ACL_FIBER *fiber, unsigned int milliseconds)

fiber_io_check();

SET_TIME(when);
when = fiber_io_stamp();
when += milliseconds;
fiber->when = when;
fiber->status = FIBER_STATUS_READY;
Expand Down
17 changes: 11 additions & 6 deletions lib_fiber/c/src/hook/epoll.c
Original file line number Diff line number Diff line change
Expand Up @@ -376,16 +376,21 @@ static void event_epoll_set(EVENT *ev, EPOLL_EVENT *ee, int timeout)
ee->events[i].events = 0;
}

if (timeout >= 0 && (ev->timeout < 0 || timeout < ev->timeout)) {
ev->timeout = timeout;
if (timeout >= 0) {
ee->expire = event_get_stamp(ev) + timeout;
if (ev->timeout < 0 || timeout < ev->timeout) {
ev->timeout = timeout;
}
} else {
ee->expire = -1;
}
}

int epoll_wait(int epfd, struct epoll_event *events, int maxevents, int timeout)
{
EVENT *ev;
EPOLL_EVENT *ee;
long long begin, now;
long long now;
int old_timeout;

if (sys_epoll_wait == NULL) {
Expand Down Expand Up @@ -418,7 +423,6 @@ int epoll_wait(int epfd, struct epoll_event *events, int maxevents, int timeout)

old_timeout = ev->timeout;
event_epoll_set(ev, ee, timeout);
SET_TIME(begin);
ev->waiter++;

while (1) {
Expand All @@ -441,8 +445,9 @@ int epoll_wait(int epfd, struct epoll_event *events, int maxevents, int timeout)
if (ee->nready != 0 || timeout == 0) {
break;
}
SET_TIME(now);
if (timeout > 0 && (now - begin >= timeout)) {

now = event_get_stamp(ev);
if (ee->expire > 0 && now >= ee->expire) {
break;
}
}
Expand Down
20 changes: 13 additions & 7 deletions lib_fiber/c/src/hook/poll.c
Original file line number Diff line number Diff line change
Expand Up @@ -115,8 +115,13 @@ static void poll_event_set(EVENT *ev, POLL_EVENT *pe, int timeout)
pfd->pfd->revents = 0;
}

if (timeout >= 0 && (ev->timeout < 0 || timeout < ev->timeout)) {
ev->timeout = timeout;
if (timeout >= 0) {
pe->expire = event_get_stamp(ev) + timeout;
if (ev->timeout < 0 || timeout < ev->timeout) {
ev->timeout = timeout;
}
} else {
pe->expire = -1;
}
}

Expand All @@ -128,8 +133,9 @@ static void poll_event_clean(EVENT *ev, POLL_EVENT *pe)
POLLFD *pfd = &pe->fds[i];

/* maybe has been cleaned in read_callback/write_callback */
if (pfd->fe == NULL)
if (pfd->fe == NULL) {
continue;
}

CLR_POLLING(pfd->fe);

Expand Down Expand Up @@ -190,7 +196,7 @@ static void pollfd_free(POLLFD *pfds)

int WINAPI acl_fiber_poll(struct pollfd *fds, nfds_t nfds, int timeout)
{
long long begin, now;
long long now;
POLL_EVENT pe;
EVENT *ev;
int old_timeout;
Expand All @@ -212,7 +218,6 @@ int WINAPI acl_fiber_poll(struct pollfd *fds, nfds_t nfds, int timeout)

old_timeout = ev->timeout;
poll_event_set(ev, &pe, timeout);
SET_TIME(begin);
ev->waiter++;

while (1) {
Expand Down Expand Up @@ -242,8 +247,9 @@ int WINAPI acl_fiber_poll(struct pollfd *fds, nfds_t nfds, int timeout)
if (pe.nready != 0 || timeout == 0) {
break;
}
SET_TIME(now);
if (timeout > 0 && (now - begin >= timeout)) {

now = event_get_stamp(ev);
if (pe.expire > 0 && now >= pe.expire) {
acl_fiber_set_error(FIBER_ETIMEDOUT);
break;
}
Expand Down

0 comments on commit c532379

Please sign in to comment.