This is the mail archive of the
libc-alpha@sourceware.org
mailing list for the glibc project.
[RFC v6 05/23] linux: Use 32-bit time_t for rusage
- From: Alistair Francis <alistair dot francis at wdc dot com>
- To: libc-alpha at sourceware dot org
- Cc: arnd at arndb dot de, adhemerval dot zanella at linaro dot org, fweimer at redhat dot com, joseph at codesourcery dot com, palmerdabbelt at google dot com, macro at wdc dot com, zongbox at gmail dot com, alistair dot francis at wdc dot com, alistair23 at gmail dot com
- Date: Sun, 12 Jan 2020 02:33:44 -0800
- Subject: [RFC v6 05/23] linux: Use 32-bit time_t for rusage
- Ironport-sdr: fzYyemELIG211TuIhtb9Mzsf26hdmx5tczo2PusgSZmyU8o8hDkdkX99v4KXdlTXs9Lsy6V0c9 9hpcYeutx1igfDRr18Z3YXct4i7HCP5+EVJZPe3cCEevZBOA7RMJKzB+WLl+2Hh8pMPAYh4b2f UyhmfKCvNl5rzOEBZcmfmiBLsXVuIsrmMO1HHGAeD/QARjiBKNPPrXIXgpUA1DZ/ZWgvFzThNP 1PkI5a0Og4IZr9xl8u8v/sxwu1jtPnJRJ5teVmyDuerDc4phUIR66+BozfApM209uolChGUCNY okM=
- Ironport-sdr: sRG3aJ1UHq5cRGAexh9VEpv7eJpce+88g8inmvyJLtsVFRSp0TwQ9dTWDWyGWw5KRgKTNQkWEV 4q8iq2i1k3bKnhVcq581oD+z/vG1MxCZegpbqCCtN0+An2napBGLB1k1C2/H2x5MLV2YuCXxyb Zh03QvGWiqK73rUFqu4bBSpAbMOY6pJ46xpnqWY/k6JBhKKSC/taF4t4mmsUYi0uaD/Gl8b1CR hZWJ1xrTwKZzdKMwlKY/21wjE045u0G/Xdl3TMxTbRHXZiTfGUpQGWGHvk7t9aeVZjMwBGyr5v sOBEf5f6ff/+ZoQ3jYvfKP9s
- Ironport-sdr: 0eOuWRa2Oy6fR2UBuc05BSg9xNhDSHQQMcNAEC39871+kFz7rvIO2DMF2lO11BNjXQL5z6tYUD dtlrgyY9KffUJ/aIBN7j22jCGUhGtKjqlkYQ4nsSNJ7ONl2dqZFM8TlQW0A0HJqkMq2M/jFoXp m/qGVt7R2C7cT9++hUiQXuH6P1ukcfTp0BV2lUMUHnfAm76JruAxuFZCfzcTiMS2S8dZveX6EW I9fAA1XLRoLEsDs5hf16UcT/JVmv4yVAlrHWL8eTViTy5iRDvZ0ImCZ8tgD1NAPvFNdjQhFR2u V/4=
- References: <cover.1578824547.git.alistair.francis@wdc.com>
- Wdcironportexception: Internal
The Linux kernel expects rusage to use a 32-bit time_t, even on archs
with a 64-bit time_t (like RV32). To address this let's convert
rusage to/from 32-bit and 64-bit to ensure the kernel always gets
a 32-bit time_t.
This means that all 32-bit architectures with a 64-bit time_t will be
able to use this generic implementation.
This code is bsaed on similar code in alpha, but adjusted to pass the
32-bit time_t to the kernel.
We can't directly call __wait4 as it expects a structrusage but we have
to pass in and use a struct rusage32. The same appies to __getrusage.
---
.../linux/generic/wordsize-32/getrusage.c | 39 +++++++++
.../linux/generic/wordsize-32/tv32-compat.h | 47 +++++++++++
.../sysv/linux/generic/wordsize-32/wait4.c | 79 +++++++++++++++++++
3 files changed, 165 insertions(+)
create mode 100644 sysdeps/unix/sysv/linux/generic/wordsize-32/getrusage.c
create mode 100644 sysdeps/unix/sysv/linux/generic/wordsize-32/wait4.c
diff --git a/sysdeps/unix/sysv/linux/generic/wordsize-32/getrusage.c b/sysdeps/unix/sysv/linux/generic/wordsize-32/getrusage.c
new file mode 100644
index 0000000000..2ada94a954
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/generic/wordsize-32/getrusage.c
@@ -0,0 +1,39 @@
+/* utimes -- change file timestamps. Linux/RV32/tv32 version.
+ Copyright (C) 2020 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <sys/time.h>
+#include <sys/resource.h>
+#include <sysdep.h>
+#include <tv32-compat.h>
+
+int
+__getrusage (int who, struct rusage *usage)
+{
+#if __TIMESIZE == 64
+ struct rusage32 usage32;
+ if (INLINE_SYSCALL_CALL (getrusage, who, &usage32) == -1)
+ return -1;
+
+ rusage32_to_rusage64 (&usage32, usage);
+ return 0;
+#else
+ return INLINE_SYSCALL_CALL (getrusage, who, usage);
+#endif
+}
+
+strong_alias (__getrusage, getrusage)
diff --git a/sysdeps/unix/sysv/linux/generic/wordsize-32/tv32-compat.h b/sysdeps/unix/sysv/linux/generic/wordsize-32/tv32-compat.h
index aa960a6632..8a4bd15002 100644
--- a/sysdeps/unix/sysv/linux/generic/wordsize-32/tv32-compat.h
+++ b/sysdeps/unix/sysv/linux/generic/wordsize-32/tv32-compat.h
@@ -24,6 +24,7 @@
#include <bits/types.h>
#include <bits/types/time_t.h>
#include <bits/types/struct_timeval.h>
+#include <bits/types/struct_rusage.h>
/* Structures containing 'struct timeval' with 32-bit time_t. */
struct itimerval32
@@ -32,4 +33,50 @@ struct itimerval32
struct __timeval_long it_value;
};
+struct rusage32
+{
+ struct __timeval_long ru_utime; /* user time used */
+ struct __timeval_long ru_stime; /* system time used */
+ long ru_maxrss; /* maximum resident set size */
+ long ru_ixrss; /* integral shared memory size */
+ long ru_idrss; /* integral unshared data size */
+ long ru_isrss; /* integral unshared stack size */
+ long ru_minflt; /* page reclaims */
+ long ru_majflt; /* page faults */
+ long ru_nswap; /* swaps */
+ long ru_inblock; /* block input operations */
+ long ru_oublock; /* block output operations */
+ long ru_msgsnd; /* messages sent */
+ long ru_msgrcv; /* messages received */
+ long ru_nsignals; /* signals received */
+ long ru_nvcsw; /* voluntary context switches */
+ long ru_nivcsw; /* involuntary " */
+};
+
+static inline void
+rusage32_to_rusage64 (const struct rusage32 *restrict r32,
+ struct rusage *restrict r64)
+{
+ /* Make sure the entire output structure is cleared, including
+ padding and reserved fields. */
+ memset (r64, 0, sizeof *r64);
+
+ r64->ru_utime = valid_timeval_long_to_timeval64 (r32->ru_utime);
+ r64->ru_stime = valid_timeval_long_to_timeval64 (r32->ru_stime);
+ r64->ru_maxrss = r32->ru_maxrss;
+ r64->ru_ixrss = r32->ru_ixrss;
+ r64->ru_idrss = r32->ru_idrss;
+ r64->ru_isrss = r32->ru_isrss;
+ r64->ru_minflt = r32->ru_minflt;
+ r64->ru_majflt = r32->ru_majflt;
+ r64->ru_nswap = r32->ru_nswap;
+ r64->ru_inblock = r32->ru_inblock;
+ r64->ru_oublock = r32->ru_oublock;
+ r64->ru_msgsnd = r32->ru_msgsnd;
+ r64->ru_msgrcv = r32->ru_msgrcv;
+ r64->ru_nsignals = r32->ru_nsignals;
+ r64->ru_nvcsw = r32->ru_nvcsw;
+ r64->ru_nivcsw = r32->ru_nivcsw;
+}
+
#endif /* tv32-compat.h */
diff --git a/sysdeps/unix/sysv/linux/generic/wordsize-32/wait4.c b/sysdeps/unix/sysv/linux/generic/wordsize-32/wait4.c
new file mode 100644
index 0000000000..a4a81a0587
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/generic/wordsize-32/wait4.c
@@ -0,0 +1,79 @@
+/* wait4 -- wait for process to change state. Linux/RV32/tv32 version.
+ Copyright (C) 2020 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <sys/wait.h>
+#include <sys/resource.h>
+#include <sysdep-cancel.h>
+#include <tv32-compat.h>
+
+pid_t
+__wait4 (pid_t pid, int *stat_loc, int options, struct rusage *usage)
+{
+ struct rusage32 usage32;
+ idtype_t idtype = P_PID;
+
+ if (pid < -1)
+ {
+ idtype = P_PGID;
+ pid *= -1;
+ }
+ else if (pid == -1)
+ idtype = P_ALL;
+ else if (pid == 0)
+ idtype = P_PGID;
+
+ options |= WEXITED;
+
+ siginfo_t infop;
+ if (SYSCALL_CANCEL (waitid, idtype, pid, &infop, options, &usage32) < 0)
+ return -1;
+
+ if (stat_loc)
+ {
+ switch (infop.si_code)
+ {
+ case CLD_EXITED:
+ *stat_loc = W_EXITCODE (infop.si_status, 0);
+ break;
+ case CLD_DUMPED:
+ *stat_loc = WCOREFLAG | infop.si_status;
+ break;
+ case CLD_KILLED:
+ *stat_loc = infop.si_status;
+ break;
+ case CLD_TRAPPED:
+ case CLD_STOPPED:
+ *stat_loc = W_STOPCODE (infop.si_status);
+ break;
+ case CLD_CONTINUED:
+ *stat_loc = __W_CONTINUED;
+ break;
+ default:
+ *stat_loc = 0;
+ break;
+ }
+ }
+
+ if (usage != NULL)
+ rusage32_to_rusage64 (&usage32, usage);
+
+ return infop.si_pid;
+}
+
+libc_hidden_def (__wait4);
+weak_alias (__wait4, wait4)
--
2.24.1