summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/sysdep.c124
-rw-r--r--src/systime.h1
-rw-r--r--src/timefns.c2
3 files changed, 49 insertions, 78 deletions
diff --git a/src/sysdep.c b/src/sysdep.c
index c9101f94818..a266307588c 100644
--- a/src/sysdep.c
+++ b/src/sysdep.c
@@ -3177,70 +3177,45 @@ make_lisp_timeval (long sec, long usec)
#endif
#ifdef GNU_LINUX
-static struct timespec
-time_from_jiffies (unsigned long long tval, long hz)
-{
- unsigned long long s = tval / hz;
- unsigned long long frac = tval % hz;
- int ns;
-
- if (TYPE_MAXIMUM (time_t) < s)
- time_overflow ();
- if (LONG_MAX - 1 <= ULLONG_MAX / TIMESPEC_HZ
- || frac <= ULLONG_MAX / TIMESPEC_HZ)
- ns = frac * TIMESPEC_HZ / hz;
- else
- {
- /* This is reachable only in the unlikely case that HZ * HZ
- exceeds ULLONG_MAX. It calculates an approximation that is
- guaranteed to be in range. */
- long hz_per_ns = hz / TIMESPEC_HZ + (hz % TIMESPEC_HZ != 0);
- ns = frac / hz_per_ns;
- }
- return make_timespec (s, ns);
+static Lisp_Object
+time_from_jiffies (unsigned long long ticks, Lisp_Object hz, Lisp_Object form)
+{
+ return Ftime_convert (Fcons (make_uint (ticks), hz), form);
}
static Lisp_Object
-ltime_from_jiffies (unsigned long long tval, long hz)
+put_jiffies (Lisp_Object attrs, Lisp_Object propname,
+ unsigned long long ticks, Lisp_Object hz)
{
- struct timespec t = time_from_jiffies (tval, hz);
- return make_lisp_time (t);
+ return Fcons (Fcons (propname, time_from_jiffies (ticks, hz, Qnil)), attrs);
}
-static struct timespec
+static Lisp_Object
get_up_time (void)
{
FILE *fup;
- struct timespec up = make_timespec (0, 0);
+ Lisp_Object up = Qnil;
block_input ();
fup = emacs_fopen ("/proc/uptime", "r");
if (fup)
{
- unsigned long long upsec, upfrac;
+ unsigned long long upsec;
+ EMACS_UINT upfrac;
int upfrac_start, upfrac_end;
- if (fscanf (fup, "%llu.%n%llu%n",
+ if (fscanf (fup, "%llu.%n%"pI"u%n",
&upsec, &upfrac_start, &upfrac, &upfrac_end)
== 2)
{
- if (TYPE_MAXIMUM (time_t) < upsec)
- {
- upsec = TYPE_MAXIMUM (time_t);
- upfrac = TIMESPEC_HZ - 1;
- }
- else
- {
- int upfraclen = upfrac_end - upfrac_start;
- for (; upfraclen < LOG10_TIMESPEC_HZ; upfraclen++)
- upfrac *= 10;
- for (; LOG10_TIMESPEC_HZ < upfraclen; upfraclen--)
- upfrac /= 10;
- upfrac = min (upfrac, TIMESPEC_HZ - 1);
- }
- up = make_timespec (upsec, upfrac);
+ EMACS_INT hz = 1;
+ for (int i = upfrac_start; i < upfrac_end; i++)
+ hz *= 10;
+ Lisp_Object sec = make_uint (upsec);
+ Lisp_Object subsec = Fcons (make_fixnum (upfrac), make_fixnum (hz));
+ up = Ftime_add (sec, subsec);
}
fclose (fup);
}
@@ -3361,7 +3336,6 @@ system_process_attributes (Lisp_Object pid)
unsigned long long u_time, s_time, cutime, cstime, start;
long priority, niceness, rss;
unsigned long minflt, majflt, cminflt, cmajflt, vsize;
- struct timespec tnow, tstart, tboot, telapsed, us_time;
double pcpu, pmem;
Lisp_Object attrs = Qnil;
Lisp_Object decoded_cmd;
@@ -3449,45 +3423,41 @@ system_process_attributes (Lisp_Object pid)
attrs = Fcons (Fcons (Qmajflt, INT_TO_INTEGER (majflt)), attrs);
attrs = Fcons (Fcons (Qcminflt, INT_TO_INTEGER (cminflt)), attrs);
attrs = Fcons (Fcons (Qcmajflt, INT_TO_INTEGER (cmajflt)), attrs);
+
clocks_per_sec = sysconf (_SC_CLK_TCK);
- if (clocks_per_sec < 0)
- clocks_per_sec = 100;
- attrs = Fcons (Fcons (Qutime,
- ltime_from_jiffies (u_time, clocks_per_sec)),
- attrs);
- attrs = Fcons (Fcons (Qstime,
- ltime_from_jiffies (s_time, clocks_per_sec)),
- attrs);
- attrs = Fcons (Fcons (Qtime,
- ltime_from_jiffies (s_time + u_time,
- clocks_per_sec)),
- attrs);
- attrs = Fcons (Fcons (Qcutime,
- ltime_from_jiffies (cutime, clocks_per_sec)),
- attrs);
- attrs = Fcons (Fcons (Qcstime,
- ltime_from_jiffies (cstime, clocks_per_sec)),
- attrs);
- attrs = Fcons (Fcons (Qctime,
- ltime_from_jiffies (cstime + cutime,
- clocks_per_sec)),
- attrs);
+ if (0 < clocks_per_sec)
+ {
+ Lisp_Object hz = make_int (clocks_per_sec);
+ attrs = put_jiffies (attrs, Qutime, u_time, hz);
+ attrs = put_jiffies (attrs, Qstime, s_time, hz);
+ attrs = put_jiffies (attrs, Qtime, s_time + u_time, hz);
+ attrs = put_jiffies (attrs, Qcutime, cutime, hz);
+ attrs = put_jiffies (attrs, Qcstime, cstime, hz);
+ attrs = put_jiffies (attrs, Qctime, cstime + cutime, hz);
+
+ Lisp_Object uptime = get_up_time ();
+ if (!NILP (uptime))
+ {
+ Lisp_Object now = Ftime_convert (Qnil, hz);
+ Lisp_Object boot = Ftime_subtract (now, uptime);
+ Lisp_Object tstart = time_from_jiffies (start, hz, hz);
+ Lisp_Object lstart =
+ Ftime_convert (Ftime_add (boot, tstart), Qnil);
+ attrs = Fcons (Fcons (Qstart, lstart), attrs);
+ Lisp_Object etime =
+ Ftime_convert (Ftime_subtract (uptime, tstart), Qnil);
+ attrs = Fcons (Fcons (Qetime, etime), attrs);
+ pcpu = (100.0 * (s_time + u_time)
+ / (clocks_per_sec * float_time (etime)));
+ attrs = Fcons (Fcons (Qpcpu, make_float (pcpu)), attrs);
+ }
+ }
+
attrs = Fcons (Fcons (Qpri, make_fixnum (priority)), attrs);
attrs = Fcons (Fcons (Qnice, make_fixnum (niceness)), attrs);
attrs = Fcons (Fcons (Qthcount, INT_TO_INTEGER (thcount)), attrs);
- tnow = current_timespec ();
- telapsed = get_up_time ();
- tboot = timespec_sub (tnow, telapsed);
- tstart = time_from_jiffies (start, clocks_per_sec);
- tstart = timespec_add (tboot, tstart);
- attrs = Fcons (Fcons (Qstart, make_lisp_time (tstart)), attrs);
attrs = Fcons (Fcons (Qvsize, INT_TO_INTEGER (vsize / 1024)), attrs);
attrs = Fcons (Fcons (Qrss, INT_TO_INTEGER (4 * rss)), attrs);
- telapsed = timespec_sub (tnow, tstart);
- attrs = Fcons (Fcons (Qetime, make_lisp_time (telapsed)), attrs);
- us_time = time_from_jiffies (u_time + s_time, clocks_per_sec);
- pcpu = timespectod (us_time) / timespectod (telapsed);
- attrs = Fcons (Fcons (Qpcpu, make_float (100 * pcpu)), attrs);
pmem = 4.0 * 100 * rss / procfs_get_total_memory ();
if (pmem > 100)
pmem = 100;
diff --git a/src/systime.h b/src/systime.h
index f3b1b2394da..41d728f1c29 100644
--- a/src/systime.h
+++ b/src/systime.h
@@ -92,6 +92,7 @@ extern bool list4_to_timespec (Lisp_Object, Lisp_Object, Lisp_Object,
Lisp_Object, struct timespec *);
extern struct timespec lisp_time_argument (Lisp_Object);
extern AVOID time_overflow (void);
+extern double float_time (Lisp_Object);
extern void init_timefns (void);
extern void syms_of_timefns (void);
diff --git a/src/timefns.c b/src/timefns.c
index 795a6484ce9..9b5b090ba71 100644
--- a/src/timefns.c
+++ b/src/timefns.c
@@ -881,7 +881,7 @@ decode_lisp_time (Lisp_Object specified_time, bool decode_secs_only,
/* Convert a Lisp timestamp SPECIFIED_TIME to double.
Signal an error if unsuccessful. */
-static double
+double
float_time (Lisp_Object specified_time)
{
double t;