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

Cameron Esfahani posted 1 patch 2 years, 2 months ago
Test checkpatch passed
Patches applied successfully (tree, apply log)
git fetch https://github.com/patchew-project/qemu tags/patchew/20220128001251.45165-1-dirty@apple.com
Maintainers: Laurent Vivier <laurent@vivier.eu>
linux-user/main.c    | 14 ++++++++++++++
linux-user/qemu.h    |  3 +++
linux-user/syscall.c |  3 +++
3 files changed, 20 insertions(+)
[PATCH v3] linux-user: Implement starttime field in self stat emulation
Posted by Cameron Esfahani 2 years, 2 months ago
Instead of always returning 0, return actual starttime.

v3: Fix formatting issues
v2: Use clock_gettime() instead of scanning /proc/self/stat

Signed-off-by: Cameron Esfahani <dirty@apple.com>
---
 linux-user/main.c    | 14 ++++++++++++++
 linux-user/qemu.h    |  3 +++
 linux-user/syscall.c |  3 +++
 3 files changed, 20 insertions(+)

diff --git a/linux-user/main.c b/linux-user/main.c
index 16def5215d..fbc9bcfd5f 100644
--- a/linux-user/main.c
+++ b/linux-user/main.c
@@ -190,12 +190,26 @@ void stop_all_tasks(void)
 /* Assumes contents are already zeroed.  */
 void init_task_state(TaskState *ts)
 {
+    long ticks_per_sec;
+    struct timespec bt;
+
     ts->used = 1;
     ts->sigaltstack_used = (struct target_sigaltstack) {
         .ss_sp = 0,
         .ss_size = 0,
         .ss_flags = TARGET_SS_DISABLE,
     };
+
+    /* Capture task start time relative to system boot */
+
+    ticks_per_sec = sysconf(_SC_CLK_TCK);
+
+    if ((ticks_per_sec > 0) && !clock_gettime(CLOCK_BOOTTIME, &bt)) {
+        /* start_boottime is expressed in clock ticks */
+        ts->start_boottime = bt.tv_sec * (uint64_t) ticks_per_sec;
+        ts->start_boottime += bt.tv_nsec * (uint64_t) ticks_per_sec /
+                              NANOSECONDS_PER_SECOND;
+    }
 }
 
 CPUArchState *cpu_copy(CPUArchState *env)
diff --git a/linux-user/qemu.h b/linux-user/qemu.h
index 7910ce59cc..106175406a 100644
--- a/linux-user/qemu.h
+++ b/linux-user/qemu.h
@@ -158,6 +158,9 @@ typedef struct TaskState {
 
     /* This thread's sigaltstack, if it has one */
     struct target_sigaltstack sigaltstack_used;
+
+    /* Start time of task after system boot in clock ticks */
+    uint64_t start_boottime;
 } __attribute__((aligned(16))) TaskState;
 
 abi_long do_brk(abi_ulong new_brk);
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 5950222a77..7b3dbc72d4 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -8107,6 +8107,9 @@ 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 */
+            g_string_printf(buf, "%" PRIu64 " ", ts->start_boottime);
         } else if (i == 27) {
             /* stack bottom */
             g_string_printf(buf, TARGET_ABI_FMT_ld " ", ts->info->start_stack);
-- 
2.32.0 (Apple Git-131)


Re: [PATCH v3] linux-user: Implement starttime field in self stat emulation
Posted by Laurent Vivier 2 years, 2 months ago
Le 28/01/2022 à 01:12, Cameron Esfahani a écrit :
> Instead of always returning 0, return actual starttime.
> 
> v3: Fix formatting issues
> v2: Use clock_gettime() instead of scanning /proc/self/stat

For your next contribution: move version information after the "---" to not clutter the commit message.

Applied to my linux-user-for-7.0 branch.

Thanks,
Laurent

> 
> Signed-off-by: Cameron Esfahani <dirty@apple.com>
> ---


>   linux-user/main.c    | 14 ++++++++++++++
>   linux-user/qemu.h    |  3 +++
>   linux-user/syscall.c |  3 +++
>   3 files changed, 20 insertions(+)
> 
> diff --git a/linux-user/main.c b/linux-user/main.c
> index 16def5215d..fbc9bcfd5f 100644
> --- a/linux-user/main.c
> +++ b/linux-user/main.c
> @@ -190,12 +190,26 @@ void stop_all_tasks(void)
>   /* Assumes contents are already zeroed.  */
>   void init_task_state(TaskState *ts)
>   {
> +    long ticks_per_sec;
> +    struct timespec bt;
> +
>       ts->used = 1;
>       ts->sigaltstack_used = (struct target_sigaltstack) {
>           .ss_sp = 0,
>           .ss_size = 0,
>           .ss_flags = TARGET_SS_DISABLE,
>       };
> +
> +    /* Capture task start time relative to system boot */
> +
> +    ticks_per_sec = sysconf(_SC_CLK_TCK);
> +
> +    if ((ticks_per_sec > 0) && !clock_gettime(CLOCK_BOOTTIME, &bt)) {
> +        /* start_boottime is expressed in clock ticks */
> +        ts->start_boottime = bt.tv_sec * (uint64_t) ticks_per_sec;
> +        ts->start_boottime += bt.tv_nsec * (uint64_t) ticks_per_sec /
> +                              NANOSECONDS_PER_SECOND;
> +    }
>   }
>   
>   CPUArchState *cpu_copy(CPUArchState *env)
> diff --git a/linux-user/qemu.h b/linux-user/qemu.h
> index 7910ce59cc..106175406a 100644
> --- a/linux-user/qemu.h
> +++ b/linux-user/qemu.h
> @@ -158,6 +158,9 @@ typedef struct TaskState {
>   
>       /* This thread's sigaltstack, if it has one */
>       struct target_sigaltstack sigaltstack_used;
> +
> +    /* Start time of task after system boot in clock ticks */
> +    uint64_t start_boottime;
>   } __attribute__((aligned(16))) TaskState;
>   
>   abi_long do_brk(abi_ulong new_brk);
> diff --git a/linux-user/syscall.c b/linux-user/syscall.c
> index 5950222a77..7b3dbc72d4 100644
> --- a/linux-user/syscall.c
> +++ b/linux-user/syscall.c
> @@ -8107,6 +8107,9 @@ 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 */
> +            g_string_printf(buf, "%" PRIu64 " ", ts->start_boottime);
>           } else if (i == 27) {
>               /* stack bottom */
>               g_string_printf(buf, TARGET_ABI_FMT_ld " ", ts->info->start_stack);


Re: [PATCH v3] linux-user: Implement starttime field in self stat emulation
Posted by Laurent Vivier 2 years, 2 months ago
Le 28/01/2022 à 01:12, Cameron Esfahani a écrit :
> Instead of always returning 0, return actual starttime.
> 
> v3: Fix formatting issues
> v2: Use clock_gettime() instead of scanning /proc/self/stat
> 
> Signed-off-by: Cameron Esfahani <dirty@apple.com>
> ---
>   linux-user/main.c    | 14 ++++++++++++++
>   linux-user/qemu.h    |  3 +++
>   linux-user/syscall.c |  3 +++
>   3 files changed, 20 insertions(+)
> 
> diff --git a/linux-user/main.c b/linux-user/main.c
> index 16def5215d..fbc9bcfd5f 100644
> --- a/linux-user/main.c
> +++ b/linux-user/main.c
> @@ -190,12 +190,26 @@ void stop_all_tasks(void)
>   /* Assumes contents are already zeroed.  */
>   void init_task_state(TaskState *ts)
>   {
> +    long ticks_per_sec;
> +    struct timespec bt;
> +
>       ts->used = 1;
>       ts->sigaltstack_used = (struct target_sigaltstack) {
>           .ss_sp = 0,
>           .ss_size = 0,
>           .ss_flags = TARGET_SS_DISABLE,
>       };
> +
> +    /* Capture task start time relative to system boot */
> +
> +    ticks_per_sec = sysconf(_SC_CLK_TCK);
> +
> +    if ((ticks_per_sec > 0) && !clock_gettime(CLOCK_BOOTTIME, &bt)) {
> +        /* start_boottime is expressed in clock ticks */
> +        ts->start_boottime = bt.tv_sec * (uint64_t) ticks_per_sec;
> +        ts->start_boottime += bt.tv_nsec * (uint64_t) ticks_per_sec /
> +                              NANOSECONDS_PER_SECOND;
> +    }
>   }
>   
>   CPUArchState *cpu_copy(CPUArchState *env)
> diff --git a/linux-user/qemu.h b/linux-user/qemu.h
> index 7910ce59cc..106175406a 100644
> --- a/linux-user/qemu.h
> +++ b/linux-user/qemu.h
> @@ -158,6 +158,9 @@ typedef struct TaskState {
>   
>       /* This thread's sigaltstack, if it has one */
>       struct target_sigaltstack sigaltstack_used;
> +
> +    /* Start time of task after system boot in clock ticks */
> +    uint64_t start_boottime;
>   } __attribute__((aligned(16))) TaskState;
>   
>   abi_long do_brk(abi_ulong new_brk);
> diff --git a/linux-user/syscall.c b/linux-user/syscall.c
> index 5950222a77..7b3dbc72d4 100644
> --- a/linux-user/syscall.c
> +++ b/linux-user/syscall.c
> @@ -8107,6 +8107,9 @@ 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 */
> +            g_string_printf(buf, "%" PRIu64 " ", ts->start_boottime);
>           } else if (i == 27) {
>               /* stack bottom */
>               g_string_printf(buf, TARGET_ABI_FMT_ld " ", ts->info->start_stack);

Reviewed-by: Laurent Vivier <laurent@vivier.eu>