1 /* resource.cc: getrusage () and friends.
3 Copyright 1996, 1997, 1998, 2000, 2001, 2002, 2009, 2010, 2011 Red Hat, Inc.
5 Written by Steve Chamberlain (sac@cygnus.com), Doug Evans (dje@cygnus.com),
6 Geoffrey Noer (noer@cygnus.com) of Cygnus Support.
7 Rewritten by Sergey S. Okhapkin (sos@prospect.com.ru)
9 This file is part of Cygwin.
11 This software is a copyrighted work licensed under the terms of the
12 Cygwin license. Please consult the file "CYGWIN_LICENSE" for
17 #include <sys/param.h>
28 /* add timeval values */
30 add_timeval (struct timeval *tv1, struct timeval *tv2)
32 tv1->tv_sec += tv2->tv_sec;
33 tv1->tv_usec += tv2->tv_usec;
34 if (tv1->tv_usec >= 1000000)
36 tv1->tv_usec -= 1000000;
41 /* add rusage values of r2 to r1 */
43 add_rusage (struct rusage *r1, struct rusage *r2)
45 add_timeval (&r1->ru_utime, &r2->ru_utime);
46 add_timeval (&r1->ru_stime, &r2->ru_stime);
47 r1->ru_maxrss += r2->ru_maxrss;
48 r1->ru_ixrss += r2->ru_ixrss;
49 r1->ru_idrss += r2->ru_idrss;
50 r1->ru_isrss += r2->ru_isrss;
51 r1->ru_minflt += r2->ru_minflt;
52 r1->ru_majflt += r2->ru_majflt;
53 r1->ru_nswap += r2->ru_nswap;
54 r1->ru_inblock += r2->ru_inblock;
55 r1->ru_oublock += r2->ru_oublock;
56 r1->ru_msgsnd += r2->ru_msgsnd;
57 r1->ru_msgrcv += r2->ru_msgrcv;
58 r1->ru_nsignals += r2->ru_nsignals;
59 r1->ru_nvcsw += r2->ru_nvcsw;
60 r1->ru_nivcsw += r2->ru_nivcsw;
63 /* FIXME: what about other fields? */
65 fill_rusage (struct rusage *r, HANDLE h)
67 FILETIME creation_time = {0,0};
68 FILETIME exit_time = {0,0};
69 FILETIME kernel_time = {0,0};
70 FILETIME user_time = {0,0};
74 memset (r, 0, sizeof (*r));
75 GetProcessTimes (h, &creation_time, &exit_time, &kernel_time, &user_time);
76 totimeval (&tv, &kernel_time, 0, 0);
77 add_timeval (&r->ru_stime, &tv);
78 totimeval (&tv, &user_time, 0, 0);
79 add_timeval (&r->ru_utime, &tv);
82 NTSTATUS status = NtQueryInformationProcess (h, ProcessVmCounters, &vmc,
84 if (NT_SUCCESS (status))
86 r->ru_maxrss += (long) (vmc.WorkingSetSize / 1024);
87 r->ru_majflt += vmc.PageFaultCount;
92 getrusage (int intwho, struct rusage *rusage_in)
97 if (intwho == RUSAGE_SELF)
99 memset (&r, 0, sizeof (r));
100 fill_rusage (&r, GetCurrentProcess ());
103 else if (intwho == RUSAGE_CHILDREN)
104 *rusage_in = myself->rusage_children;
111 syscall_printf ("%R = getrusage(%d, %p)", res, intwho, rusage_in);
116 getrlimit (int resource, struct rlimit *rlp)
118 MEMORY_BASIC_INFORMATION m;
121 if (efault.faulted (EFAULT))
124 rlp->rlim_cur = RLIM_INFINITY;
125 rlp->rlim_max = RLIM_INFINITY;
135 if (!VirtualQuery ((LPCVOID) &m, &m, sizeof m))
136 debug_printf ("couldn't get stack info, returning def.values. %E");
139 rlp->rlim_cur = (DWORD) &m - (DWORD) m.AllocationBase;
140 rlp->rlim_max = (DWORD) m.BaseAddress + m.RegionSize
141 - (DWORD) m.AllocationBase;
145 rlp->rlim_cur = getdtablesize ();
146 if (rlp->rlim_cur < OPEN_MAX)
147 rlp->rlim_cur = OPEN_MAX;
148 rlp->rlim_max = OPEN_MAX_MAX;
151 rlp->rlim_cur = cygheap->rlim_core;
161 setrlimit (int resource, const struct rlimit *rlp)
164 if (efault.faulted (EFAULT))
167 struct rlimit oldlimits;
169 // Check if the request is to actually change the resource settings.
170 // If it does not result in a change, take no action and do not
172 if (getrlimit (resource, &oldlimits) < 0)
175 if (oldlimits.rlim_cur == rlp->rlim_cur &&
176 oldlimits.rlim_max == rlp->rlim_max)
177 // No change in resource requirements, succeed immediately
183 cygheap->rlim_core = rlp->rlim_cur;
186 if (rlp->rlim_cur != RLIM_INFINITY)
187 return setdtablesize (rlp->rlim_cur);