mirror of
https://github.com/FRRouting/frr.git
synced 2025-04-30 13:37:17 +02:00
lib: Substitute poll APIs with epoll APIs in thread management routine
This commit substitutes poll APIs with epoll APIs for better performace. Note that epoll APIs are only available for Linux platforms. For BSD platforms which do not support epoll APIs, poll APIs are still used. Signed-off-by: Kaifei Peng <2534164734@qq.com>
This commit is contained in:
parent
196b7f1c31
commit
bb5743652d
20
configure.ac
20
configure.ac
|
@ -1599,6 +1599,26 @@ AC_CHECK_FUNCS([pollts], [
|
|||
AC_DEFINE([HAVE_POLLTS], [1], [have NetBSD pollts()])
|
||||
])
|
||||
|
||||
AC_ARG_ENABLE([epoll],
|
||||
[AS_HELP_STRING([--enable-epoll], [Enable epoll support])],
|
||||
[enable_epoll=yes],
|
||||
[enable_epoll=no])
|
||||
|
||||
if test "x$enable_epoll" = "xyes"; then
|
||||
AC_CHECK_FUNC([epoll_wait], [AC_DEFINE([HAVE_EPOLL_WAIT], [1], [Define if you have epoll_wait])])
|
||||
AC_CHECK_FUNC([epoll_pwait], [AC_DEFINE([HAVE_EPOLL_PWAIT], [1], [Define if you have epoll_pwait])])
|
||||
AC_CHECK_FUNC([epoll_pwait2], [AC_DEFINE([HAVE_EPOLL_PWAIT2], [1], [Define if you have epoll_pwait2])])
|
||||
|
||||
# Define USE_EPOLL if any of the above is found
|
||||
AC_MSG_CHECKING([for any epoll API support])
|
||||
if test "x$ac_cv_func_epoll_wait" = "xyes" || test "x$ac_cv_func_epoll_pwait" = "xyes" || test "x$ac_cv_func_epoll_pwait2" = "xyes"; then
|
||||
AC_DEFINE([USE_EPOLL], [1], [Define if any epoll API is supported])
|
||||
AC_MSG_RESULT([yes])
|
||||
else
|
||||
AC_MSG_RESULT([no])
|
||||
fi
|
||||
fi
|
||||
|
||||
AC_CHECK_HEADER([asm-generic/unistd.h],
|
||||
[AC_CHECK_DECL(__NR_setns,
|
||||
AC_DEFINE([HAVE_NETNS], [1], [Have netns]),,
|
||||
|
|
921
lib/event.c
921
lib/event.c
File diff suppressed because it is too large
Load diff
|
@ -6,10 +6,21 @@
|
|||
#ifndef _ZEBRA_THREAD_H
|
||||
#define _ZEBRA_THREAD_H
|
||||
|
||||
#if defined(USE_EPOLL) && \
|
||||
(defined(HAVE_EPOLL_WAIT) || defined(HAVE_EPOLL_PWAIT) || \
|
||||
defined(HAVE_EPOLL_PWAIT2))
|
||||
#define EPOLL_ENABLED 1
|
||||
#else
|
||||
#define EPOLL_ENABLED 0
|
||||
#endif
|
||||
|
||||
#include <signal.h>
|
||||
#include <zebra.h>
|
||||
#include <pthread.h>
|
||||
#include <poll.h>
|
||||
#if EPOLL_ENABLED
|
||||
#include <sys/epoll.h>
|
||||
#endif
|
||||
#include "monotime.h"
|
||||
#include "frratomic.h"
|
||||
#include "typesafe.h"
|
||||
|
@ -43,6 +54,34 @@ struct rusage_t {
|
|||
PREDECL_LIST(event_list);
|
||||
PREDECL_HEAP(event_timer_list);
|
||||
|
||||
#if EPOLL_ENABLED
|
||||
struct fd_handler {
|
||||
/* The epoll set file descriptor */
|
||||
int epoll_fd;
|
||||
|
||||
/* A hash table in which monitored I/O file descrpitors and events
|
||||
* are registered
|
||||
*/
|
||||
struct hash *epoll_event_hash;
|
||||
|
||||
/* Maximum size of .revents and .regular_revents arrays */
|
||||
int eventsize;
|
||||
|
||||
/* The buffer which stores the results of epoll_wait */
|
||||
struct epoll_event *revents;
|
||||
|
||||
/* Vtysh might redirect stdin/stdout to regular files. However,
|
||||
* regular files can't be added into epoll set and need special
|
||||
* treatment. I/O events from/to regular file will be directly
|
||||
* added to regular_revents, but not into epoll set, whereby
|
||||
* sidesteping epoll_wait.
|
||||
*/
|
||||
struct epoll_event *regular_revents;
|
||||
int regular_revent_count;
|
||||
|
||||
unsigned long *fd_poll_counter;
|
||||
};
|
||||
#else
|
||||
struct fd_handler {
|
||||
/* number of pfd that fit in the allocated space of pfds. This is a
|
||||
* constant and is the same for both pfds and copy.
|
||||
|
@ -59,6 +98,7 @@ struct fd_handler {
|
|||
/* number of pollfds stored in copy */
|
||||
nfds_t copycount;
|
||||
};
|
||||
#endif
|
||||
|
||||
struct xref_eventsched {
|
||||
struct xref xref;
|
||||
|
@ -91,7 +131,9 @@ struct event_loop {
|
|||
pthread_mutex_t mtx;
|
||||
pthread_t owner;
|
||||
|
||||
#if !EPOLL_ENABLED
|
||||
nfds_t last_read;
|
||||
#endif
|
||||
|
||||
bool ready_run_loop;
|
||||
RUSAGE_T last_getrusage;
|
||||
|
|
|
@ -59,6 +59,18 @@ struct printfrr_eargs;
|
|||
} while (0)
|
||||
#endif
|
||||
|
||||
#ifndef msec_to_timespec
|
||||
#define msec_to_timespec(ms, ts, tsp) \
|
||||
do { \
|
||||
if ((ms) >= 0) { \
|
||||
(ts).tv_sec = (ms) / 1000; \
|
||||
(ts).tv_nsec = ((ms) % 1000) * 1000000; \
|
||||
(tsp) = &(ts); \
|
||||
} else \
|
||||
(tsp) = NULL; \
|
||||
} while (0)
|
||||
#endif
|
||||
|
||||
static inline time_t monotime(struct timeval *tvo)
|
||||
{
|
||||
struct timespec ts;
|
||||
|
|
Loading…
Reference in a new issue