OSDN Git Service

Throughout, remove extra space after function name from debugging output.
[pf3gnuchains/pf3gnuchains4x.git] / winsup / cygwin / resource.cc
1 /* resource.cc: getrusage () and friends.
2
3    Copyright 1996, 1997, 1998, 2000, 2001, 2002, 2009, 2010, 2011 Red Hat, Inc.
4
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)
8
9 This file is part of Cygwin.
10
11 This software is a copyrighted work licensed under the terms of the
12 Cygwin license.  Please consult the file "CYGWIN_LICENSE" for
13 details. */
14
15 #include "winsup.h"
16 #include <unistd.h>
17 #include <sys/param.h>
18 #include "pinfo.h"
19 #include "psapi.h"
20 #include "cygtls.h"
21 #include "path.h"
22 #include "fhandler.h"
23 #include "pinfo.h"
24 #include "dtable.h"
25 #include "cygheap.h"
26 #include "ntdll.h"
27
28 /* add timeval values */
29 static void
30 add_timeval (struct timeval *tv1, struct timeval *tv2)
31 {
32   tv1->tv_sec += tv2->tv_sec;
33   tv1->tv_usec += tv2->tv_usec;
34   if (tv1->tv_usec >= 1000000)
35     {
36       tv1->tv_usec -= 1000000;
37       tv1->tv_sec++;
38     }
39 }
40
41 /* add rusage values of r2 to r1 */
42 void __stdcall
43 add_rusage (struct rusage *r1, struct rusage *r2)
44 {
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;
61 }
62
63 /* FIXME: what about other fields? */
64 void __stdcall
65 fill_rusage (struct rusage *r, HANDLE h)
66 {
67   FILETIME creation_time = {0,0};
68   FILETIME exit_time = {0,0};
69   FILETIME kernel_time = {0,0};
70   FILETIME user_time = {0,0};
71
72   struct timeval tv;
73
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);
80
81   VM_COUNTERS vmc;
82   NTSTATUS status = NtQueryInformationProcess (h, ProcessVmCounters, &vmc,
83                                                sizeof vmc, NULL);
84   if (NT_SUCCESS (status))
85     {
86       r->ru_maxrss += (long) (vmc.WorkingSetSize / 1024);
87       r->ru_majflt += vmc.PageFaultCount;
88     }
89 }
90
91 extern "C" int
92 getrusage (int intwho, struct rusage *rusage_in)
93 {
94   int res = 0;
95   struct rusage r;
96
97   if (intwho == RUSAGE_SELF)
98     {
99       memset (&r, 0, sizeof (r));
100       fill_rusage (&r, GetCurrentProcess ());
101       *rusage_in = r;
102     }
103   else if (intwho == RUSAGE_CHILDREN)
104     *rusage_in = myself->rusage_children;
105   else
106     {
107       set_errno (EINVAL);
108       res = -1;
109     }
110
111   syscall_printf ("%R = getrusage(%d, %p)", res, intwho, rusage_in);
112   return res;
113 }
114
115 extern "C" int
116 getrlimit (int resource, struct rlimit *rlp)
117 {
118   MEMORY_BASIC_INFORMATION m;
119
120   myfault efault;
121   if (efault.faulted (EFAULT))
122     return -1;
123
124   rlp->rlim_cur = RLIM_INFINITY;
125   rlp->rlim_max = RLIM_INFINITY;
126
127   switch (resource)
128     {
129     case RLIMIT_CPU:
130     case RLIMIT_FSIZE:
131     case RLIMIT_DATA:
132     case RLIMIT_AS:
133       break;
134     case RLIMIT_STACK:
135       if (!VirtualQuery ((LPCVOID) &m, &m, sizeof m))
136         debug_printf ("couldn't get stack info, returning def.values. %E");
137       else
138         {
139           rlp->rlim_cur = (DWORD) &m - (DWORD) m.AllocationBase;
140           rlp->rlim_max = (DWORD) m.BaseAddress + m.RegionSize
141                           - (DWORD) m.AllocationBase;
142         }
143       break;
144     case RLIMIT_NOFILE:
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;
149       break;
150     case RLIMIT_CORE:
151       rlp->rlim_cur = cygheap->rlim_core;
152       break;
153     default:
154       set_errno (EINVAL);
155       return -1;
156     }
157   return 0;
158 }
159
160 extern "C" int
161 setrlimit (int resource, const struct rlimit *rlp)
162 {
163   myfault efault;
164   if (efault.faulted (EFAULT))
165     return -1;
166
167   struct rlimit oldlimits;
168
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
171   // fail.
172   if (getrlimit (resource, &oldlimits) < 0)
173     return -1;
174
175   if (oldlimits.rlim_cur == rlp->rlim_cur &&
176       oldlimits.rlim_max == rlp->rlim_max)
177     // No change in resource requirements, succeed immediately
178     return 0;
179
180   switch (resource)
181     {
182     case RLIMIT_CORE:
183       cygheap->rlim_core = rlp->rlim_cur;
184       break;
185     case RLIMIT_NOFILE:
186       if (rlp->rlim_cur != RLIM_INFINITY)
187         return setdtablesize (rlp->rlim_cur);
188       break;
189     default:
190       set_errno (EINVAL);
191       return -1;
192     }
193   return 0;
194 }