1 /* Copyright (C) 1991-2022 Free Software Foundation, Inc.
2    This file is part of the GNU C Library.
3 
4    The GNU C Library is free software; you can redistribute it and/or
5    modify it under the terms of the GNU Lesser General Public
6    License as published by the Free Software Foundation; either
7    version 2.1 of the License, or (at your option) any later version.
8 
9    The GNU C Library is distributed in the hope that it will be useful,
10    but WITHOUT ANY WARRANTY; without even the implied warranty of
11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12    Lesser General Public License for more details.
13 
14    You should have received a copy of the GNU Lesser General Public
15    License along with the GNU C Library; if not, see
16    <https://www.gnu.org/licenses/>.  */
17 
18 #include <stddef.h>
19 #include <sys/resource.h>
20 #include <shlib-compat.h>
21 
22 #if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_33)
23 
24 /* Granularity of the `vm_utime' and `vm_stime' fields of a `struct vtimes'.
25    (This is the frequency of the machine's power supply, in Hz.)  */
26 # define VTIMES_UNITS_PER_SECOND 60
27 
28 struct vtimes
29 {
30   /* User time used in units of 1/VTIMES_UNITS_PER_SECOND seconds.  */
31   int vm_utime;
32   /* System time used in units of 1/VTIMES_UNITS_PER_SECOND seconds.  */
33   int vm_stime;
34 
35   /* Amount of data and stack memory used (kilobyte-seconds).  */
36   unsigned int vm_idsrss;
37   /* Amount of text memory used (kilobyte-seconds).  */
38   unsigned int vm_ixrss;
39   /* Maximum resident set size (text, data, and stack) (kilobytes).  */
40   int vm_maxrss;
41 
42   /* Number of hard page faults (i.e. those that required I/O).  */
43   int vm_majflt;
44   /* Number of soft page faults (i.e. those serviced by reclaiming
45      a page from the list of pages awaiting reallocation.  */
46   int vm_minflt;
47 
48   /* Number of times a process was swapped out of physical memory.  */
49   int vm_nswap;
50 
51   /* Number of input operations via the file system.  Note: This
52      and `ru_oublock' do not include operations with the cache.  */
53   int vm_inblk;
54   /* Number of output operations via the file system.  */
55   int vm_oublk;
56 };
57 
58 /* Return the number of 1/VTIMES_UNITS_PER_SECOND-second
59    units in the `struct timeval' TV.  */
60 # define TIMEVAL_TO_VTIMES(tv) \
61   ((tv.tv_sec * VTIMES_UNITS_PER_SECOND) \
62    + (tv.tv_usec * VTIMES_UNITS_PER_SECOND / 1000000))
63 
64 /* If VT is not NULL, write statistics for WHO into *VT.
65    Return 0 for success, -1 for failure.  */
66 static int
vtimes_one(struct vtimes * vt,enum __rusage_who who)67 vtimes_one (struct vtimes *vt, enum __rusage_who who)
68 {
69   if (vt != NULL)
70     {
71       struct rusage usage;
72 
73       if (__getrusage (who, &usage) < 0)
74 	return -1;
75 
76       vt->vm_utime = TIMEVAL_TO_VTIMES (usage.ru_utime);
77       vt->vm_stime = TIMEVAL_TO_VTIMES (usage.ru_stime);
78       vt->vm_idsrss = usage.ru_idrss + usage.ru_isrss;
79       vt->vm_majflt = usage.ru_majflt;
80       vt->vm_minflt = usage.ru_minflt;
81       vt->vm_nswap = usage.ru_nswap;
82       vt->vm_inblk = usage.ru_inblock;
83       vt->vm_oublk = usage.ru_oublock;
84     }
85   return 0;
86 }
87 
88 /* If CURRENT is not NULL, write statistics for the current process into
89    *CURRENT.  If CHILD is not NULL, write statistics for all terminated child
90    processes into *CHILD.  Returns 0 for success, -1 for failure.  */
91 int
__vtimes(struct vtimes * current,struct vtimes * child)92 __vtimes (struct vtimes *current, struct vtimes *child)
93 {
94   if (vtimes_one (current, RUSAGE_SELF) < 0
95       || vtimes_one (child, RUSAGE_CHILDREN) < 0)
96     return -1;
97   return 0;
98 }
99 compat_symbol (libc, __vtimes, vtimes, GLIBC_2_0);
100 
101 #endif /* SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_33)  */
102