use int64_t instead of struct timespec everywhere

This should be more efficient and is also easier to read.
pull/196/head
David Schweikert 4 years ago
parent 5473c7d734
commit eb87a2affd

@ -211,7 +211,7 @@ typedef struct host_entry {
struct sockaddr_storage saddr; /* internet address */ struct sockaddr_storage saddr; /* internet address */
socklen_t saddr_len; socklen_t saddr_len;
int timeout; /* time to wait for response */ int timeout; /* time to wait for response */
struct timespec last_send_time; /* time of last packet sent */ int64_t last_send_time; /* time of last packet sent */
int num_sent; /* number of ping packets sent (for statistics) */ int num_sent; /* number of ping packets sent (for statistics) */
int num_recv; /* number of pings received (duplicates ignored) */ int num_recv; /* number of pings received (duplicates ignored) */
int num_recv_total; /* number of pings received, including duplicates */ int num_recv_total; /* number of pings received, including duplicates */
@ -231,9 +231,6 @@ typedef struct host_entry {
* this host. */ * this host. */
struct event *event_storage_ping; struct event *event_storage_ping;
struct event *event_storage_timeout; struct event *event_storage_timeout;
#if defined(DEBUG) || defined(_DEBUG)
int64_t* sent_times; /* per-sent-ping timestamp */
#endif /* DEBUG || _DEBUG */
} HOST_ENTRY; } HOST_ENTRY;
int event_storage_count; /* how many events can be stored in host_entry->event_storage_xxx */ int event_storage_count; /* how many events can be stored in host_entry->event_storage_xxx */
@ -259,7 +256,7 @@ int event_storage_count; /* how many events can be stored in host_entry->event_s
struct event { struct event {
struct event *ev_prev; struct event *ev_prev;
struct event *ev_next; struct event *ev_next;
struct timespec ev_time; int64_t ev_time;
struct host_entry *host; struct host_entry *host;
int ping_index; int ping_index;
}; };
@ -335,10 +332,11 @@ int num_timeout = 0, /* number of times select timed out */
num_othericmprcvd = 0; /* total non-echo-reply ICMP received */ num_othericmprcvd = 0; /* total non-echo-reply ICMP received */
struct timespec current_time; /* current time (pseudo) */ struct timespec current_time; /* current time (pseudo) */
struct timespec start_time; int64_t current_time_ns;
struct timespec end_time; int64_t start_time;
struct timespec last_send_time; /* time last ping was sent */ int64_t end_time;
struct timespec next_report_time; /* time next -Q report is expected */ int64_t last_send_time; /* time last ping was sent */
int64_t next_report_time; /* time next -Q report is expected */
/* switches */ /* switches */
int generate_flag = 0; /* flag for IP list generation */ int generate_flag = 0; /* flag for IP list generation */
@ -350,7 +348,7 @@ int outage_flag = 0;
int timestamp_flag = 0; int timestamp_flag = 0;
int random_data_flag = 0; int random_data_flag = 0;
#if defined(DEBUG) || defined(_DEBUG) #if defined(DEBUG) || defined(_DEBUG)
int randomly_lose_flag, sent_times_flag, trace_flag, print_per_system_flag; int randomly_lose_flag, trace_flag, print_per_system_flag;
int lose_factor; int lose_factor;
#endif /* DEBUG || _DEBUG */ #endif /* DEBUG || _DEBUG */
@ -365,10 +363,6 @@ void crash_and_burn(char* message);
void errno_crash_and_burn(char* message); void errno_crash_and_burn(char* message);
char* get_host_by_address(struct in_addr in); char* get_host_by_address(struct in_addr in);
int send_ping(HOST_ENTRY* h, int index); int send_ping(HOST_ENTRY* h, int index);
void timespec_from_ns(struct timespec* a, uint64_t ns);
int64_t timespec_ns(struct timespec* a);
int64_t timespec_diff(struct timespec* a, struct timespec* b);
void timespec_add(struct timespec* a, int64_t ns);
void usage(int); void usage(int);
int wait_for_reply(long); int wait_for_reply(long);
void print_per_system_stats(void); void print_per_system_stats(void);
@ -386,10 +380,11 @@ void add_cidr(char*);
void add_range(char*, char*); void add_range(char*, char*);
void print_warning(char* fmt, ...); void print_warning(char* fmt, ...);
int addr_cmp(struct sockaddr* a, struct sockaddr* b); int addr_cmp(struct sockaddr* a, struct sockaddr* b);
void host_add_ping_event(HOST_ENTRY *h, int index, struct timespec *ts); void host_add_ping_event(HOST_ENTRY *h, int index, int64_t ev_time);
void host_add_timeout_event(HOST_ENTRY *h, int index, struct timespec *ts); void host_add_timeout_event(HOST_ENTRY *h, int index, int64_t ev_time);
struct event *host_get_timeout_event(HOST_ENTRY *h, int index); struct event *host_get_timeout_event(HOST_ENTRY *h, int index);
void stats_add(HOST_ENTRY *h, int index, int success, int64_t latency); void stats_add(HOST_ENTRY *h, int index, int success, int64_t latency);
void update_current_time();
/************************************************************ /************************************************************
@ -873,9 +868,6 @@ int main(int argc, char** argv)
if (debugging & DBG_TRACE) if (debugging & DBG_TRACE)
trace_flag = 1; trace_flag = 1;
if ((debugging & DBG_SENT_TIMES) && !loop_flag)
sent_times_flag = 1;
if (debugging & DBG_RANDOM_LOSE_FEW) { if (debugging & DBG_RANDOM_LOSE_FEW) {
randomly_lose_flag = 1; randomly_lose_flag = 1;
lose_factor = 1; /* ie, 1/4 */ lose_factor = 1; /* ie, 1/4 */
@ -930,8 +922,6 @@ int main(int argc, char** argv)
fprintf(stderr, " report_all_rtts_flag set\n"); fprintf(stderr, " report_all_rtts_flag set\n");
if (randomly_lose_flag) if (randomly_lose_flag)
fprintf(stderr, " randomly_lose_flag set\n"); fprintf(stderr, " randomly_lose_flag set\n");
if (sent_times_flag)
fprintf(stderr, " sent_times_flag set\n");
if (print_per_system_flag) if (print_per_system_flag)
fprintf(stderr, " print_per_system_flag set\n"); fprintf(stderr, " print_per_system_flag set\n");
if (outage_flag) if (outage_flag)
@ -975,8 +965,8 @@ int main(int argc, char** argv)
} }
#endif #endif
clock_gettime(CLOCKID, &start_time); update_current_time();
current_time = start_time; start_time = current_time_ns;
/* handle host names supplied on command line or in a file */ /* handle host names supplied on command line or in a file */
/* if the generate_flag is on, then generate the IP list */ /* if the generate_flag is on, then generate the IP list */
@ -1108,16 +1098,10 @@ int main(int argc, char** argv)
setlinebuf(stdout); setlinebuf(stdout);
if (report_interval) { if (report_interval) {
next_report_time = start_time; next_report_time = current_time_ns + (int64_t)report_interval*10000;
timespec_add(&next_report_time, (int64_t)report_interval*10000);
} }
last_send_time.tv_sec = current_time.tv_sec - 10000; last_send_time = 0;
#if defined(DEBUG) || defined(_DEBUG)
if (randomly_lose_flag)
srandom(start_time.tv_nsec);
#endif /* DEBUG || _DEBUG */
seqmap_init(); seqmap_init();
@ -1129,6 +1113,11 @@ int main(int argc, char** argv)
return 0; return 0;
} }
static inline int64_t timespec_ns(struct timespec* a)
{
return ((int64_t) a->tv_sec * 1000000000) + a->tv_nsec;
}
void add_cidr(char* addr) void add_cidr(char* addr)
{ {
char* addr_end; char* addr_end;
@ -1264,7 +1253,7 @@ void main_loop()
/* timeout event ? */ /* timeout event ? */
if (event_queue_timeout.first && if (event_queue_timeout.first &&
timespec_diff(&event_queue_timeout.first->ev_time, &current_time) <= 0) event_queue_timeout.first->ev_time - current_time_ns <= 0)
{ {
event = ev_dequeue(&event_queue_timeout); event = ev_dequeue(&event_queue_timeout);
h = event->host; h = event->host;
@ -1292,10 +1281,10 @@ void main_loop()
/* ping event ? */ /* ping event ? */
if (event_queue_ping.first && if (event_queue_ping.first &&
timespec_diff(&event_queue_ping.first->ev_time, &current_time) <= 0) event_queue_ping.first->ev_time - current_time_ns <= 0)
{ {
/* Make sure that we don't ping more than once every "interval" */ /* Make sure that we don't ping more than once every "interval" */
lt = timespec_diff(&current_time, &last_send_time); lt = current_time_ns - last_send_time;
if (lt < interval*10000) if (lt < interval*10000)
goto wait_for_reply; goto wait_for_reply;
@ -1310,10 +1299,7 @@ void main_loop()
/* Loop and count mode: schedule next ping */ /* Loop and count mode: schedule next ping */
if (loop_flag || (count_flag && event->ping_index+1 < count)) { if (loop_flag || (count_flag && event->ping_index+1 < count)) {
struct timespec next_ping_time; host_add_ping_event(h, event->ping_index+1, event->ev_time + (int64_t)perhost_interval*10000);
next_ping_time = event->ev_time;
timespec_add(&next_ping_time, (int64_t)perhost_interval*10000);
host_add_ping_event(h, event->ping_index+1, &next_ping_time);
} }
} }
@ -1322,13 +1308,13 @@ void main_loop()
/* When is the next ping next event? */ /* When is the next ping next event? */
wait_time_ns = -1; wait_time_ns = -1;
if (event_queue_ping.first) { if (event_queue_ping.first) {
wait_time_ns = timespec_diff(&event_queue_ping.first->ev_time, &current_time); wait_time_ns = event_queue_ping.first->ev_time - current_time_ns;
if (wait_time_ns < 0) if (wait_time_ns < 0)
wait_time_ns = 0; wait_time_ns = 0;
/* make sure that we wait enough, so that the inter-ping delay is /* make sure that we wait enough, so that the inter-ping delay is
* bigger than 'interval' */ * bigger than 'interval' */
if (wait_time_ns < interval*10000) { if (wait_time_ns < interval*10000) {
lt = timespec_diff(&current_time, &last_send_time); lt = current_time_ns - last_send_time;
if (lt < interval*10000) { if (lt < interval*10000) {
wait_time_ns = interval*10000 - lt; wait_time_ns = interval*10000 - lt;
} }
@ -1339,7 +1325,7 @@ void main_loop()
/* When is the next timeout event? */ /* When is the next timeout event? */
if (event_queue_timeout.first) { if (event_queue_timeout.first) {
long wait_time_timeout = timespec_diff(&event_queue_timeout.first->ev_time, &current_time); int64_t wait_time_timeout = event_queue_timeout.first->ev_time - current_time_ns;
if(wait_time_ns < 0 || wait_time_timeout < wait_time_ns) { if(wait_time_ns < 0 || wait_time_timeout < wait_time_ns) {
wait_time_ns = wait_time_timeout; wait_time_ns = wait_time_timeout;
if (wait_time_ns < 0) { if (wait_time_ns < 0) {
@ -1352,7 +1338,7 @@ void main_loop()
/* When is the next report due? */ /* When is the next report due? */
if (report_interval && (loop_flag || count_flag)) { if (report_interval && (loop_flag || count_flag)) {
long wait_time_next_report = timespec_diff(&next_report_time, &current_time); int64_t wait_time_next_report = next_report_time - current_time_ns;
if (wait_time_next_report < wait_time_ns) { if (wait_time_next_report < wait_time_ns) {
wait_time_ns = wait_time_next_report; wait_time_ns = wait_time_next_report;
if (wait_time_ns < 0) { if (wait_time_ns < 0) {
@ -1381,7 +1367,7 @@ void main_loop()
; /* process other replies in the queue */ ; /* process other replies in the queue */
} }
clock_gettime(CLOCKID, &current_time); update_current_time();
if (status_snapshot) { if (status_snapshot) {
status_snapshot = 0; status_snapshot = 0;
@ -1389,14 +1375,15 @@ void main_loop()
} }
/* Print report */ /* Print report */
if (report_interval && (loop_flag || count_flag) && (timespec_diff(&current_time, &next_report_time) >= 0)) { if (report_interval && (loop_flag || count_flag) && (current_time_ns >= next_report_time)) {
if (netdata_flag) if (netdata_flag)
print_netdata(); print_netdata();
else else
print_per_system_splits(); print_per_system_splits();
while (timespec_diff(&current_time, &next_report_time) >= 0) while (current_time_ns >= next_report_time) {
timespec_add(&next_report_time, (int64_t)report_interval*10000); next_report_time += (int64_t)report_interval*10000;
}
} }
} }
} }
@ -1429,6 +1416,18 @@ void signal_handler(int signum)
} }
} }
/************************************************************
Function: update_current_time
*************************************************************/
void update_current_time()
{
clock_gettime(CLOCKID, &current_time);
current_time_ns = timespec_ns(&current_time);
}
/************************************************************ /************************************************************
@ -1449,7 +1448,8 @@ void finish()
int i; int i;
HOST_ENTRY* h; HOST_ENTRY* h;
clock_gettime(CLOCKID, &end_time); update_current_time();
end_time = current_time_ns;
/* tot up unreachables */ /* tot up unreachables */
for (i = 0; i < num_hosts; i++) { for (i = 0; i < num_hosts; i++) {
@ -1559,19 +1559,6 @@ void print_per_system_stats(void)
fprintf(stderr, "\n"); fprintf(stderr, "\n");
} }
#if defined(DEBUG) || defined(_DEBUG)
if (sent_times_flag) {
for (j = 0; j < h->num_sent; j++) {
if ((resp = h->sent_times[j]) >= 0)
fprintf(stderr, " %s", sprint_tm(resp));
else
fprintf(stderr, " -");
fprintf(stderr, "\n");
}
}
#endif
} }
} }
@ -1670,7 +1657,7 @@ void print_per_system_splits(void)
if (verbose_flag || per_recv_flag) if (verbose_flag || per_recv_flag)
fprintf(stderr, "\n"); fprintf(stderr, "\n");
clock_gettime(CLOCKID, &current_time); update_current_time();
curr_tm = localtime((time_t*)&current_time.tv_sec); curr_tm = localtime((time_t*)&current_time.tv_sec);
fprintf(stderr, "[%2.2d:%2.2d:%2.2d]\n", curr_tm->tm_hour, fprintf(stderr, "[%2.2d:%2.2d:%2.2d]\n", curr_tm->tm_hour,
curr_tm->tm_min, curr_tm->tm_sec); curr_tm->tm_min, curr_tm->tm_sec);
@ -1745,7 +1732,7 @@ void print_global_stats(void)
sprint_tm((int)(sum_replies / total_replies))); sprint_tm((int)(sum_replies / total_replies)));
fprintf(stderr, " %s ms (max round trip time)\n", sprint_tm(max_reply)); fprintf(stderr, " %s ms (max round trip time)\n", sprint_tm(max_reply));
fprintf(stderr, " %12.3f sec (elapsed real time)\n", fprintf(stderr, " %12.3f sec (elapsed real time)\n",
timespec_diff(&end_time, &start_time) / 1e9); (end_time - start_time) / 1e9);
fprintf(stderr, "\n"); fprintf(stderr, "\n");
} }
@ -1773,8 +1760,9 @@ int send_ping(HOST_ENTRY* h, int index)
int myseq; int myseq;
int ret = 1; int ret = 1;
clock_gettime(CLOCKID, &h->last_send_time); update_current_time();
myseq = seqmap_add(h->i, index, &h->last_send_time); h->last_send_time = current_time_ns;
myseq = seqmap_add(h->i, index, current_time_ns);
dbg_printf("%s [%d]: send ping\n", h->host, index); dbg_printf("%s [%d]: send ping\n", h->host, index);
@ -1813,19 +1801,12 @@ int send_ping(HOST_ENTRY* h, int index)
} }
else { else {
/* schedule timeout */ /* schedule timeout */
struct timespec timeout_time = current_time; host_add_timeout_event(h, index, current_time_ns + (int64_t)h->timeout*10000);
timespec_add(&timeout_time, (int64_t)(h->timeout)*10000);
host_add_timeout_event(h, index, &timeout_time);
/* mark this trial as outstanding */ /* mark this trial as outstanding */
if (!loop_flag) { if (!loop_flag) {
h->resp_times[index] = RESP_WAITING; h->resp_times[index] = RESP_WAITING;
} }
#if defined(DEBUG) || defined(_DEBUG)
if (sent_times_flag)
h->sent_times[index] = timespec_diff(&h->last_send_time, &start_time);
#endif
} }
num_pingsent++; num_pingsent++;
@ -1879,7 +1860,7 @@ select_again:
} }
int receive_packet(int64_t wait_time, int receive_packet(int64_t wait_time,
struct timespec* reply_timestamp, int64_t* reply_timestamp,
struct sockaddr* reply_src_addr, struct sockaddr* reply_src_addr,
size_t reply_src_addr_len, size_t reply_src_addr_len,
char* reply_buf, char* reply_buf,
@ -1902,7 +1883,6 @@ int receive_packet(int64_t wait_time,
sizeof(msg_control), sizeof(msg_control),
0 0
}; };
int timestamp_set = 0;
#if HAVE_SO_TIMESTAMPNS #if HAVE_SO_TIMESTAMPNS
struct cmsghdr* cmsg; struct cmsghdr* cmsg;
#endif #endif
@ -1911,18 +1891,15 @@ int receive_packet(int64_t wait_time,
if (wait_time) { if (wait_time) {
to.tv_sec = wait_time / UINT64_C(1000000000); to.tv_sec = wait_time / UINT64_C(1000000000);
to.tv_usec = (wait_time % UINT64_C(1000000000)) / 1000 + 1; to.tv_usec = (wait_time % UINT64_C(1000000000)) / 1000 + 1;
} }
else { else {
to.tv_sec = 0; to.tv_sec = 0;
to.tv_usec = 0; to.tv_usec = 0;
} }
dbg_printf("wait time: %ld\n", wait_time);
s = socket_can_read(&to); s = socket_can_read(&to);
if (s == -1) { if (s == -1) {
return 0; /* timeout */ return 0; /* timeout */
} }
dbg_printf("socket ready: %d\n", s);
recv_len = recvmsg(s, &recv_msghdr, 0); recv_len = recvmsg(s, &recv_msghdr, 0);
if (recv_len <= 0) { if (recv_len <= 0) {
@ -1931,20 +1908,19 @@ int receive_packet(int64_t wait_time,
#if HAVE_SO_TIMESTAMPNS #if HAVE_SO_TIMESTAMPNS
/* ancilliary data */ /* ancilliary data */
for (cmsg = CMSG_FIRSTHDR(&recv_msghdr); {
cmsg != NULL; struct timespec reply_timestamp_ts;
cmsg = CMSG_NXTHDR(&recv_msghdr, cmsg)) { for (cmsg = CMSG_FIRSTHDR(&recv_msghdr);
if (cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SCM_TIMESTAMPNS) { cmsg != NULL;
memcpy(reply_timestamp, CMSG_DATA(cmsg), sizeof(*reply_timestamp)); cmsg = CMSG_NXTHDR(&recv_msghdr, cmsg)) {
timestamp_set = 1; if (cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SCM_TIMESTAMPNS) {
memcpy(&reply_timestamp_ts, CMSG_DATA(cmsg), sizeof(reply_timestamp_ts));
*reply_timestamp = timespec_ns(&reply_timestamp_ts);
}
} }
} }
#endif #endif
if (!timestamp_set) {
clock_gettime(CLOCKID, reply_timestamp);
}
#if defined(DEBUG) || defined(_DEBUG) #if defined(DEBUG) || defined(_DEBUG)
if (randomly_lose_flag) { if (randomly_lose_flag) {
if ((random() & 0x07) <= lose_factor) if ((random() & 0x07) <= lose_factor)
@ -2076,7 +2052,7 @@ int decode_icmp_ipv4(
return 0; return 0;
} }
seqmap_value = seqmap_fetch(ntohs(sent_icmp->icmp_seq), &current_time); seqmap_value = seqmap_fetch(ntohs(sent_icmp->icmp_seq), current_time_ns);
if (seqmap_value == NULL) { if (seqmap_value == NULL) {
return 0; return 0;
} }
@ -2168,7 +2144,7 @@ int decode_icmp_ipv6(
return 0; return 0;
} }
seqmap_value = seqmap_fetch(ntohs(sent_icmp->icmp6_seq), &current_time); seqmap_value = seqmap_fetch(ntohs(sent_icmp->icmp6_seq), current_time_ns);
if (seqmap_value == NULL) { if (seqmap_value == NULL) {
return 0; return 0;
} }
@ -2228,8 +2204,7 @@ int wait_for_reply(int64_t wait_time)
HOST_ENTRY* h; HOST_ENTRY* h;
long this_reply; long this_reply;
int this_count; int this_count;
struct timespec* sent_time; int64_t recv_time=0;
struct timespec recv_time = {0};
SEQMAP_VALUE* seqmap_value; SEQMAP_VALUE* seqmap_value;
unsigned short id; unsigned short id;
unsigned short seq; unsigned short seq;
@ -2247,7 +2222,8 @@ int wait_for_reply(int64_t wait_time)
return 0; return 0;
} }
clock_gettime(CLOCKID, &current_time); update_current_time();
if(recv_time==0) recv_time = current_time_ns;
/* Process ICMP packet and retrieve id/seq */ /* Process ICMP packet and retrieve id/seq */
if (response_addr.ss_family == AF_INET) { if (response_addr.ss_family == AF_INET) {
@ -2288,7 +2264,7 @@ int wait_for_reply(int64_t wait_time)
return 1; return 1;
} }
seqmap_value = seqmap_fetch(seq, &current_time); seqmap_value = seqmap_fetch(seq, current_time_ns);
if (seqmap_value == NULL) { if (seqmap_value == NULL) {
return 1; return 1;
} }
@ -2296,9 +2272,8 @@ int wait_for_reply(int64_t wait_time)
/* find corresponding host_entry */ /* find corresponding host_entry */
n = seqmap_value->host_nr; n = seqmap_value->host_nr;
h = table[n]; h = table[n];
sent_time = &seqmap_value->ping_ts;
this_count = seqmap_value->ping_count; this_count = seqmap_value->ping_count;
this_reply = timespec_diff(&recv_time, sent_time); this_reply = recv_time - seqmap_value->ping_ts;
/* update stats that include invalid replies */ /* update stats that include invalid replies */
h->num_recv_total++; h->num_recv_total++;
@ -2372,9 +2347,7 @@ int wait_for_reply(int64_t wait_time)
/* print received ping (unless --quiet) */ /* print received ping (unless --quiet) */
if (per_recv_flag) { if (per_recv_flag) {
if (timestamp_flag) { if (timestamp_flag) {
printf("[%lu.%09lu] ", printf("[%10.5f] ", (double)(recv_time / 1000000)/1000);
(unsigned long)recv_time.tv_sec,
(unsigned long)recv_time.tv_nsec);
} }
avg = h->total_time / h->num_recv; avg = h->total_time / h->num_recv;
printf("%-*s : [%d], %d bytes, %s ms", printf("%-*s : [%d], %d bytes, %s ms",
@ -2531,7 +2504,6 @@ void add_addr(char* name, char* host, struct sockaddr* ipaddr, socklen_t ipaddr_
HOST_ENTRY* p; HOST_ENTRY* p;
int n; int n;
int64_t *i; int64_t *i;
struct timespec ts;
p = (HOST_ENTRY*)calloc(1, sizeof(HOST_ENTRY)); p = (HOST_ENTRY*)calloc(1, sizeof(HOST_ENTRY));
if (!p) if (!p)
@ -2568,27 +2540,12 @@ void add_addr(char* name, char* host, struct sockaddr* ipaddr, socklen_t ipaddr_
p->resp_times = i; p->resp_times = i;
} }
#if defined(DEBUG) || defined(_DEBUG)
/* likewise for sent times */
if (sent_times_flag) {
i = (int64_t*)malloc(trials * sizeof(int64_t));
if (!i)
crash_and_burn("can't allocate sent_times array");
for (n = 1; n < trials; n++)
i[n] = RESP_UNUSED;
p->sent_times = i;
}
#endif /* DEBUG || _DEBUG */
/* allocate event storage */ /* allocate event storage */
p->event_storage_ping = (struct event *) calloc(event_storage_count, sizeof(struct event)); p->event_storage_ping = (struct event *) calloc(event_storage_count, sizeof(struct event));
p->event_storage_timeout = (struct event *) calloc(event_storage_count, sizeof(struct event)); p->event_storage_timeout = (struct event *) calloc(event_storage_count, sizeof(struct event));
/* schedule first ping */ /* schedule first ping */
ts = current_time; host_add_ping_event(p, 0, current_time_ns);
host_add_ping_event(p, 0, &ts);
num_hosts++; num_hosts++;
} }
@ -2649,48 +2606,6 @@ void print_warning(char* format, ...)
} }
} }
/************************************************************
Function: timespec_diff
*************************************************************
Inputs: struct timespec *a, struct timespec *b
Returns: int64_t
Description:
timespec_diff now returns result in nanoseconds
************************************************************/
int64_t timespec_ns(struct timespec* a)
{
return ((int64_t) a->tv_sec * UINT64_C(1000000000)) + a->tv_nsec;
}
void timespec_from_ns(struct timespec* a, uint64_t ns)
{
a->tv_sec = ns / UINT64_C(1000000000);
a->tv_nsec = ns % UINT64_C(1000000000);
}
int64_t timespec_diff(struct timespec* a, struct timespec* b)
{
return timespec_ns(a) - timespec_ns(b);
}
/************************************************************
Function: timespec_add
*************************************************************/
void timespec_add(struct timespec* a, int64_t ns)
{
a->tv_sec += (ns + a->tv_nsec) / UINT64_C(1000000000);
a->tv_nsec = (ns + a->tv_nsec) % UINT64_C(1000000000);
}
/************************************************************ /************************************************************
Function: sprint_tm Function: sprint_tm
@ -2764,28 +2679,28 @@ int addr_cmp(struct sockaddr* a, struct sockaddr* b)
return 0; return 0;
} }
void host_add_ping_event(HOST_ENTRY *h, int index, struct timespec *ts) void host_add_ping_event(HOST_ENTRY *h, int index, int64_t ev_time)
{ {
struct event *event = &h->event_storage_ping[index % event_storage_count]; struct event *event = &h->event_storage_ping[index % event_storage_count];
event->host = h; event->host = h;
event->ping_index = index; event->ping_index = index;
event->ev_time = *ts; event->ev_time = ev_time;
ev_enqueue(&event_queue_ping, event); ev_enqueue(&event_queue_ping, event);
dbg_printf("%s [%d]: add ping event in %ld ms\n", dbg_printf("%s [%d]: add ping event in %ld ms\n",
event->host->host, index, timespec_diff(&event->ev_time, &current_time) / 1000000); event->host->host, index, (ev_time - current_time_ns) / 1000000);
} }
void host_add_timeout_event(HOST_ENTRY *h, int index, struct timespec *ts) void host_add_timeout_event(HOST_ENTRY *h, int index, int64_t ev_time)
{ {
struct event *event = &h->event_storage_timeout[index % event_storage_count]; struct event *event = &h->event_storage_timeout[index % event_storage_count];
event->host = h; event->host = h;
event->ping_index = index; event->ping_index = index;
event->ev_time = *ts; event->ev_time = ev_time;
ev_enqueue(&event_queue_timeout, event); ev_enqueue(&event_queue_timeout, event);
dbg_printf("%s [%d]: add timeout event in %ld ms\n", dbg_printf("%s [%d]: add timeout event in %ld ms\n",
event->host->host, index, timespec_diff(&event->ev_time, &current_time) / 1000000); event->host->host, index, (ev_time - current_time_ns) / 1000000);
} }
struct event *host_get_timeout_event(HOST_ENTRY *h, int index) struct event *host_get_timeout_event(HOST_ENTRY *h, int index)
@ -2823,7 +2738,7 @@ void ev_enqueue(struct event_queue *queue, struct event* event)
} }
/* Insert on tail? */ /* Insert on tail? */
if (timespec_diff(&event->ev_time, &queue->last->ev_time) >= 0) { if (event->ev_time - queue->last->ev_time >= 0) {
event->ev_next = NULL; event->ev_next = NULL;
event->ev_prev = queue->last; event->ev_prev = queue->last;
queue->last->ev_next = event; queue->last->ev_next = event;
@ -2835,7 +2750,7 @@ void ev_enqueue(struct event_queue *queue, struct event* event)
i = queue->last; i = queue->last;
while (1) { while (1) {
i_prev = i->ev_prev; i_prev = i->ev_prev;
if (i_prev == NULL || timespec_diff(&event->ev_time, &i_prev->ev_time) >= 0) { if (i_prev == NULL || event->ev_time - i_prev->ev_time >= 0) {
event->ev_prev = i_prev; event->ev_prev = i_prev;
event->ev_next = i; event->ev_next = i;
i->ev_prev = event; i->ev_prev = event;

@ -9,8 +9,10 @@
/* this requires variadic macros, part of C99 */ /* this requires variadic macros, part of C99 */
#if (defined(DEBUG) || defined(_DEBUG)) #if (defined(DEBUG) || defined(_DEBUG))
extern int64_t current_time_ns;
extern int trace_flag; extern int trace_flag;
#define dbg_printf(fmt, ...) do { if (trace_flag) fprintf(stderr, fmt, __VA_ARGS__); } while (0) #define dbg_printf(fmt, ...) do { if (trace_flag) { fprintf(stderr, "[%10.5f] ", (double)(current_time_ns / 1000)/1000000); fprintf(stderr, fmt, __VA_ARGS__); } } while (0)
#else #else
#define dbg_printf(fmt, ...) #define dbg_printf(fmt, ...)
#endif #endif

@ -47,7 +47,7 @@
/* description of the data structure used: /* description of the data structure used:
* *
* - we assume that no more than SEQMAP_MAXSEQ (65535) pings are sent in * - we assume that no more than SEQMAP_MAXSEQ (65535) pings are sent in
* the timeout interval (SEQMAP_TIMEOUT_IN_S) * the timeout interval (SEQMAP_TIMEOUT_IN_NS)
* - we store the values in an array with SEQMAP_MAXSEQ elements * - we store the values in an array with SEQMAP_MAXSEQ elements
* - current sequence number % SEQMAP_MAXSEQ gives the current index * - current sequence number % SEQMAP_MAXSEQ gives the current index
* - when entering a value, we check that the current entry is expired * - when entering a value, we check that the current entry is expired
@ -56,7 +56,7 @@
static SEQMAP_VALUE* seqmap_map = NULL; static SEQMAP_VALUE* seqmap_map = NULL;
static unsigned int seqmap_next_id = 0; static unsigned int seqmap_next_id = 0;
#define SEQMAP_TIMEOUT_IN_S 10 #define SEQMAP_TIMEOUT_IN_NS 10000000000
#define SEQMAP_UNASSIGNED_HOST_NR UINT_MAX #define SEQMAP_UNASSIGNED_HOST_NR UINT_MAX
void seqmap_init() void seqmap_init()
@ -67,7 +67,7 @@ void seqmap_init()
} }
} }
unsigned int seqmap_add(unsigned int host_nr, unsigned int ping_count, struct timespec* now) unsigned int seqmap_add(unsigned int host_nr, unsigned int ping_count, int64_t timestamp)
{ {
unsigned int current_id; unsigned int current_id;
SEQMAP_VALUE* next_value; SEQMAP_VALUE* next_value;
@ -80,17 +80,16 @@ unsigned int seqmap_add(unsigned int host_nr, unsigned int ping_count, struct ti
/* check if expired (note that unused seqmap values will have fields set to /* check if expired (note that unused seqmap values will have fields set to
* 0, so will be seen as expired */ * 0, so will be seen as expired */
next_value = &seqmap_map[seqmap_next_id]; next_value = &seqmap_map[seqmap_next_id];
if (next_value->ping_ts.tv_sec != 0 && (now->tv_sec - next_value->ping_ts.tv_sec) < SEQMAP_TIMEOUT_IN_S) { if (timestamp - next_value->ping_ts < SEQMAP_TIMEOUT_IN_NS) {
fprintf(stderr, "fping error: not enough sequence numbers available! (expire_timeout=%d, host_nr=%d, ping_count=%d, seqmap_next_id=%d)\n", fprintf(stderr, "fping error: not enough sequence numbers available! (expire_timeout=%ld, host_nr=%d, ping_count=%d, seqmap_next_id=%d)\n",
SEQMAP_TIMEOUT_IN_S, host_nr, ping_count, seqmap_next_id); SEQMAP_TIMEOUT_IN_NS, host_nr, ping_count, seqmap_next_id);
exit(4); exit(4);
} }
/* store the value */ /* store the value */
next_value->host_nr = host_nr; next_value->host_nr = host_nr;
next_value->ping_count = ping_count; next_value->ping_count = ping_count;
next_value->ping_ts.tv_sec = now->tv_sec; next_value->ping_ts = timestamp;
next_value->ping_ts.tv_nsec = now->tv_nsec;
/* increase next id */ /* increase next id */
current_id = seqmap_next_id; current_id = seqmap_next_id;
@ -101,7 +100,7 @@ unsigned int seqmap_add(unsigned int host_nr, unsigned int ping_count, struct ti
return current_id; return current_id;
} }
SEQMAP_VALUE* seqmap_fetch(unsigned int id, struct timespec* now) SEQMAP_VALUE* seqmap_fetch(unsigned int id, int64_t now)
{ {
SEQMAP_VALUE* value; SEQMAP_VALUE* value;
@ -112,7 +111,9 @@ SEQMAP_VALUE* seqmap_fetch(unsigned int id, struct timespec* now)
value = &seqmap_map[id]; value = &seqmap_map[id];
/* verify that value is not expired */ /* verify that value is not expired */
if (now->tv_sec - value->ping_ts.tv_sec >= SEQMAP_TIMEOUT_IN_S) { if (now - value->ping_ts >= SEQMAP_TIMEOUT_IN_NS) {
dbg_printf("seqmap_fetch(%d) -> host: %d, index: %d -> DISCARDED %ld\n", id, value->host_nr, value->ping_count,
now - value->ping_ts);
return NULL; return NULL;
} }

@ -2,19 +2,20 @@
#define SEQMAP_H #define SEQMAP_H
#include <sys/time.h> #include <sys/time.h>
#include <stdint.h>
typedef struct seqmap_value typedef struct seqmap_value
{ {
unsigned int host_nr; unsigned int host_nr;
unsigned int ping_count; unsigned int ping_count;
struct timespec ping_ts; int64_t ping_ts;
} SEQMAP_VALUE; } SEQMAP_VALUE;
#define SEQMAP_MAXSEQ 65535 #define SEQMAP_MAXSEQ 65535
void seqmap_init(); void seqmap_init();
unsigned int seqmap_add(unsigned int host_nr, unsigned int ping_count, struct timespec *now); unsigned int seqmap_add(unsigned int host_nr, unsigned int ping_count, int64_t now);
SEQMAP_VALUE *seqmap_fetch(unsigned int id, struct timespec *now); SEQMAP_VALUE *seqmap_fetch(unsigned int id, int64_t now);
#endif #endif

Loading…
Cancel
Save