nmeter: add %T (zero-based timestamp) format
function old new delta collect_tv - 132 +132 collect_monotonic - 61 +61 nmeter_main 754 778 +24 gmtime - 21 +21 init_monotonic - 18 +18 init_functions 44 48 +4 packed_usage 33432 33420 -12 collect_time 125 19 -106 ------------------------------------------------------------------------------ (add/remove: 5/0 grow/shrink: 2/2 up/down: 260/-118) Total: 142 bytes Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
This commit is contained in:
parent
505eeae402
commit
4789c7cd81
@ -37,6 +37,7 @@
|
|||||||
//usage: "\n %[pn] # of processes"
|
//usage: "\n %[pn] # of processes"
|
||||||
//usage: "\n %b Block io"
|
//usage: "\n %b Block io"
|
||||||
//usage: "\n %Nt Time (with N decimal points)"
|
//usage: "\n %Nt Time (with N decimal points)"
|
||||||
|
//usage: "\n %NT Zero-based timestamp (with N decimal points)"
|
||||||
//usage: "\n %r Print <cr> instead of <lf> at EOL"
|
//usage: "\n %r Print <cr> instead of <lf> at EOL"
|
||||||
|
|
||||||
//TODO:
|
//TODO:
|
||||||
@ -88,6 +89,7 @@ struct globals {
|
|||||||
int delta;
|
int delta;
|
||||||
unsigned deltanz;
|
unsigned deltanz;
|
||||||
struct timeval tv;
|
struct timeval tv;
|
||||||
|
struct timeval start;
|
||||||
#define first_proc_file proc_stat
|
#define first_proc_file proc_stat
|
||||||
proc_file proc_stat; // Must match the order of proc_name's!
|
proc_file proc_stat; // Must match the order of proc_name's!
|
||||||
proc_file proc_loadavg;
|
proc_file proc_loadavg;
|
||||||
@ -101,7 +103,6 @@ struct globals {
|
|||||||
#define is26 (G.is26 )
|
#define is26 (G.is26 )
|
||||||
#define need_seconds (G.need_seconds )
|
#define need_seconds (G.need_seconds )
|
||||||
#define cur_outbuf (G.cur_outbuf )
|
#define cur_outbuf (G.cur_outbuf )
|
||||||
#define tv (G.tv )
|
|
||||||
#define proc_stat (G.proc_stat )
|
#define proc_stat (G.proc_stat )
|
||||||
#define proc_loadavg (G.proc_loadavg )
|
#define proc_loadavg (G.proc_loadavg )
|
||||||
#define proc_net_dev (G.proc_net_dev )
|
#define proc_net_dev (G.proc_net_dev )
|
||||||
@ -754,25 +755,53 @@ S_STAT(time_stat)
|
|||||||
unsigned scale;
|
unsigned scale;
|
||||||
S_STAT_END(time_stat)
|
S_STAT_END(time_stat)
|
||||||
|
|
||||||
static void FAST_FUNC collect_time(time_stat *s)
|
static void FAST_FUNC collect_tv(time_stat *s, struct timeval *tv, int local)
|
||||||
{
|
{
|
||||||
char buf[sizeof("12:34:56.123456")];
|
char buf[sizeof("12:34:56.123456")];
|
||||||
struct tm* tm;
|
struct tm* tm;
|
||||||
unsigned us = tv.tv_usec + s->scale/2;
|
unsigned us = tv->tv_usec + s->scale/2;
|
||||||
time_t t = tv.tv_sec;
|
time_t t = tv->tv_sec;
|
||||||
|
|
||||||
if (us >= 1000000) {
|
if (us >= 1000000) {
|
||||||
t++;
|
t++;
|
||||||
us -= 1000000;
|
us -= 1000000;
|
||||||
}
|
}
|
||||||
tm = localtime(&t);
|
if (local)
|
||||||
|
tm = localtime(&t);
|
||||||
|
else
|
||||||
|
tm = gmtime(&t);
|
||||||
|
|
||||||
sprintf(buf, "%02d:%02d:%02d", tm->tm_hour, tm->tm_min, tm->tm_sec);
|
sprintf(buf, "%02u:%02u:%02u", tm->tm_hour, tm->tm_min, tm->tm_sec);
|
||||||
if (s->prec)
|
if (s->prec)
|
||||||
sprintf(buf+8, ".%0*d", s->prec, us / s->scale);
|
sprintf(buf+8, ".%0*u", s->prec, us / s->scale);
|
||||||
put(buf);
|
put(buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void FAST_FUNC collect_time(time_stat *s)
|
||||||
|
{
|
||||||
|
collect_tv(s, &G.tv, /*local:*/ 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void FAST_FUNC collect_monotonic(time_stat *s)
|
||||||
|
{
|
||||||
|
struct timeval tv_mono;
|
||||||
|
|
||||||
|
tv_mono.tv_sec = G.tv.tv_sec - G.start.tv_sec;
|
||||||
|
#if 0 /* Do we want this? */
|
||||||
|
if (tv_mono.tv_sec < 0) {
|
||||||
|
/* Time went backwards, reset start time to "now" */
|
||||||
|
tv_mono.tv_sec = 0;
|
||||||
|
G.start = G.tv;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
tv_mono.tv_usec = G.tv.tv_usec - G.start.tv_usec;
|
||||||
|
if ((int32_t)tv_mono.tv_usec < 0) {
|
||||||
|
tv_mono.tv_usec += 1000000;
|
||||||
|
tv_mono.tv_sec--;
|
||||||
|
}
|
||||||
|
collect_tv(s, &tv_mono, /*local:*/ 0);
|
||||||
|
}
|
||||||
|
|
||||||
static s_stat* init_time(const char *param)
|
static s_stat* init_time(const char *param)
|
||||||
{
|
{
|
||||||
int prec;
|
int prec;
|
||||||
@ -789,6 +818,13 @@ static s_stat* init_time(const char *param)
|
|||||||
return (s_stat*)s;
|
return (s_stat*)s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static s_stat* init_monotonic(const char *param)
|
||||||
|
{
|
||||||
|
time_stat *s = (void*)init_time(param);
|
||||||
|
s->collect = collect_monotonic;
|
||||||
|
return (s_stat*)s;
|
||||||
|
}
|
||||||
|
|
||||||
static void FAST_FUNC collect_info(s_stat *s)
|
static void FAST_FUNC collect_info(s_stat *s)
|
||||||
{
|
{
|
||||||
gen ^= 1;
|
gen ^= 1;
|
||||||
@ -801,7 +837,7 @@ static void FAST_FUNC collect_info(s_stat *s)
|
|||||||
|
|
||||||
typedef s_stat* init_func(const char *param);
|
typedef s_stat* init_func(const char *param);
|
||||||
|
|
||||||
static const char options[] ALIGN1 = "ncmsfixptbr";
|
static const char options[] ALIGN1 = "ncmsfixptTbr";
|
||||||
static init_func *const init_functions[] = {
|
static init_func *const init_functions[] = {
|
||||||
init_if,
|
init_if,
|
||||||
init_cpu,
|
init_cpu,
|
||||||
@ -812,6 +848,7 @@ static init_func *const init_functions[] = {
|
|||||||
init_ctx,
|
init_ctx,
|
||||||
init_fork,
|
init_fork,
|
||||||
init_time,
|
init_time,
|
||||||
|
init_monotonic,
|
||||||
init_blk,
|
init_blk,
|
||||||
init_cr
|
init_cr
|
||||||
};
|
};
|
||||||
@ -913,13 +950,15 @@ int nmeter_main(int argc UNUSED_PARAM, char **argv)
|
|||||||
// Generate first samples but do not print them, they're bogus
|
// Generate first samples but do not print them, they're bogus
|
||||||
collect_info(first);
|
collect_info(first);
|
||||||
reset_outbuf();
|
reset_outbuf();
|
||||||
|
|
||||||
if (G.delta >= 0) {
|
if (G.delta >= 0) {
|
||||||
gettimeofday(&tv, NULL);
|
gettimeofday(&G.tv, NULL);
|
||||||
usleep(G.delta > 1000000 ? 1000000 : G.delta - tv.tv_usec % G.deltanz);
|
usleep(G.delta > 1000000 ? 1000000 : G.delta - G.tv.tv_usec % G.deltanz);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
gettimeofday(&G.start, NULL);
|
||||||
|
G.tv = G.start;
|
||||||
while (1) {
|
while (1) {
|
||||||
gettimeofday(&tv, NULL);
|
|
||||||
collect_info(first);
|
collect_info(first);
|
||||||
put_c(G.final_char);
|
put_c(G.final_char);
|
||||||
print_outbuf();
|
print_outbuf();
|
||||||
@ -932,11 +971,11 @@ int nmeter_main(int argc UNUSED_PARAM, char **argv)
|
|||||||
if (G.delta >= 0) {
|
if (G.delta >= 0) {
|
||||||
int rem;
|
int rem;
|
||||||
// can be commented out, will sacrifice sleep time precision a bit
|
// can be commented out, will sacrifice sleep time precision a bit
|
||||||
gettimeofday(&tv, NULL);
|
gettimeofday(&G.tv, NULL);
|
||||||
if (need_seconds)
|
if (need_seconds)
|
||||||
rem = G.delta - ((ullong)tv.tv_sec*1000000 + tv.tv_usec) % G.deltanz;
|
rem = G.delta - ((ullong)G.tv.tv_sec*1000000 + G.tv.tv_usec) % G.deltanz;
|
||||||
else
|
else
|
||||||
rem = G.delta - (unsigned)tv.tv_usec % G.deltanz;
|
rem = G.delta - (unsigned)G.tv.tv_usec % G.deltanz;
|
||||||
// Sometimes kernel wakes us up just a tiny bit earlier than asked
|
// Sometimes kernel wakes us up just a tiny bit earlier than asked
|
||||||
// Do not go to very short sleep in this case
|
// Do not go to very short sleep in this case
|
||||||
if (rem < (unsigned)G.delta / 128) {
|
if (rem < (unsigned)G.delta / 128) {
|
||||||
@ -944,6 +983,7 @@ int nmeter_main(int argc UNUSED_PARAM, char **argv)
|
|||||||
}
|
}
|
||||||
usleep(rem);
|
usleep(rem);
|
||||||
}
|
}
|
||||||
|
gettimeofday(&G.tv, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*return 0;*/
|
/*return 0;*/
|
||||||
|
Loading…
Reference in New Issue
Block a user