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>
This commit is contained in:
parent
5da5365d3c
commit
1fd8e66203
105
procps/ps.c
105
procps/ps.c
@ -145,12 +145,6 @@ static unsigned long get_uptime(void)
|
||||
#endif
|
||||
|
||||
#if ENABLE_DESKTOP
|
||||
|
||||
#include <sys/times.h> /* for times() */
|
||||
#ifndef AT_CLKTCK
|
||||
# define AT_CLKTCK 17
|
||||
#endif
|
||||
|
||||
/* TODO:
|
||||
* http://pubs.opengroup.org/onlinepubs/9699919799/utilities/ps.html
|
||||
* specifies (for XSI-conformant systems) following default columns
|
||||
@ -187,7 +181,9 @@ struct globals {
|
||||
char *buffer;
|
||||
unsigned terminal_width;
|
||||
#if ENABLE_FEATURE_PS_TIME
|
||||
# if ENABLE_FEATURE_PS_UNUSUAL_SYSTEMS || !defined(__linux__)
|
||||
unsigned kernel_HZ;
|
||||
# endif
|
||||
unsigned long seconds_since_boot;
|
||||
#endif
|
||||
} FIX_ALIASING;
|
||||
@ -198,92 +194,15 @@ struct globals {
|
||||
#define need_flags (G.need_flags )
|
||||
#define buffer (G.buffer )
|
||||
#define terminal_width (G.terminal_width )
|
||||
#define kernel_HZ (G.kernel_HZ )
|
||||
#define INIT_G() do { setup_common_bufsiz(); } while (0)
|
||||
|
||||
#if ENABLE_FEATURE_PS_TIME
|
||||
/* for ELF executables, notes are pushed before environment and args */
|
||||
/* try "LD_SHOW_AUXV=1 /bin/true" */
|
||||
static uintptr_t find_elf_note(uintptr_t findme)
|
||||
{
|
||||
uintptr_t *ep = (uintptr_t *) environ;
|
||||
|
||||
while (*ep++)
|
||||
continue;
|
||||
while (*ep) {
|
||||
if (ep[0] == findme) {
|
||||
return ep[1];
|
||||
}
|
||||
ep += 2;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
# if ENABLE_FEATURE_PS_UNUSUAL_SYSTEMS
|
||||
static unsigned get_HZ_by_waiting(void)
|
||||
{
|
||||
struct timeval tv1, tv2;
|
||||
unsigned t1, t2, r, hz;
|
||||
unsigned cnt = cnt; /* for compiler */
|
||||
int diff;
|
||||
|
||||
r = 0;
|
||||
|
||||
/* Wait for times() to reach new tick */
|
||||
t1 = times(NULL);
|
||||
do {
|
||||
t2 = times(NULL);
|
||||
} while (t2 == t1);
|
||||
gettimeofday(&tv2, NULL);
|
||||
|
||||
do {
|
||||
t1 = t2;
|
||||
tv1.tv_usec = tv2.tv_usec;
|
||||
|
||||
/* Wait exactly one times() tick */
|
||||
do {
|
||||
t2 = times(NULL);
|
||||
} while (t2 == t1);
|
||||
gettimeofday(&tv2, NULL);
|
||||
|
||||
/* Calculate ticks per sec, rounding up to even */
|
||||
diff = tv2.tv_usec - tv1.tv_usec;
|
||||
if (diff <= 0) diff += 1000000;
|
||||
hz = 1000000u / (unsigned)diff;
|
||||
hz = (hz+1) & ~1;
|
||||
|
||||
/* Count how many same hz values we saw */
|
||||
if (r != hz) {
|
||||
r = hz;
|
||||
cnt = 0;
|
||||
}
|
||||
cnt++;
|
||||
} while (cnt < 3); /* exit if saw 3 same values */
|
||||
|
||||
return r;
|
||||
}
|
||||
# if ENABLE_FEATURE_PS_UNUSUAL_SYSTEMS || !defined(__linux__)
|
||||
# define get_kernel_HZ() (G.kernel_HZ)
|
||||
# else
|
||||
static inline unsigned get_HZ_by_waiting(void)
|
||||
{
|
||||
/* Better method? */
|
||||
return 100;
|
||||
}
|
||||
/* non-ancient Linux standardized on 100 for "times" freq */
|
||||
# define get_kernel_HZ() ((unsigned)100)
|
||||
# endif
|
||||
|
||||
static unsigned get_kernel_HZ(void)
|
||||
{
|
||||
if (kernel_HZ)
|
||||
return kernel_HZ;
|
||||
|
||||
/* Works for ELF only, Linux 2.4.0+ */
|
||||
kernel_HZ = find_elf_note(AT_CLKTCK);
|
||||
if (kernel_HZ == (unsigned)-1)
|
||||
kernel_HZ = get_HZ_by_waiting();
|
||||
|
||||
G.seconds_since_boot = get_uptime();
|
||||
|
||||
return kernel_HZ;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* 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)
|
||||
}
|
||||
|
||||
#if ENABLE_FEATURE_PS_ADDITIONAL_COLUMNS
|
||||
|
||||
static void func_rgroup(char *buf, int size, const procps_status_t *ps)
|
||||
{
|
||||
safe_strncpy(buf, get_cached_groupname(ps->rgid), size+1);
|
||||
}
|
||||
|
||||
static void func_ruser(char *buf, int size, const procps_status_t *ps)
|
||||
{
|
||||
safe_strncpy(buf, get_cached_username(ps->ruid), size+1);
|
||||
}
|
||||
|
||||
static void func_nice(char *buf, int size, const procps_status_t *ps)
|
||||
{
|
||||
sprintf(buf, "%*d", size, ps->niceness);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if ENABLE_FEATURE_PS_TIME
|
||||
|
||||
static void func_etime(char *buf, int size, const procps_status_t *ps)
|
||||
{
|
||||
/* 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)
|
||||
unsigned ss;
|
||||
|
||||
mm = ps->start_time / get_kernel_HZ();
|
||||
/* must be after get_kernel_HZ()! */
|
||||
mm = G.seconds_since_boot - mm;
|
||||
ss = mm % 60;
|
||||
mm /= 60;
|
||||
snprintf(buf, size+1, "%3lu:%02u", mm, ss);
|
||||
}
|
||||
|
||||
static void func_time(char *buf, int size, const procps_status_t *ps)
|
||||
{
|
||||
/* 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)
|
||||
mm /= 60;
|
||||
snprintf(buf, size+1, "%3lu:%02u", mm, ss);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if ENABLE_SELINUX
|
||||
@ -627,6 +538,10 @@ int ps_main(int argc UNUSED_PARAM, char **argv)
|
||||
};
|
||||
|
||||
INIT_G();
|
||||
G.seconds_since_boot = get_uptime();
|
||||
#if ENABLE_FEATURE_PS_TIME && (ENABLE_FEATURE_PS_UNUSUAL_SYSTEMS || !defined(__linux__))
|
||||
G.kernel_HZ = bb_clk_tck(); /* this is sysconf(_SC_CLK_TCK) */
|
||||
#endif
|
||||
|
||||
// POSIX:
|
||||
// -a Write information for all processes associated with terminals
|
||||
|
Loading…
Reference in New Issue
Block a user