aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2020-06-10 15:37:39 +0200
committerDenys Vlasenko <vda.linux@googlemail.com>2020-06-10 15:37:39 +0200
commit4789c7cd8152fee53c176e569b022ec4013597a0 (patch)
tree0fc5d8198b3448d1a03b0e965863a3daa363ef8c
parent505eeae402a84dc5208986c5ad611f5e485cbe34 (diff)
downloadbusybox-w32-4789c7cd8152fee53c176e569b022ec4013597a0.tar.gz
busybox-w32-4789c7cd8152fee53c176e569b022ec4013597a0.tar.bz2
busybox-w32-4789c7cd8152fee53c176e569b022ec4013597a0.zip
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>
-rw-r--r--procps/nmeter.c68
1 files changed, 54 insertions, 14 deletions
diff --git a/procps/nmeter.c b/procps/nmeter.c
index ae16d8548..856ce0202 100644
--- a/procps/nmeter.c
+++ b/procps/nmeter.c
@@ -37,6 +37,7 @@
37//usage: "\n %[pn] # of processes" 37//usage: "\n %[pn] # of processes"
38//usage: "\n %b Block io" 38//usage: "\n %b Block io"
39//usage: "\n %Nt Time (with N decimal points)" 39//usage: "\n %Nt Time (with N decimal points)"
40//usage: "\n %NT Zero-based timestamp (with N decimal points)"
40//usage: "\n %r Print <cr> instead of <lf> at EOL" 41//usage: "\n %r Print <cr> instead of <lf> at EOL"
41 42
42//TODO: 43//TODO:
@@ -88,6 +89,7 @@ struct globals {
88 int delta; 89 int delta;
89 unsigned deltanz; 90 unsigned deltanz;
90 struct timeval tv; 91 struct timeval tv;
92 struct timeval start;
91#define first_proc_file proc_stat 93#define first_proc_file proc_stat
92 proc_file proc_stat; // Must match the order of proc_name's! 94 proc_file proc_stat; // Must match the order of proc_name's!
93 proc_file proc_loadavg; 95 proc_file proc_loadavg;
@@ -101,7 +103,6 @@ struct globals {
101#define is26 (G.is26 ) 103#define is26 (G.is26 )
102#define need_seconds (G.need_seconds ) 104#define need_seconds (G.need_seconds )
103#define cur_outbuf (G.cur_outbuf ) 105#define cur_outbuf (G.cur_outbuf )
104#define tv (G.tv )
105#define proc_stat (G.proc_stat ) 106#define proc_stat (G.proc_stat )
106#define proc_loadavg (G.proc_loadavg ) 107#define proc_loadavg (G.proc_loadavg )
107#define proc_net_dev (G.proc_net_dev ) 108#define proc_net_dev (G.proc_net_dev )
@@ -754,25 +755,53 @@ S_STAT(time_stat)
754 unsigned scale; 755 unsigned scale;
755S_STAT_END(time_stat) 756S_STAT_END(time_stat)
756 757
757static void FAST_FUNC collect_time(time_stat *s) 758static void FAST_FUNC collect_tv(time_stat *s, struct timeval *tv, int local)
758{ 759{
759 char buf[sizeof("12:34:56.123456")]; 760 char buf[sizeof("12:34:56.123456")];
760 struct tm* tm; 761 struct tm* tm;
761 unsigned us = tv.tv_usec + s->scale/2; 762 unsigned us = tv->tv_usec + s->scale/2;
762 time_t t = tv.tv_sec; 763 time_t t = tv->tv_sec;
763 764
764 if (us >= 1000000) { 765 if (us >= 1000000) {
765 t++; 766 t++;
766 us -= 1000000; 767 us -= 1000000;
767 } 768 }
768 tm = localtime(&t); 769 if (local)
770 tm = localtime(&t);
771 else
772 tm = gmtime(&t);
769 773
770 sprintf(buf, "%02d:%02d:%02d", tm->tm_hour, tm->tm_min, tm->tm_sec); 774 sprintf(buf, "%02u:%02u:%02u", tm->tm_hour, tm->tm_min, tm->tm_sec);
771 if (s->prec) 775 if (s->prec)
772 sprintf(buf+8, ".%0*d", s->prec, us / s->scale); 776 sprintf(buf+8, ".%0*u", s->prec, us / s->scale);
773 put(buf); 777 put(buf);
774} 778}
775 779
780static void FAST_FUNC collect_time(time_stat *s)
781{
782 collect_tv(s, &G.tv, /*local:*/ 1);
783}
784
785static void FAST_FUNC collect_monotonic(time_stat *s)
786{
787 struct timeval tv_mono;
788
789 tv_mono.tv_sec = G.tv.tv_sec - G.start.tv_sec;
790#if 0 /* Do we want this? */
791 if (tv_mono.tv_sec < 0) {
792 /* Time went backwards, reset start time to "now" */
793 tv_mono.tv_sec = 0;
794 G.start = G.tv;
795 }
796#endif
797 tv_mono.tv_usec = G.tv.tv_usec - G.start.tv_usec;
798 if ((int32_t)tv_mono.tv_usec < 0) {
799 tv_mono.tv_usec += 1000000;
800 tv_mono.tv_sec--;
801 }
802 collect_tv(s, &tv_mono, /*local:*/ 0);
803}
804
776static s_stat* init_time(const char *param) 805static s_stat* init_time(const char *param)
777{ 806{
778 int prec; 807 int prec;
@@ -789,6 +818,13 @@ static s_stat* init_time(const char *param)
789 return (s_stat*)s; 818 return (s_stat*)s;
790} 819}
791 820
821static s_stat* init_monotonic(const char *param)
822{
823 time_stat *s = (void*)init_time(param);
824 s->collect = collect_monotonic;
825 return (s_stat*)s;
826}
827
792static void FAST_FUNC collect_info(s_stat *s) 828static void FAST_FUNC collect_info(s_stat *s)
793{ 829{
794 gen ^= 1; 830 gen ^= 1;
@@ -801,7 +837,7 @@ static void FAST_FUNC collect_info(s_stat *s)
801 837
802typedef s_stat* init_func(const char *param); 838typedef s_stat* init_func(const char *param);
803 839
804static const char options[] ALIGN1 = "ncmsfixptbr"; 840static const char options[] ALIGN1 = "ncmsfixptTbr";
805static init_func *const init_functions[] = { 841static init_func *const init_functions[] = {
806 init_if, 842 init_if,
807 init_cpu, 843 init_cpu,
@@ -812,6 +848,7 @@ static init_func *const init_functions[] = {
812 init_ctx, 848 init_ctx,
813 init_fork, 849 init_fork,
814 init_time, 850 init_time,
851 init_monotonic,
815 init_blk, 852 init_blk,
816 init_cr 853 init_cr
817}; 854};
@@ -913,13 +950,15 @@ int nmeter_main(int argc UNUSED_PARAM, char **argv)
913 // Generate first samples but do not print them, they're bogus 950 // Generate first samples but do not print them, they're bogus
914 collect_info(first); 951 collect_info(first);
915 reset_outbuf(); 952 reset_outbuf();
953
916 if (G.delta >= 0) { 954 if (G.delta >= 0) {
917 gettimeofday(&tv, NULL); 955 gettimeofday(&G.tv, NULL);
918 usleep(G.delta > 1000000 ? 1000000 : G.delta - tv.tv_usec % G.deltanz); 956 usleep(G.delta > 1000000 ? 1000000 : G.delta - G.tv.tv_usec % G.deltanz);
919 } 957 }
920 958
959 gettimeofday(&G.start, NULL);
960 G.tv = G.start;
921 while (1) { 961 while (1) {
922 gettimeofday(&tv, NULL);
923 collect_info(first); 962 collect_info(first);
924 put_c(G.final_char); 963 put_c(G.final_char);
925 print_outbuf(); 964 print_outbuf();
@@ -932,11 +971,11 @@ int nmeter_main(int argc UNUSED_PARAM, char **argv)
932 if (G.delta >= 0) { 971 if (G.delta >= 0) {
933 int rem; 972 int rem;
934 // can be commented out, will sacrifice sleep time precision a bit 973 // can be commented out, will sacrifice sleep time precision a bit
935 gettimeofday(&tv, NULL); 974 gettimeofday(&G.tv, NULL);
936 if (need_seconds) 975 if (need_seconds)
937 rem = G.delta - ((ullong)tv.tv_sec*1000000 + tv.tv_usec) % G.deltanz; 976 rem = G.delta - ((ullong)G.tv.tv_sec*1000000 + G.tv.tv_usec) % G.deltanz;
938 else 977 else
939 rem = G.delta - (unsigned)tv.tv_usec % G.deltanz; 978 rem = G.delta - (unsigned)G.tv.tv_usec % G.deltanz;
940 // Sometimes kernel wakes us up just a tiny bit earlier than asked 979 // Sometimes kernel wakes us up just a tiny bit earlier than asked
941 // Do not go to very short sleep in this case 980 // Do not go to very short sleep in this case
942 if (rem < (unsigned)G.delta / 128) { 981 if (rem < (unsigned)G.delta / 128) {
@@ -944,6 +983,7 @@ int nmeter_main(int argc UNUSED_PARAM, char **argv)
944 } 983 }
945 usleep(rem); 984 usleep(rem);
946 } 985 }
986 gettimeofday(&G.tv, NULL);
947 } 987 }
948 988
949 /*return 0;*/ 989 /*return 0;*/