From 7e048838a78f0ec2f7c4a35fa8da291c912d10b4 Mon Sep 17 00:00:00 2001 From: logwang Date: Fri, 4 Aug 2017 17:40:50 +0800 Subject: [PATCH] Add API: ff_gettimeofday. Since f-stack run with polling mode, nginx will call gettimeofday every loop, and cost a lot. With this commit, f-stack will update current timespec periodically in ff_hardclock_job. And ff_gettimeofday will get this value. In nginx, hijack gettimeofday to call ff_gettimeofday. --- .../src/event/modules/ngx_ff_module.c | 7 ++++ lib/ff_api.h | 3 ++ lib/ff_api.symlist | 2 +- lib/ff_dpdk_if.c | 17 ++++++---- lib/ff_host_interface.c | 32 +++++++------------ lib/ff_host_interface.h | 4 ++- lib/ff_syscall_wrapper.c | 9 ++++++ 7 files changed, 46 insertions(+), 28 deletions(-) diff --git a/app/nginx-1.11.10/src/event/modules/ngx_ff_module.c b/app/nginx-1.11.10/src/event/modules/ngx_ff_module.c index 54a69de14..0dcf12a3b 100644 --- a/app/nginx-1.11.10/src/event/modules/ngx_ff_module.c +++ b/app/nginx-1.11.10/src/event/modules/ngx_ff_module.c @@ -332,3 +332,10 @@ kevent(int kq, const struct kevent *changelist, int nchanges, { return ff_kevent(kq, changelist, nchanges, eventlist, nevents, timeout); } + +int +gettimeofday(struct timeval *tv, struct timezone *tz) +{ + return ff_gettimeofday(tv, tz); +} + diff --git a/lib/ff_api.h b/lib/ff_api.h index 00ab9c20a..5ca680b8f 100644 --- a/lib/ff_api.h +++ b/lib/ff_api.h @@ -34,6 +34,7 @@ extern "C" { #include #include #include +#include #include "ff_event.h" #include "ff_errno.h" @@ -106,6 +107,8 @@ int ff_kevent_do_each(int kq, const struct kevent *changelist, int nchanges, void *eventlist, int nevents, const struct timespec *timeout, void (*do_each)(void **, struct kevent *)); +int ff_gettimeofday(struct timeval *tv, struct timezone *tz); + /* route api begin */ enum FF_ROUTE_CTL { FF_ROUTE_ADD, diff --git a/lib/ff_api.symlist b/lib/ff_api.symlist index 2d6258c31..88199d408 100644 --- a/lib/ff_api.symlist +++ b/lib/ff_api.symlist @@ -40,4 +40,4 @@ ff_mbuf_copydata ff_mbuf_tx_offload ff_route_ctl ff_rtioctl - +ff_gettimeofday diff --git a/lib/ff_dpdk_if.c b/lib/ff_dpdk_if.c index aacee8954..cedc58ba0 100644 --- a/lib/ff_dpdk_if.c +++ b/lib/ff_dpdk_if.c @@ -182,9 +182,10 @@ static struct ff_dpdk_if_context *veth_ctx[RTE_MAX_ETHPORTS]; extern void ff_hardclock(void); static void -freebsd_hardclock_job(__rte_unused struct rte_timer *timer, +ff_hardclock_job(__rte_unused struct rte_timer *timer, __rte_unused void *arg) { ff_hardclock(); + ff_update_current_ts(); } struct ff_dpdk_if_context * @@ -773,11 +774,15 @@ init_port_start(void) } } + if (rte_eal_process_type() == RTE_PROC_PRIMARY) { + check_all_ports_link_status(); + } + return 0; } static int -init_freebsd_clock(void) +init_clock(void) { rte_timer_subsystem_init(); uint64_t hz = rte_get_timer_hz(); @@ -786,7 +791,9 @@ init_freebsd_clock(void) rte_timer_init(&freebsd_clock); rte_timer_reset(&freebsd_clock, tsc, PERIODICAL, - rte_lcore_id(), &freebsd_hardclock_job, NULL); + rte_lcore_id(), &ff_hardclock_job, NULL); + + ff_update_current_ts(); return 0; } @@ -827,9 +834,7 @@ ff_dpdk_init(int argc, char **argv) rte_exit(EXIT_FAILURE, "init_port_start failed\n"); } - check_all_ports_link_status(); - - init_freebsd_clock(); + init_clock(); return 0; } diff --git a/lib/ff_host_interface.c b/lib/ff_host_interface.c index 222a43c16..681ad1a98 100644 --- a/lib/ff_host_interface.c +++ b/lib/ff_host_interface.c @@ -45,6 +45,8 @@ #include "ff_host_interface.h" #include "ff_errno.h" +static struct timespec current_ts; + void * ff_mmap(void *addr, uint64_t len, int prot, int flags, int fd, uint64_t offset) { @@ -171,28 +173,18 @@ ff_clock_gettime_ns(int id) return ((uint64_t)sec * ff_NSEC_PER_SEC + nsec); } -/* - * Sleeps for at least the given number of nanoseconds and returns 0, - * unless there is a non-EINTR failure, in which case a non-zero value is - * returned. - */ -int -ff_nanosleep(uint64_t nsecs) +void +ff_get_current_time(time_t *sec, long *nsec) { - struct timespec ts; - struct timespec rts; - int rv; + *sec = current_ts.tv_sec; + *nsec = current_ts.tv_nsec; +} - ts.tv_sec = nsecs / ff_NSEC_PER_SEC; - ts.tv_nsec = nsecs % ff_NSEC_PER_SEC; - while ((-1 == (rv = nanosleep(&ts, &rts))) && (EINTR == errno)) { - ts = rts; - } - if (-1 == rv) { - rv = errno; - } - - return (rv); +void +ff_update_current_ts() +{ + int rv = clock_gettime(CLOCK_MONOTONIC, ¤t_ts); + assert(rv == 0); } void diff --git a/lib/ff_host_interface.h b/lib/ff_host_interface.h index ce8bc704a..9b1656d9c 100644 --- a/lib/ff_host_interface.h +++ b/lib/ff_host_interface.h @@ -56,7 +56,9 @@ void ff_free(void *p); void ff_clock_gettime(int id, int64_t *sec, long *nsec); uint64_t ff_clock_gettime_ns(int id); -int ff_nanosleep(uint64_t nsecs); + +void ff_get_current_time(int64_t *sec, long *nsec); +void ff_update_current_ts(void); typedef void * ff_mutex_t; typedef void * ff_cond_t; diff --git a/lib/ff_syscall_wrapper.c b/lib/ff_syscall_wrapper.c index cbee8402e..ffa2cec7b 100644 --- a/lib/ff_syscall_wrapper.c +++ b/lib/ff_syscall_wrapper.c @@ -1025,6 +1025,15 @@ ff_kevent(int kq, const struct kevent *changelist, int nchanges, return ff_kevent_do_each(kq, changelist, nchanges, eventlist, nevents, timeout, NULL); } +int +ff_gettimeofday(struct timeval *tv, struct timezone *tz) +{ + long nsec; + ff_get_current_time(&(tv->tv_sec), &nsec); + tv->tv_usec = nsec/1000; + return 0; +} + int ff_route_ctl(enum FF_ROUTE_CTL req, enum FF_ROUTE_FLAG flag, struct linux_sockaddr *dst, struct linux_sockaddr *gw,