aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2017-08-10 14:10:56 +0200
committerDenys Vlasenko <vda.linux@googlemail.com>2017-08-10 14:10:56 +0200
commit1fd8e66203906f6e245959de1bc293556e6ab7fa (patch)
tree0a70e15cfabd7cce793694bfde566f674040313c
parent5da5365d3caeba421331132518abb0abb78ff20e (diff)
downloadbusybox-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.c105
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)
207static 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
223static 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
266static 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
273static 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
379static void func_rgroup(char *buf, int size, const procps_status_t *ps) 297static 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
384static void func_ruser(char *buf, int size, const procps_status_t *ps) 301static 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
389static void func_nice(char *buf, int size, const procps_status_t *ps) 305static 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
398static void func_etime(char *buf, int size, const procps_status_t *ps) 312static 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
412static void func_time(char *buf, int size, const procps_status_t *ps) 324static 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