1 /* 2 tickcount -- Display the kernel tick count (or any tick count passed as an 3 argument or as input) in human-readable format 4 5 This is public domain software 6 */ 7 8 #include <assert.h> 9 #include <stdio.h> 10 #include <stdlib.h> 11 #include <tchar.h> 12 #include <windows.h> 13 14 typedef __int64 int64_; 15 typedef unsigned __int64 uint64_; 16 17 #define TICKS_YEAR (TICKS_DAY * ((uint64_)365)) 18 #define TICKS_MONTH (TICKS_DAY * ((uint64_)30)) 19 #define TICKS_WEEK (TICKS_DAY * ((uint64_)7)) 20 #define TICKS_DAY (TICKS_HOUR * ((uint64_)24)) 21 #define TICKS_HOUR (TICKS_MINUTE * ((uint64_)60)) 22 #define TICKS_MINUTE (TICKS_SECOND * ((uint64_)60)) 23 #define TICKS_SECOND ((uint64_)1000) 24 25 #define SLICES_COUNT (sizeof(ticks_per_slice) / sizeof(ticks_per_slice[0])) 26 27 uint64_ ticks_per_slice[] = 28 { 29 TICKS_YEAR, 30 TICKS_MONTH, 31 TICKS_WEEK, 32 TICKS_DAY, 33 TICKS_HOUR, 34 TICKS_MINUTE, 35 TICKS_SECOND, 36 1 37 }; 38 39 _TCHAR * slice_names_singular[SLICES_COUNT] = 40 { 41 _T("year"), 42 _T("month"), 43 _T("week"), 44 _T("day"), 45 _T("hour"), 46 _T("minute"), 47 _T("second"), 48 _T("millisecond") 49 }; 50 51 _TCHAR * slice_names_plural[SLICES_COUNT] = 52 { 53 _T("years"), 54 _T("months"), 55 _T("weeks"), 56 _T("days"), 57 _T("hours"), 58 _T("minutes"), 59 _T("seconds"), 60 _T("milliseconds") 61 }; 62 63 void print_uptime 64 ( 65 uint64_ tickcount, 66 uint64_ prevsliceval, 67 _TCHAR * prevsliceunit, 68 int curslice 69 ) 70 { 71 uint64_ tick_cur = tickcount / ticks_per_slice[curslice]; 72 uint64_ tick_residual = tickcount % ticks_per_slice[curslice]; 73 74 assert(tick_cur <= (~((uint64_)0))); 75 76 if(tick_residual == 0) 77 { 78 /* the current slice is the last */ 79 80 if(prevsliceval == 0) 81 { 82 /* the current slice is the only */ 83 _tprintf 84 ( 85 _T("%u %s"), 86 (unsigned)tick_cur, 87 (tick_cur == 1 ? slice_names_singular : slice_names_plural)[curslice] 88 ); 89 } 90 else 91 { 92 /* the current slice is the last, and there's a previous slice */ 93 assert(prevsliceunit); 94 95 /* print the previous and the current slice, and terminate */ 96 _tprintf 97 ( 98 _T("%u %s %s %u %s"), 99 (unsigned)prevsliceval, 100 prevsliceunit, 101 _T("and"), 102 (unsigned)tick_cur, 103 (tick_cur == 1 ? slice_names_singular : slice_names_plural)[curslice] 104 ); 105 } 106 } 107 else if(tick_cur != 0) 108 { 109 /* the current slice is not the last, and non-zero */ 110 111 if(prevsliceval != 0) 112 { 113 /* there's a previous slice: print it */ 114 assert(prevsliceunit); 115 _tprintf(_T("%u %s, "), (unsigned)prevsliceval, prevsliceunit); 116 } 117 118 /* recursion on the next slice size, storing the current slice */ 119 print_uptime 120 ( 121 tick_residual, 122 tick_cur, 123 (tick_cur == 1 ? slice_names_singular : slice_names_plural)[curslice], 124 curslice + 1 125 ); 126 } 127 else 128 { 129 /* 130 the current slice is not the last, and zero: recursion, remembering the 131 previous non-zero slice 132 */ 133 print_uptime(tick_residual, prevsliceval, prevsliceunit, curslice + 1); 134 } 135 } 136 137 int parse_print(const _TCHAR * str) 138 { 139 int64_ tickcount; 140 141 tickcount = _ttoi64(str); 142 143 if(tickcount < 0) 144 tickcount = - tickcount; 145 else if(tickcount == 0) 146 return 1; 147 148 print_uptime(tickcount, 0, NULL, 0); 149 _puttc(_T('\n'), stdout); 150 151 return 0; 152 } 153 154 int _tmain(int argc, _TCHAR * argv[]) 155 { 156 int r; 157 158 if(argc <= 1) 159 { 160 print_uptime((uint64_)GetTickCount(), 0, NULL, 0); 161 _puttc(_T('\n'), stdout); 162 } 163 else if(argc == 2 && argv[1][0] == _T('-') && argv[1][1] == 0) 164 { 165 while(!feof(stdin)) 166 { 167 _TCHAR buf[23]; 168 _TCHAR * str; 169 170 str = _fgetts(buf, 22, stdin); 171 172 if(str == NULL) 173 return 0; 174 175 if((r = parse_print(str)) != 0) 176 return r; 177 } 178 } 179 else 180 { 181 int i; 182 183 for(i = 1; i < argc; ++ i) 184 if((r = parse_print(argv[i])) != 0) 185 return r; 186 } 187 188 return 0; 189 } 190