diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2020-06-10 15:37:39 +0200 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2020-06-10 15:37:39 +0200 |
commit | 4789c7cd8152fee53c176e569b022ec4013597a0 (patch) | |
tree | 0fc5d8198b3448d1a03b0e965863a3daa363ef8c | |
parent | 505eeae402a84dc5208986c5ad611f5e485cbe34 (diff) | |
download | busybox-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.c | 68 |
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; |
755 | S_STAT_END(time_stat) | 756 | S_STAT_END(time_stat) |
756 | 757 | ||
757 | static void FAST_FUNC collect_time(time_stat *s) | 758 | static 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 | ||
780 | static void FAST_FUNC collect_time(time_stat *s) | ||
781 | { | ||
782 | collect_tv(s, &G.tv, /*local:*/ 1); | ||
783 | } | ||
784 | |||
785 | static 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 | |||
776 | static s_stat* init_time(const char *param) | 805 | static 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 | ||
821 | static 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 | |||
792 | static void FAST_FUNC collect_info(s_stat *s) | 828 | static 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 | ||
802 | typedef s_stat* init_func(const char *param); | 838 | typedef s_stat* init_func(const char *param); |
803 | 839 | ||
804 | static const char options[] ALIGN1 = "ncmsfixptbr"; | 840 | static const char options[] ALIGN1 = "ncmsfixptTbr"; |
805 | static init_func *const init_functions[] = { | 841 | static 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;*/ |