Matt Provost
mattpro@yelp.com
Ping to Pong
Rewriting Ping as a Video Game
Yelp’s Mission
Connecting people with great
local businesses.
/*
* P I N G . C
*
* Using the InterNet Control Message Protocol (ICMP) "ECHO" facility,
* measure round-trip-delays and packet loss across network paths.
*
* Author -
* Mike Muuss
* U. S. Army Ballistic Research Laboratory
* December, 1983
* Modified at Uc Berkeley
* Record Route and verbose headers - Phil Dykstra, BRL, March 1988.
*
* Status -
* Public Domain. Distribution Unlimited.
*
* Bugs -
* More statistics could always be gathered.
* This program has to run SUID to ROOT to access the ICMP socket.
*/
Raspberry Pi Model B+ (700 MHz): Dhrystones per Second: 1481481
VAX MIPS rating = 843.19
Raspberry Pi 2 Model B (1000 MHz)*: Dhrystones per Second: 2085024
VAX MIPS rating = 1186.70
*using one core
while (true)
{
processInput();
update();
render();
}
http://gameprogrammingpatterns.com/game-loop.html
NAME
ping - send ICMP ECHO_REQUEST packets to network hosts
SYNOPSIS
ping [-dfnqrvR] [-c count] [-i wait] [-l preload] [-p pattern] [-s packetsize]
OPTIONS
-f
Flood ping. Outputs packets as fast as they come back or one hundred times per
second, whichever is more. For every ECHO_REQUEST sent a period ``.'' is printed,
while for every ECHO_REPLY received a backspace is printed. This provides a rapid
display of how many packets are being dropped. Only the super-user may use this
option. This can be very hard on a network and should be used with caution.
-i wait
Wait wait seconds between sending each packet. The default is to wait for one
second between each packet. This option is incompatible with the -f option.
while (true)
{
double start = getCurrentTime();
processInput();
update();
render();
sleep(start + MS_PER_FRAME - getCurrentTime());
}
http://gameprogrammingpatterns.com/game-loop.html
/*
* C A T C H E R
*
* This routine causes another PING to be transmitted, and then
* schedules another SIGALRM for 1 second from now.
*
* Bug -
* Our sense of time will slowly skew (ie, packets will not be launched
* exactly at 1-second intervals). This does not affect the quality
* of the delay and loss statistics.
*/
catcher()
{
if (nreceived) {
waittime = 2 * tmax / 1000;
if (waittime == 0)
waittime = 1;
} else
waittime = PING_MAXWAIT; // 10
signal(SIGALRM, finish);
alarm(waittime);
}
}
NAME
alarm - schedule an alarm signal
SYNOPSIS
#include <unistd.h>
unsigned alarm(unsigned seconds);
DESCRIPTION
The alarm() function shall cause the system to generate a SIGALRM signal for the process after the number of realtime seconds
specified by seconds have elapsed. Processor scheduling delays may prevent the process from handling the signal as soon as it is
generated.
iputils/ping_common.c:
int __schedule_exit(int next)
{
if (nreceived) {
waittime = 2 * tmax;
if (waittime < 1000*interval)
waittime = 1000*interval;
} else
waittime = lingertime*1000;
// struct timeval it_value
it.it_value.tv_sec = waittime/1000000;
it.it_value.tv_usec = waittime%1000000;
setitimer(ITIMER_REAL, &it, NULL);
}
NAME
getitimer, setitimer - get and set value of interval timer
SYNOPSIS
#include <sys/time.h>
int setitimer(int which, const struct itimerval *restrict value, struct itimerval *restrict ovalue);
DESCRIPTION
The setitimer() function shall set the timer specified by which to the value specified in the structure pointed to by value, and if ovalue
is not a null pointer, store the previous value of the timer in the structure pointed to by ovalue.
A timer value is defined by the itimerval structure, specified in <sys/time.h>. If it_value is non-zero, it shall indicate the time to the
next timer expiration. If it_interval is non-zero, it shall specify a value to be used in reloading it_value when the timer expires.
An XSI-conforming implementation provides each process with at least three interval timers, which are indicated by the which
argument:
ITIMER_PROF
Decrements both in process virtual time and when the system is running on behalf of the process. It is designed to be
used by interpreters in statistically profiling the execution of interpreted programs. Each time the ITIMER_PROF timer expires,
the SIGPROF signal is delivered.
ITIMER_REAL
Decrements in real time. A SIGALRM signal is delivered when this timer expires.
ITIMER_VIRTUAL
Decrements in process virtual time. It runs only when the process is executing. A SIGVTALRM signal is delivered when
it expires.
$ rrdtool create target.rrd 
--start 1537445727 
--step 10 
DS:ping:GAUGE:60:0:10000 
RRA:AVERAGE:0.5:6:60 
RRA:AVERAGE:0.5:8640:31
Sent Elapsed ms RTT Average
1 0 118
2 1,118 125
3 2,243 109
4 3,352 113
5 4,465 127
6 5,592 121
7 6,713 123
8 7,836 117
9 8,953 116 119
10 10,069 129
Sent Elapsed ms RTT Average
9 8,953 116 119
10 10,069 129
11 11,198 111
12 12,309 487
13 13,796 353
14 15,149 673
15 16,822 731
16 18,553 365
17 19,918 212 382.625
18 21,130 212
Sent Elapsed ms RTT Average
17 19,918 212 382.625
18 21,130 212
19 22,342 145
20 23,487 119
21 24,606 1245
22 26,851 1561
23 29,412 1812 849
24 32,224 743
Sent Elapsed ms RTT Average
1 0 118
2 1,118 125
3 2,243 109
4 3,352 113
5 4,465 127
6 5,592 121
7 6,713 123
8 7,836 117
9 8,953 116 119
10 10,069 129
11 11,198 111
12 12,309 487
13 13,796 353
14 15,149 673
15 16,822 731
16 18,553 365
17 19,918 212 383
18 21,130 212
19 22,342 145
20 23,487 119
21 24,606 1345
22 26,951 1561
23 29,512 1812 866
24 32,324 743
http://rrdtool.vandenbogaerdt.nl/process.php
double lastTime = getCurrentTime();
while (true)
{
double current = getCurrentTime();
double elapsed = current - lastTime;
processInput();
update(elapsed);
render();
lastTime = current;
}
http://gameprogrammingpatterns.com/game-loop.html
Sent Elapsed ms RTT Average Actual Start Deadline Sleep Time Adjusted RTT Adjusted Avg
1 0 118 0 1,000 882 118
2 1,118 125 1,000 2,000 875 125
3 2,243 109 2,000 3,000 891 109
4 3,352 113 3,000 4,000 887 113
5 4,465 127 4,000 5,000 873 127
6 5,592 121 5,000 6,000 879 121
7 6,713 123 6,000 7,000 877 123
8 7,836 117 7,000 8,000 883 117
9 8,953 116 119 8,000 9,000 884 116 119
10 10,069 129 9,000 10,000 871 129
11 11,198 111 10,000 11,000 889 111
12 12,309 487 11,000 12,000 513 487
13 13,796 353 12,000 13,000 647 353
14 15,149 673 13,000 14,000 327 673
15 16,822 731 14,000 15,000 269 731
16 18,553 365 15,000 16,000 635 365
17 19,918 212 383 16,000 17,000 788 212 383
18 21,130 212 17,000 18,000 788 212
19 22,342 145 18,000 19,000 855 145
20 23,487 119 19,000 20,000 881 119
21 24,606 1345 20,000 21,000 0 1,345
22 26,951 1561 21,345 22,000 0 1,906
23 29,512 1812 866 22,906 23,000 0 2,718 1,074
24 32,324 743 24,718 24,000 0 2,461
NAME
fping - send ICMP ECHO_REQUEST packets to network hosts
SYNOPSIS
fping [ options ] [ systems... ]
OPTIONS
-i n The minimum amount of time (in milliseconds) between sending a ping packet to any
target (default is 25).
-p <n> In looping or counting modes (-l, -c, or -C), this parameter sets the time in
milliseconds that fping waits between successive packets to an individual target.
Default is 1000.
EXAMPLES
Generate 20 pings to two hosts in ca. 1 second (i.e. one ping every 50 ms to each host),
and report every ping RTT at the end:
$ fping −q −i=1 −C=20 −p=50 127.0.0.1 127.0.0.2
NAME
nfsping - send RPC NULL requests to NFS servers
SYNOPSIS
nfsping [-aAdDEGhKlLmMnNqRsTuv] [-c count] [-C count] [-g prefix] [-H hertz] [-i
interval] [-P port] [-Q interval ] [-S source] [-ttimeout] [-V version] <servers...>
OPTIONS
-H
The polling frequency in Hertz. This is the number of pings sent to each target per
second. Default = 10.
NFStash/src/nfsping.c:
/* calculate the sleep_time based on the frequency */
/* check for a frequency of 1, that's a simple case */
/* this doesn't support frequencies lower than 1Hz */
if (hertz == 1) {
sleep_time.tv_sec = 1;
sleep_time.tv_nsec = 0;
} else {
sleep_time.tv_sec = 0;
/* nanoseconds */
sleep_time.tv_nsec = 1000000000 / hertz;
}
NFStash/src/nfsping.c:
/* sleep between rounds */
/* measure how long the current round took, and subtract that from the sleep time */
/* this tries to ensure that each polling round takes the same time */
#ifdef CLOCK_MONOTONIC_RAW
clock_gettime(CLOCK_MONOTONIC_RAW, &loop_end);
#else
clock_gettime(CLOCK_MONOTONIC, &loop_end);
#endif
timespecsub(&loop_end, &loop_start, &loop_elapsed);
debug("Polling took %lld.%.9ldsn", (long long)loop_elapsed.tv_sec,loop_elapsed.tv_nsec);
/* don't sleep if we went over the sleep_time */
if (timespeccmp(&loop_elapsed, &sleep_time, >)) {
debug("Slow poll, not sleepingn");
} else {
timespecsub(&sleep_time, &loop_elapsed, &sleepy);
debug("Sleeping for %lld.%.9ldsn", (long long)sleepy.tv_sec, sleepy.tv_nsec);
nanosleep(&sleepy, NULL);
}
NAME
nanosleep - high resolution sleep (REALTIME)
SYNOPSIS
#include <time.h>
int nanosleep(const struct timespec *rqtp, struct timespec *rmtp);
DESCRIPTION
The nanosleep() function shall cause the current thread to be suspended from execution until either the time interval specified by the
rqtp argument has elapsed or a signal is delivered to the calling thread, and its action is to invoke a signal-catching function or to
terminate the process. The suspension time may be longer than requested because the argument value is rounded up to an integer
multiple of the sleep resolution or because of the scheduling of other activity by the system. But, except for the case of being
interrupted by a signal, the suspension time shall not be less than the time specified by rqtp, as measured by the system clock
CLOCK_REALTIME.
The use of the nanosleep() function has no effect on the action or blockage of any signal.
NFStash/src/nfsping.c:
/* grab the wall clock time for output */
/* use the start time of the request */
/* the call_start timer is more important so do this first so we're not measuring the
time this call takes */
clock_gettime(CLOCK_REALTIME, &wall_clock);
/* first time marker */
/* the MONOTONIC clocks don't record the actual time but are good for measuring elapsed
time accurately */
#ifdef CLOCK_MONOTONIC_RAW
clock_gettime(CLOCK_MONOTONIC_RAW, &call_start);
#else
clock_gettime(CLOCK_MONOTONIC, &call_start);
#endif
/* the actual ping */
status = nfsproc3_null_3(NULL, target->client);
/* second time marker */
#ifdef CLOCK_MONOTONIC_RAW
clock_gettime(CLOCK_MONOTONIC_RAW, &call_end);
#else
clock_gettime(CLOCK_MONOTONIC, &call_end);
#endif
NAME
clock_getres, clock_gettime, clock_settime - clock and timer functions (REALTIME)
SYNOPSIS
#include <time.h>
int clock_getres(clockid_t clock_id, struct timespec *res);
int clock_gettime(clockid_t clock_id, struct timespec *tp);
int clock_settime(clockid_t clock_id, const struct timespec *tp);
DESCRIPTION
The clock_gettime() function shall return the current value tp for the specified clock, clock_id.
A clock may be system-wide (that is, visible to all processes) or per-process (measuring time that is meaningful only within a
process). All implementations shall support a clock_id of CLOCK_REALTIME as defined in <time.h>. This clock represents the realtime
clock for the system. For this clock, the values returned by clock_gettime() and specified by clock_settime() represent the amount of
time (in seconds and nanoseconds) since the Epoch. An implementation may also support additional clocks.
Setting the value of the CLOCK_REALTIME clock via clock_settime() shall have no effect on threads that are blocked waiting for a
relative time service based upon this clock, including the nanosleep() function; nor on the expiration of relative timers based upon
this clock. Consequently, these time services shall expire when the requested relative interval elapses, independently of the new or
old value of the clock.
If the Monotonic Clock option is supported, all implementations shall support a clock_id of CLOCK_MONOTONIC defined in <time.h>.
This clock represents the monotonic clock for the system. For this clock, the value returned by clock_gettime() represents the
amount of time (in seconds and nanoseconds) since an unspecified point in the past (for example, system start-up time, or the
Epoch). This point does not change after system start-up time. The value of the CLOCK_MONOTONIC clock cannot be set via
clock_settime().
CLOCK_MONOTONIC
Clock that cannot be set and represents monotonic time since
some unspecified starting point. This clock is not affected
by discontinuous jumps in the system time (e.g., if the system
administrator manually changes the clock), but is affected by
the incremental adjustments performed by adjtime(3) and NTP.
CLOCK_MONOTONIC_RAW (since Linux 2.6.28; Linux-specific)
Similar to CLOCK_MONOTONIC, but provides access to a raw hard ‐
ware-based time that is not subject to NTP adjustments or the
incremental adjustments performed by adjtime(3).
www.yelp.com/careers/
We're Hiring!
@YelpEngineering
fb.com/YelpEngineers
engineeringblog.yelp.com
github.com/yelp

Ping to Pong

  • 1.
    Matt Provost mattpro@yelp.com Ping toPong Rewriting Ping as a Video Game
  • 2.
    Yelp’s Mission Connecting peoplewith great local businesses.
  • 3.
    /* * P IN G . C * * Using the InterNet Control Message Protocol (ICMP) "ECHO" facility, * measure round-trip-delays and packet loss across network paths. * * Author - * Mike Muuss * U. S. Army Ballistic Research Laboratory * December, 1983 * Modified at Uc Berkeley * Record Route and verbose headers - Phil Dykstra, BRL, March 1988. * * Status - * Public Domain. Distribution Unlimited. * * Bugs - * More statistics could always be gathered. * This program has to run SUID to ROOT to access the ICMP socket. */
  • 6.
    Raspberry Pi ModelB+ (700 MHz): Dhrystones per Second: 1481481 VAX MIPS rating = 843.19 Raspberry Pi 2 Model B (1000 MHz)*: Dhrystones per Second: 2085024 VAX MIPS rating = 1186.70 *using one core
  • 8.
  • 9.
    NAME ping - sendICMP ECHO_REQUEST packets to network hosts SYNOPSIS ping [-dfnqrvR] [-c count] [-i wait] [-l preload] [-p pattern] [-s packetsize] OPTIONS -f Flood ping. Outputs packets as fast as they come back or one hundred times per second, whichever is more. For every ECHO_REQUEST sent a period ``.'' is printed, while for every ECHO_REPLY received a backspace is printed. This provides a rapid display of how many packets are being dropped. Only the super-user may use this option. This can be very hard on a network and should be used with caution. -i wait Wait wait seconds between sending each packet. The default is to wait for one second between each packet. This option is incompatible with the -f option.
  • 10.
    while (true) { double start= getCurrentTime(); processInput(); update(); render(); sleep(start + MS_PER_FRAME - getCurrentTime()); } http://gameprogrammingpatterns.com/game-loop.html
  • 11.
    /* * C AT C H E R * * This routine causes another PING to be transmitted, and then * schedules another SIGALRM for 1 second from now. * * Bug - * Our sense of time will slowly skew (ie, packets will not be launched * exactly at 1-second intervals). This does not affect the quality * of the delay and loss statistics. */ catcher() { if (nreceived) { waittime = 2 * tmax / 1000; if (waittime == 0) waittime = 1; } else waittime = PING_MAXWAIT; // 10 signal(SIGALRM, finish); alarm(waittime); } }
  • 12.
    NAME alarm - schedulean alarm signal SYNOPSIS #include <unistd.h> unsigned alarm(unsigned seconds); DESCRIPTION The alarm() function shall cause the system to generate a SIGALRM signal for the process after the number of realtime seconds specified by seconds have elapsed. Processor scheduling delays may prevent the process from handling the signal as soon as it is generated.
  • 13.
    iputils/ping_common.c: int __schedule_exit(int next) { if(nreceived) { waittime = 2 * tmax; if (waittime < 1000*interval) waittime = 1000*interval; } else waittime = lingertime*1000; // struct timeval it_value it.it_value.tv_sec = waittime/1000000; it.it_value.tv_usec = waittime%1000000; setitimer(ITIMER_REAL, &it, NULL); }
  • 14.
    NAME getitimer, setitimer -get and set value of interval timer SYNOPSIS #include <sys/time.h> int setitimer(int which, const struct itimerval *restrict value, struct itimerval *restrict ovalue); DESCRIPTION The setitimer() function shall set the timer specified by which to the value specified in the structure pointed to by value, and if ovalue is not a null pointer, store the previous value of the timer in the structure pointed to by ovalue. A timer value is defined by the itimerval structure, specified in <sys/time.h>. If it_value is non-zero, it shall indicate the time to the next timer expiration. If it_interval is non-zero, it shall specify a value to be used in reloading it_value when the timer expires. An XSI-conforming implementation provides each process with at least three interval timers, which are indicated by the which argument: ITIMER_PROF Decrements both in process virtual time and when the system is running on behalf of the process. It is designed to be used by interpreters in statistically profiling the execution of interpreted programs. Each time the ITIMER_PROF timer expires, the SIGPROF signal is delivered. ITIMER_REAL Decrements in real time. A SIGALRM signal is delivered when this timer expires. ITIMER_VIRTUAL Decrements in process virtual time. It runs only when the process is executing. A SIGVTALRM signal is delivered when it expires.
  • 15.
    $ rrdtool createtarget.rrd --start 1537445727 --step 10 DS:ping:GAUGE:60:0:10000 RRA:AVERAGE:0.5:6:60 RRA:AVERAGE:0.5:8640:31
  • 17.
    Sent Elapsed msRTT Average 1 0 118 2 1,118 125 3 2,243 109 4 3,352 113 5 4,465 127 6 5,592 121 7 6,713 123 8 7,836 117 9 8,953 116 119 10 10,069 129
  • 18.
    Sent Elapsed msRTT Average 9 8,953 116 119 10 10,069 129 11 11,198 111 12 12,309 487 13 13,796 353 14 15,149 673 15 16,822 731 16 18,553 365 17 19,918 212 382.625 18 21,130 212
  • 19.
    Sent Elapsed msRTT Average 17 19,918 212 382.625 18 21,130 212 19 22,342 145 20 23,487 119 21 24,606 1245 22 26,851 1561 23 29,412 1812 849 24 32,224 743
  • 20.
    Sent Elapsed msRTT Average 1 0 118 2 1,118 125 3 2,243 109 4 3,352 113 5 4,465 127 6 5,592 121 7 6,713 123 8 7,836 117 9 8,953 116 119 10 10,069 129 11 11,198 111 12 12,309 487 13 13,796 353 14 15,149 673 15 16,822 731 16 18,553 365 17 19,918 212 383 18 21,130 212 19 22,342 145 20 23,487 119 21 24,606 1345 22 26,951 1561 23 29,512 1812 866 24 32,324 743
  • 21.
  • 22.
    double lastTime =getCurrentTime(); while (true) { double current = getCurrentTime(); double elapsed = current - lastTime; processInput(); update(elapsed); render(); lastTime = current; } http://gameprogrammingpatterns.com/game-loop.html
  • 23.
    Sent Elapsed msRTT Average Actual Start Deadline Sleep Time Adjusted RTT Adjusted Avg 1 0 118 0 1,000 882 118 2 1,118 125 1,000 2,000 875 125 3 2,243 109 2,000 3,000 891 109 4 3,352 113 3,000 4,000 887 113 5 4,465 127 4,000 5,000 873 127 6 5,592 121 5,000 6,000 879 121 7 6,713 123 6,000 7,000 877 123 8 7,836 117 7,000 8,000 883 117 9 8,953 116 119 8,000 9,000 884 116 119 10 10,069 129 9,000 10,000 871 129 11 11,198 111 10,000 11,000 889 111 12 12,309 487 11,000 12,000 513 487 13 13,796 353 12,000 13,000 647 353 14 15,149 673 13,000 14,000 327 673 15 16,822 731 14,000 15,000 269 731 16 18,553 365 15,000 16,000 635 365 17 19,918 212 383 16,000 17,000 788 212 383 18 21,130 212 17,000 18,000 788 212 19 22,342 145 18,000 19,000 855 145 20 23,487 119 19,000 20,000 881 119 21 24,606 1345 20,000 21,000 0 1,345 22 26,951 1561 21,345 22,000 0 1,906 23 29,512 1812 866 22,906 23,000 0 2,718 1,074 24 32,324 743 24,718 24,000 0 2,461
  • 25.
    NAME fping - sendICMP ECHO_REQUEST packets to network hosts SYNOPSIS fping [ options ] [ systems... ] OPTIONS -i n The minimum amount of time (in milliseconds) between sending a ping packet to any target (default is 25). -p <n> In looping or counting modes (-l, -c, or -C), this parameter sets the time in milliseconds that fping waits between successive packets to an individual target. Default is 1000. EXAMPLES Generate 20 pings to two hosts in ca. 1 second (i.e. one ping every 50 ms to each host), and report every ping RTT at the end: $ fping −q −i=1 −C=20 −p=50 127.0.0.1 127.0.0.2
  • 26.
    NAME nfsping - sendRPC NULL requests to NFS servers SYNOPSIS nfsping [-aAdDEGhKlLmMnNqRsTuv] [-c count] [-C count] [-g prefix] [-H hertz] [-i interval] [-P port] [-Q interval ] [-S source] [-ttimeout] [-V version] <servers...> OPTIONS -H The polling frequency in Hertz. This is the number of pings sent to each target per second. Default = 10.
  • 27.
    NFStash/src/nfsping.c: /* calculate thesleep_time based on the frequency */ /* check for a frequency of 1, that's a simple case */ /* this doesn't support frequencies lower than 1Hz */ if (hertz == 1) { sleep_time.tv_sec = 1; sleep_time.tv_nsec = 0; } else { sleep_time.tv_sec = 0; /* nanoseconds */ sleep_time.tv_nsec = 1000000000 / hertz; }
  • 28.
    NFStash/src/nfsping.c: /* sleep betweenrounds */ /* measure how long the current round took, and subtract that from the sleep time */ /* this tries to ensure that each polling round takes the same time */ #ifdef CLOCK_MONOTONIC_RAW clock_gettime(CLOCK_MONOTONIC_RAW, &loop_end); #else clock_gettime(CLOCK_MONOTONIC, &loop_end); #endif timespecsub(&loop_end, &loop_start, &loop_elapsed); debug("Polling took %lld.%.9ldsn", (long long)loop_elapsed.tv_sec,loop_elapsed.tv_nsec); /* don't sleep if we went over the sleep_time */ if (timespeccmp(&loop_elapsed, &sleep_time, >)) { debug("Slow poll, not sleepingn"); } else { timespecsub(&sleep_time, &loop_elapsed, &sleepy); debug("Sleeping for %lld.%.9ldsn", (long long)sleepy.tv_sec, sleepy.tv_nsec); nanosleep(&sleepy, NULL); }
  • 29.
    NAME nanosleep - highresolution sleep (REALTIME) SYNOPSIS #include <time.h> int nanosleep(const struct timespec *rqtp, struct timespec *rmtp); DESCRIPTION The nanosleep() function shall cause the current thread to be suspended from execution until either the time interval specified by the rqtp argument has elapsed or a signal is delivered to the calling thread, and its action is to invoke a signal-catching function or to terminate the process. The suspension time may be longer than requested because the argument value is rounded up to an integer multiple of the sleep resolution or because of the scheduling of other activity by the system. But, except for the case of being interrupted by a signal, the suspension time shall not be less than the time specified by rqtp, as measured by the system clock CLOCK_REALTIME. The use of the nanosleep() function has no effect on the action or blockage of any signal.
  • 30.
    NFStash/src/nfsping.c: /* grab thewall clock time for output */ /* use the start time of the request */ /* the call_start timer is more important so do this first so we're not measuring the time this call takes */ clock_gettime(CLOCK_REALTIME, &wall_clock); /* first time marker */ /* the MONOTONIC clocks don't record the actual time but are good for measuring elapsed time accurately */ #ifdef CLOCK_MONOTONIC_RAW clock_gettime(CLOCK_MONOTONIC_RAW, &call_start); #else clock_gettime(CLOCK_MONOTONIC, &call_start); #endif /* the actual ping */ status = nfsproc3_null_3(NULL, target->client); /* second time marker */ #ifdef CLOCK_MONOTONIC_RAW clock_gettime(CLOCK_MONOTONIC_RAW, &call_end); #else clock_gettime(CLOCK_MONOTONIC, &call_end); #endif
  • 31.
    NAME clock_getres, clock_gettime, clock_settime- clock and timer functions (REALTIME) SYNOPSIS #include <time.h> int clock_getres(clockid_t clock_id, struct timespec *res); int clock_gettime(clockid_t clock_id, struct timespec *tp); int clock_settime(clockid_t clock_id, const struct timespec *tp); DESCRIPTION The clock_gettime() function shall return the current value tp for the specified clock, clock_id. A clock may be system-wide (that is, visible to all processes) or per-process (measuring time that is meaningful only within a process). All implementations shall support a clock_id of CLOCK_REALTIME as defined in <time.h>. This clock represents the realtime clock for the system. For this clock, the values returned by clock_gettime() and specified by clock_settime() represent the amount of time (in seconds and nanoseconds) since the Epoch. An implementation may also support additional clocks. Setting the value of the CLOCK_REALTIME clock via clock_settime() shall have no effect on threads that are blocked waiting for a relative time service based upon this clock, including the nanosleep() function; nor on the expiration of relative timers based upon this clock. Consequently, these time services shall expire when the requested relative interval elapses, independently of the new or old value of the clock. If the Monotonic Clock option is supported, all implementations shall support a clock_id of CLOCK_MONOTONIC defined in <time.h>. This clock represents the monotonic clock for the system. For this clock, the value returned by clock_gettime() represents the amount of time (in seconds and nanoseconds) since an unspecified point in the past (for example, system start-up time, or the Epoch). This point does not change after system start-up time. The value of the CLOCK_MONOTONIC clock cannot be set via clock_settime().
  • 32.
    CLOCK_MONOTONIC Clock that cannotbe set and represents monotonic time since some unspecified starting point. This clock is not affected by discontinuous jumps in the system time (e.g., if the system administrator manually changes the clock), but is affected by the incremental adjustments performed by adjtime(3) and NTP. CLOCK_MONOTONIC_RAW (since Linux 2.6.28; Linux-specific) Similar to CLOCK_MONOTONIC, but provides access to a raw hard ‐ ware-based time that is not subject to NTP adjustments or the incremental adjustments performed by adjtime(3).
  • 33.
  • 34.