diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2017-08-10 14:10:56 +0200 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2017-08-10 14:10:56 +0200 |
commit | 1fd8e66203906f6e245959de1bc293556e6ab7fa (patch) | |
tree | 0a70e15cfabd7cce793694bfde566f674040313c | |
parent | 5da5365d3caeba421331132518abb0abb78ff20e (diff) | |
download | busybox-w32-1fd8e66203906f6e245959de1bc293556e6ab7fa.tar.gz busybox-w32-1fd8e66203906f6e245959de1bc293556e6ab7fa.tar.bz2 busybox-w32-1fd8e66203906f6e245959de1bc293556e6ab7fa.zip |
ps: stop using AT_CLKTCK, there are more standard ways
function old new delta
ps_main 537 558 +21
func_time 66 59 -7
get_kernel_HZ 102 - -102
------------------------------------------------------------------------------
(add/remove: 0/1 grow/shrink: 1/1 up/down: 21/-109) Total: -88 bytes
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r-- | procps/ps.c | 105 |
1 files changed, 10 insertions, 95 deletions
diff --git a/procps/ps.c b/procps/ps.c index e004d25bb..fab8c81eb 100644 --- a/procps/ps.c +++ b/procps/ps.c | |||
@@ -145,12 +145,6 @@ static unsigned long get_uptime(void) | |||
145 | #endif | 145 | #endif |
146 | 146 | ||
147 | #if ENABLE_DESKTOP | 147 | #if ENABLE_DESKTOP |
148 | |||
149 | #include <sys/times.h> /* for times() */ | ||
150 | #ifndef AT_CLKTCK | ||
151 | # define AT_CLKTCK 17 | ||
152 | #endif | ||
153 | |||
154 | /* TODO: | 148 | /* TODO: |
155 | * http://pubs.opengroup.org/onlinepubs/9699919799/utilities/ps.html | 149 | * http://pubs.opengroup.org/onlinepubs/9699919799/utilities/ps.html |
156 | * specifies (for XSI-conformant systems) following default columns | 150 | * specifies (for XSI-conformant systems) following default columns |
@@ -187,7 +181,9 @@ struct globals { | |||
187 | char *buffer; | 181 | char *buffer; |
188 | unsigned terminal_width; | 182 | unsigned terminal_width; |
189 | #if ENABLE_FEATURE_PS_TIME | 183 | #if ENABLE_FEATURE_PS_TIME |
184 | # if ENABLE_FEATURE_PS_UNUSUAL_SYSTEMS || !defined(__linux__) | ||
190 | unsigned kernel_HZ; | 185 | unsigned kernel_HZ; |
186 | # endif | ||
191 | unsigned long seconds_since_boot; | 187 | unsigned long seconds_since_boot; |
192 | #endif | 188 | #endif |
193 | } FIX_ALIASING; | 189 | } FIX_ALIASING; |
@@ -198,92 +194,15 @@ struct globals { | |||
198 | #define need_flags (G.need_flags ) | 194 | #define need_flags (G.need_flags ) |
199 | #define buffer (G.buffer ) | 195 | #define buffer (G.buffer ) |
200 | #define terminal_width (G.terminal_width ) | 196 | #define terminal_width (G.terminal_width ) |
201 | #define kernel_HZ (G.kernel_HZ ) | ||
202 | #define INIT_G() do { setup_common_bufsiz(); } while (0) | 197 | #define INIT_G() do { setup_common_bufsiz(); } while (0) |
203 | 198 | ||
204 | #if ENABLE_FEATURE_PS_TIME | 199 | #if ENABLE_FEATURE_PS_TIME |
205 | /* for ELF executables, notes are pushed before environment and args */ | 200 | # if ENABLE_FEATURE_PS_UNUSUAL_SYSTEMS || !defined(__linux__) |
206 | /* try "LD_SHOW_AUXV=1 /bin/true" */ | 201 | # define get_kernel_HZ() (G.kernel_HZ) |
207 | static uintptr_t find_elf_note(uintptr_t findme) | ||
208 | { | ||
209 | uintptr_t *ep = (uintptr_t *) environ; | ||
210 | |||
211 | while (*ep++) | ||
212 | continue; | ||
213 | while (*ep) { | ||
214 | if (ep[0] == findme) { | ||
215 | return ep[1]; | ||
216 | } | ||
217 | ep += 2; | ||
218 | } | ||
219 | return -1; | ||
220 | } | ||
221 | |||
222 | # if ENABLE_FEATURE_PS_UNUSUAL_SYSTEMS | ||
223 | static unsigned get_HZ_by_waiting(void) | ||
224 | { | ||
225 | struct timeval tv1, tv2; | ||
226 | unsigned t1, t2, r, hz; | ||
227 | unsigned cnt = cnt; /* for compiler */ | ||
228 | int diff; | ||
229 | |||
230 | r = 0; | ||
231 | |||
232 | /* Wait for times() to reach new tick */ | ||
233 | t1 = times(NULL); | ||
234 | do { | ||
235 | t2 = times(NULL); | ||
236 | } while (t2 == t1); | ||
237 | gettimeofday(&tv2, NULL); | ||
238 | |||
239 | do { | ||
240 | t1 = t2; | ||
241 | tv1.tv_usec = tv2.tv_usec; | ||
242 | |||
243 | /* Wait exactly one times() tick */ | ||
244 | do { | ||
245 | t2 = times(NULL); | ||
246 | } while (t2 == t1); | ||
247 | gettimeofday(&tv2, NULL); | ||
248 | |||
249 | /* Calculate ticks per sec, rounding up to even */ | ||
250 | diff = tv2.tv_usec - tv1.tv_usec; | ||
251 | if (diff <= 0) diff += 1000000; | ||
252 | hz = 1000000u / (unsigned)diff; | ||
253 | hz = (hz+1) & ~1; | ||
254 | |||
255 | /* Count how many same hz values we saw */ | ||
256 | if (r != hz) { | ||
257 | r = hz; | ||
258 | cnt = 0; | ||
259 | } | ||
260 | cnt++; | ||
261 | } while (cnt < 3); /* exit if saw 3 same values */ | ||
262 | |||
263 | return r; | ||
264 | } | ||
265 | # else | 202 | # else |
266 | static inline unsigned get_HZ_by_waiting(void) | 203 | /* non-ancient Linux standardized on 100 for "times" freq */ |
267 | { | 204 | # define get_kernel_HZ() ((unsigned)100) |
268 | /* Better method? */ | ||
269 | return 100; | ||
270 | } | ||
271 | # endif | 205 | # endif |
272 | |||
273 | static unsigned get_kernel_HZ(void) | ||
274 | { | ||
275 | if (kernel_HZ) | ||
276 | return kernel_HZ; | ||
277 | |||
278 | /* Works for ELF only, Linux 2.4.0+ */ | ||
279 | kernel_HZ = find_elf_note(AT_CLKTCK); | ||
280 | if (kernel_HZ == (unsigned)-1) | ||
281 | kernel_HZ = get_HZ_by_waiting(); | ||
282 | |||
283 | G.seconds_since_boot = get_uptime(); | ||
284 | |||
285 | return kernel_HZ; | ||
286 | } | ||
287 | #endif | 206 | #endif |
288 | 207 | ||
289 | /* Print value to buf, max size+1 chars (including trailing '\0') */ | 208 | /* Print value to buf, max size+1 chars (including trailing '\0') */ |
@@ -375,26 +294,21 @@ static void func_tty(char *buf, int size, const procps_status_t *ps) | |||
375 | } | 294 | } |
376 | 295 | ||
377 | #if ENABLE_FEATURE_PS_ADDITIONAL_COLUMNS | 296 | #if ENABLE_FEATURE_PS_ADDITIONAL_COLUMNS |
378 | |||
379 | static void func_rgroup(char *buf, int size, const procps_status_t *ps) | 297 | static void func_rgroup(char *buf, int size, const procps_status_t *ps) |
380 | { | 298 | { |
381 | safe_strncpy(buf, get_cached_groupname(ps->rgid), size+1); | 299 | safe_strncpy(buf, get_cached_groupname(ps->rgid), size+1); |
382 | } | 300 | } |
383 | |||
384 | static void func_ruser(char *buf, int size, const procps_status_t *ps) | 301 | static void func_ruser(char *buf, int size, const procps_status_t *ps) |
385 | { | 302 | { |
386 | safe_strncpy(buf, get_cached_username(ps->ruid), size+1); | 303 | safe_strncpy(buf, get_cached_username(ps->ruid), size+1); |
387 | } | 304 | } |
388 | |||
389 | static void func_nice(char *buf, int size, const procps_status_t *ps) | 305 | static void func_nice(char *buf, int size, const procps_status_t *ps) |
390 | { | 306 | { |
391 | sprintf(buf, "%*d", size, ps->niceness); | 307 | sprintf(buf, "%*d", size, ps->niceness); |
392 | } | 308 | } |
393 | |||
394 | #endif | 309 | #endif |
395 | 310 | ||
396 | #if ENABLE_FEATURE_PS_TIME | 311 | #if ENABLE_FEATURE_PS_TIME |
397 | |||
398 | static void func_etime(char *buf, int size, const procps_status_t *ps) | 312 | static void func_etime(char *buf, int size, const procps_status_t *ps) |
399 | { | 313 | { |
400 | /* elapsed time [[dd-]hh:]mm:ss; here only mm:ss */ | 314 | /* elapsed time [[dd-]hh:]mm:ss; here only mm:ss */ |
@@ -402,13 +316,11 @@ static void func_etime(char *buf, int size, const procps_status_t *ps) | |||
402 | unsigned ss; | 316 | unsigned ss; |
403 | 317 | ||
404 | mm = ps->start_time / get_kernel_HZ(); | 318 | mm = ps->start_time / get_kernel_HZ(); |
405 | /* must be after get_kernel_HZ()! */ | ||
406 | mm = G.seconds_since_boot - mm; | 319 | mm = G.seconds_since_boot - mm; |
407 | ss = mm % 60; | 320 | ss = mm % 60; |
408 | mm /= 60; | 321 | mm /= 60; |
409 | snprintf(buf, size+1, "%3lu:%02u", mm, ss); | 322 | snprintf(buf, size+1, "%3lu:%02u", mm, ss); |
410 | } | 323 | } |
411 | |||
412 | static void func_time(char *buf, int size, const procps_status_t *ps) | 324 | static void func_time(char *buf, int size, const procps_status_t *ps) |
413 | { | 325 | { |
414 | /* cumulative time [[dd-]hh:]mm:ss; here only mm:ss */ | 326 | /* cumulative time [[dd-]hh:]mm:ss; here only mm:ss */ |
@@ -420,7 +332,6 @@ static void func_time(char *buf, int size, const procps_status_t *ps) | |||
420 | mm /= 60; | 332 | mm /= 60; |
421 | snprintf(buf, size+1, "%3lu:%02u", mm, ss); | 333 | snprintf(buf, size+1, "%3lu:%02u", mm, ss); |
422 | } | 334 | } |
423 | |||
424 | #endif | 335 | #endif |
425 | 336 | ||
426 | #if ENABLE_SELINUX | 337 | #if ENABLE_SELINUX |
@@ -627,6 +538,10 @@ int ps_main(int argc UNUSED_PARAM, char **argv) | |||
627 | }; | 538 | }; |
628 | 539 | ||
629 | INIT_G(); | 540 | INIT_G(); |
541 | G.seconds_since_boot = get_uptime(); | ||
542 | #if ENABLE_FEATURE_PS_TIME && (ENABLE_FEATURE_PS_UNUSUAL_SYSTEMS || !defined(__linux__)) | ||
543 | G.kernel_HZ = bb_clk_tck(); /* this is sysconf(_SC_CLK_TCK) */ | ||
544 | #endif | ||
630 | 545 | ||
631 | // POSIX: | 546 | // POSIX: |
632 | // -a Write information for all processes associated with terminals | 547 | // -a Write information for all processes associated with terminals |