Use eventfd() on Linux to wake up dupecheck when packets are available
This commit is contained in:
parent
809691aa3d
commit
a454f2332f
|
|
@ -9,6 +9,9 @@
|
|||
/* POSIX capabilities */
|
||||
#undef HAVE_CAPABILITY_H
|
||||
|
||||
/* Linux event fd support */
|
||||
#undef HAVE_EVENTFD_H
|
||||
|
||||
/* Define to 1 if you have the `gai_strerror' function. */
|
||||
#undef HAVE_GAI_STRERROR
|
||||
|
||||
|
|
@ -60,6 +63,9 @@
|
|||
/* Define to 1 if you have the <sys/epoll.h> header file. */
|
||||
#undef HAVE_SYS_EPOLL_H
|
||||
|
||||
/* Define to 1 if you have the <sys/eventfd.h> header file. */
|
||||
#undef HAVE_SYS_EVENTFD_H
|
||||
|
||||
/* Define to 1 if you have the <sys/prctl.h> header file. */
|
||||
#undef HAVE_SYS_PRCTL_H
|
||||
|
||||
|
|
|
|||
|
|
@ -35,6 +35,15 @@
|
|||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_EVENTFD_H
|
||||
#include <sys/eventfd.h>
|
||||
#ifdef EFD_NONBLOCK
|
||||
#ifdef EFD_CLOEXEC
|
||||
#define USE_EVENTFD
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
extern int fork_a_daemon; /* fork a daemon */
|
||||
|
||||
extern int dump_requests; /* print requests */
|
||||
|
|
|
|||
|
|
@ -3536,6 +3536,21 @@ if test "x$ac_cv_lib_cap_cap_init" = x""yes; then :
|
|||
fi
|
||||
|
||||
|
||||
for ac_header in sys/eventfd.h
|
||||
do :
|
||||
ac_fn_c_check_header_mongrel "$LINENO" "sys/eventfd.h" "ac_cv_header_sys_eventfd_h" "$ac_includes_default"
|
||||
if test "x$ac_cv_header_sys_eventfd_h" = x""yes; then :
|
||||
cat >>confdefs.h <<_ACEOF
|
||||
#define HAVE_SYS_EVENTFD_H 1
|
||||
_ACEOF
|
||||
|
||||
$as_echo "#define HAVE_EVENTFD_H /**/" >>confdefs.h
|
||||
|
||||
fi
|
||||
|
||||
done
|
||||
|
||||
|
||||
for ac_header in alloca.h
|
||||
do :
|
||||
ac_fn_c_check_header_mongrel "$LINENO" "alloca.h" "ac_cv_header_alloca_h" "$ac_includes_default"
|
||||
|
|
|
|||
|
|
@ -69,6 +69,9 @@ AC_CHECK_HEADERS([sys/prctl.h], AC_DEFINE([HAVE_PRCTL_H], [], [Linux process con
|
|||
AC_SUBST(LIBCAP)
|
||||
AC_CHECK_LIB(cap,cap_init,[LIBCAP="-lcap"])
|
||||
|
||||
dnl Check for
|
||||
AC_CHECK_HEADERS([sys/eventfd.h], AC_DEFINE([HAVE_EVENTFD_H], [], [Linux event fd support]))
|
||||
|
||||
dnl Checks for system headers
|
||||
AC_CHECK_HEADERS([alloca.h], AC_DEFINE([HAVE_ALLOCA_H]))
|
||||
AC_CHECK_HEADERS([poll.h], AC_DEFINE([HAVE_POLL_H]))
|
||||
|
|
|
|||
|
|
@ -20,6 +20,10 @@
|
|||
#include <stdlib.h>
|
||||
#include <pthread.h>
|
||||
|
||||
#ifdef USE_EVENTFD
|
||||
#include <sys/eventfd.h>
|
||||
#endif
|
||||
|
||||
#include "dupecheck.h"
|
||||
#include "config.h"
|
||||
#include "hlog.h"
|
||||
|
|
@ -59,6 +63,11 @@ cellarena_t *dupecheck_cells;
|
|||
volatile uint32_t dupecheck_seqnum = -2000; // Explicit early wrap-around..
|
||||
volatile uint32_t dupecheck_dupe_seqnum = -2000; // Explicit early wrap-around..
|
||||
|
||||
#ifdef USE_EVENTFD
|
||||
int dupecheck_eventfd = -1;
|
||||
struct pollfd dupecheck_eventfd_poll;
|
||||
#endif
|
||||
|
||||
static int pbuf_seqnum_lag(const uint32_t seqnum, const uint32_t pbuf_seq)
|
||||
{
|
||||
// The lag calculation method takes care of the value space
|
||||
|
|
@ -204,6 +213,18 @@ void dupecheck_init(void)
|
|||
2048 /* 2 MB at the time */,
|
||||
0 /* minfree */);
|
||||
#endif
|
||||
|
||||
#ifdef USE_EVENTFD
|
||||
dupecheck_eventfd = eventfd(0, EFD_NONBLOCK|EFD_CLOEXEC);
|
||||
if (dupecheck_eventfd < 0) {
|
||||
hlog(LOG_ERR, "dupecheck: eventfd init failed: %s", strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
dupecheck_eventfd_poll.fd = dupecheck_eventfd;
|
||||
dupecheck_eventfd_poll.events = POLLIN;
|
||||
hlog(LOG_DEBUG, "dupecheck: eventfd initialized on fd %d", dupecheck_eventfd);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
static struct dupe_record_t *dupecheck_db_alloc(int len)
|
||||
|
|
@ -790,14 +811,25 @@ static void dupecheck_thread(void)
|
|||
// if (n > 0)
|
||||
// hlog(LOG_DEBUG, "Dupecheck did analyze %d packets, found %d duplicates", n, pb_out_dupe_count);
|
||||
/* sleep a little, if there was nothing to do */
|
||||
if (n == 0)
|
||||
if (n == 0) {
|
||||
#ifdef USE_EVENTFD
|
||||
int p = poll(&dupecheck_eventfd_poll, 1, 1000);
|
||||
hlog(LOG_DEBUG, "dupecheck: poll returned %d", p);
|
||||
if (p > 0) {
|
||||
uint64_t u;
|
||||
p = read(dupecheck_eventfd, &u, sizeof(uint64_t));
|
||||
hlog(LOG_DEBUG, "dupecheck: eventfd read %d: %lu", p, u);
|
||||
}
|
||||
#else
|
||||
poll(NULL, 0, 20); // 20 ms
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
hlog( LOG_INFO, "Dupecheck thread shut down; seqnum=%u/%u",
|
||||
pbuf_seqnum_lag(dupecheck_seqnum,(uint32_t)-2000), // initial bias..
|
||||
pbuf_seqnum_lag(dupecheck_dupe_seqnum,(uint32_t)-2000));
|
||||
|
||||
|
||||
dupecheck_running = 0;
|
||||
}
|
||||
|
||||
|
|
@ -827,6 +859,15 @@ void dupecheck_stop(void)
|
|||
|
||||
dupecheck_shutting_down = 1;
|
||||
|
||||
#ifdef USE_EVENTFD
|
||||
/* wake up dupecheck from sleep */
|
||||
uint64_t u = 1;
|
||||
int i = write(dupecheck_eventfd, &u, sizeof(uint64_t));
|
||||
if (i != sizeof(uint64_t)) {
|
||||
hlog(LOG_ERR, "incoming_stop() failed to write to dupecheck_eventfd: %s", strerror(errno));
|
||||
}
|
||||
#endif
|
||||
|
||||
if ((e = pthread_join(dupecheck_th, NULL)))
|
||||
hlog(LOG_ERR, "Could not pthread_join dupecheck_th: %s", strerror(e));
|
||||
else
|
||||
|
|
|
|||
|
|
@ -41,6 +41,8 @@ extern long long dupecheck_dupecount; /* statistics counter */
|
|||
extern long long dupecheck_dupetypes[DTYPE_MAX+1];
|
||||
extern long dupecheck_cellgauge; /* statistics gauge */
|
||||
|
||||
extern int dupecheck_eventfd;
|
||||
|
||||
extern int outgoing_lag_report(struct worker_t *self, int*lag, int*dupelag);
|
||||
|
||||
extern void dupecheck_init(void);
|
||||
|
|
|
|||
|
|
@ -17,6 +17,9 @@
|
|||
#include <string.h>
|
||||
#include <strings.h>
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#ifdef HAVE_ALLOCA_H
|
||||
#include <alloca.h>
|
||||
|
|
@ -35,6 +38,7 @@
|
|||
#include "version.h"
|
||||
#include "cellmalloc.h"
|
||||
#include "messaging.h"
|
||||
#include "dupecheck.h"
|
||||
|
||||
/* When adding labels here, remember to add the description strings in
|
||||
* web/aprsc.js rx_err_strings
|
||||
|
|
@ -394,8 +398,17 @@ void incoming_flush(struct worker_t *self)
|
|||
self->pbuf_incoming_count += self->pbuf_incoming_local_count;
|
||||
pthread_mutex_unlock(&self->pbuf_incoming_mutex);
|
||||
|
||||
// hlog( LOG_DEBUG, "incoming_flush() sent out %d packets, incoming_count %d",
|
||||
// self->pbuf_incoming_local_count, incoming_count );
|
||||
hlog( LOG_DEBUG, "incoming_flush() sent out %d packets",
|
||||
self->pbuf_incoming_local_count );
|
||||
|
||||
#ifdef USE_EVENTFD
|
||||
/* wake up dupecheck from sleep */
|
||||
uint64_t u = 1;
|
||||
int i = write(dupecheck_eventfd, &u, sizeof(uint64_t));
|
||||
if (i != sizeof(uint64_t)) {
|
||||
hlog(LOG_ERR, "incoming_flush() failed to write to dupecheck_eventfd: %s", strerror(errno));
|
||||
}
|
||||
#endif
|
||||
|
||||
/* clean the local lockfree queue */
|
||||
self->pbuf_incoming_local = NULL;
|
||||
|
|
|
|||
Loading…
Reference in New Issue