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.
dev
logwang 2017-08-04 17:40:50 +08:00
parent 3cbf1fd344
commit 7e048838a7
7 changed files with 46 additions and 28 deletions

View File

@ -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);
}

View File

@ -34,6 +34,7 @@ extern "C" {
#include <sys/select.h>
#include <sys/poll.h>
#include <netinet/in.h>
#include <sys/time.h>
#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,

View File

@ -40,4 +40,4 @@ ff_mbuf_copydata
ff_mbuf_tx_offload
ff_route_ctl
ff_rtioctl
ff_gettimeofday

View File

@ -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;
}

View File

@ -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, &current_ts);
assert(rv == 0);
}
void

View File

@ -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;

View File

@ -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,