qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [PATCH] linux-user: Implement starttime field in self stat emulation


From: Laurent Vivier
Subject: Re: [PATCH] linux-user: Implement starttime field in self stat emulation
Date: Tue, 25 Jan 2022 10:41:53 +0100
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:91.0) Gecko/20100101 Thunderbird/91.4.0

Le 25/01/2022 à 03:47, Cameron Esfahani a écrit :
Instead of always returning 0, return actual starttime.

Signed-off-by: Cameron Esfahani <dirty@apple.com>
---
  linux-user/syscall.c | 28 ++++++++++++++++++++++++++++
  1 file changed, 28 insertions(+)

diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 5950222a77..59265ab986 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -8107,6 +8107,34 @@ static int open_self_stat(void *cpu_env, int fd)
          } else if (i == 3) {
              /* ppid */
              g_string_printf(buf, FMT_pid " ", getppid());
+        } else if (i == 21) { > +            /* starttime */
+            FILE *fp = NULL;
+            char *line = NULL;
+            char *skipped_comm = NULL;
+            size_t n = 0;
+            unsigned long long starttime = 0;
+
+            fp = fopen("/proc/self/stat", "r");
+            if (fp) {
+                if (getdelim(&line, &n, '\0', fp) != -1) {
+                    /* Find end of comm field */
+                    skipped_comm = strrchr(line, ')');
+                    if (skipped_comm != NULL) {
+                        /* Skip over parenthesis and space */
+                        skipped_comm += 2;
+                        /* Scan starttime (field 20 after pid and comm) */
+                        (void) sscanf(skipped_comm, "%*c %*d %*d %*d %*d %*d "
+                                            "%*u %*u %*u %*u %*u %*u %*u %*d "
+                                            "%*d %*d %*d %*d %*d %llu",
+                                            &starttime);
+                    }
+                    free(line);
+                }
+                fclose(fp);
+            }
+
+            g_string_printf(buf, "%llu ", starttime);

According to the kernel code:

  start_time = nsec_to_clock_t(timens_add_boottime_ns(task->start_boottime));

(timens_add_boottime_ns() is to adjust time offset according to the namespace)
(nsec_to_clock_t() is "div_u64(x, NSEC_PER_SEC / USER_HZ);")

and

  p->start_boottime = ktime_get_boottime_ns();
...
  static inline u64 ktime_get_boottime_ns(void)
  {
          return ktime_to_ns(ktime_get_boottime());
  }
...
  /**
   * ktime_get_boottime - Returns monotonic time since boot in ktime_t format
   *
   * This is similar to CLOCK_MONTONIC/ktime_get, but also includes the
   * time spent in suspend.
   */
  static inline ktime_t ktime_get_boottime(void)
  {
          return ktime_get_with_offset(TK_OFFS_BOOT);
  }

So I think rather than scanning /proc/self/stat you could use clock_gettime(CLOCK_BOOTTIME, ...) to get the value.

https://linux.die.net/man/2/clock_gettime

CLOCK_BOOTTIME (since Linux 2.6.39; Linux-specific)

        Identical to CLOCK_MONOTONIC, except it also includes any time that the 
system is suspended.
        This allows applications to get a suspend-aware monotonic clock without 
having to deal with
        the complications of CLOCK_REALTIME, which may have discontinuities if 
the time is changed
        using settimeofday(2).

https://man7.org/linux/man-pages/man5/proc.5.html

   /proc/[pid]/stat
...
        (22) starttime  %llu

                The time the process started after system boot.  In
                kernels before Linux 2.6, this value was expressed
                in jiffies.  Since Linux 2.6, the value is
                expressed in clock ticks (divide by
                sysconf(_SC_CLK_TCK)).

                The format for this field was %lu before Linux 2.6.

          } else if (i == 27) {
              /* stack bottom */
              g_string_printf(buf, TARGET_ABI_FMT_ld " ", 
ts->info->start_stack);

Thanks,
Laurent



reply via email to

[Prev in Thread] Current Thread [Next in Thread]