Print this page
| Split |
Close |
| Expand all |
| Collapse all |
--- old/usr/src/uts/common/syscall/rusagesys.c
+++ new/usr/src/uts/common/syscall/rusagesys.c
1 1 /*
2 2 * CDDL HEADER START
3 3 *
4 4 * The contents of this file are subject to the terms of the
5 5 * Common Development and Distribution License (the "License").
6 6 * You may not use this file except in compliance with the License.
7 7 *
8 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 9 * or http://www.opensolaris.org/os/licensing.
10 10 * See the License for the specific language governing permissions
11 11 * and limitations under the License.
12 12 *
13 13 * When distributing Covered Code, include this CDDL HEADER in each
14 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 15 * If applicable, add the following below this CDDL HEADER, with the
16 16 * fields enclosed by brackets "[]" replaced with your own identifying
17 17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 18 *
19 19 * CDDL HEADER END
20 20 */
21 21 /*
22 22 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
23 23 * Use is subject to license terms.
24 24 * Copyright 2014 Joyent, Inc. All rights reserved.
25 25 */
26 26
27 27 /*
28 28 * Implement fast getrusage call
29 29 */
30 30
31 31 #include <sys/types.h>
32 32 #include <sys/systm.h>
33 33 #include <sys/time.h>
34 34 #include <sys/errno.h>
35 35 #include <sys/resource.h>
36 36 #include <sys/vm_usage.h>
37 37
38 38 static int
39 39 getrusage(void *user_rusage)
40 40 {
41 41 struct rusage r;
42 42 kthread_t *t = curthread;
43 43 proc_t *p = ttoproc(t);
44 44 hrtime_t snsecs, unsecs;
45 45 klwp_t *lwp;
46 46
47 47 bzero(&r, sizeof (struct rusage));
48 48
49 49 mutex_enter(&p->p_lock);
50 50
51 51 if (p->p_defunct > 0) {
52 52 r.ru_majflt = p->p_ru.majflt;
53 53 r.ru_minflt = p->p_ru.minflt;
54 54 r.ru_nswap = p->p_ru.nswap;
55 55 r.ru_inblock = p->p_ru.inblock;
56 56 r.ru_oublock = p->p_ru.oublock;
57 57 r.ru_msgsnd = p->p_ru.msgsnd;
58 58 r.ru_msgrcv = p->p_ru.msgrcv;
59 59 r.ru_nsignals = p->p_ru.nsignals;
60 60 r.ru_nvcsw = p->p_ru.nvcsw;
61 61 r.ru_nivcsw = p->p_ru.nivcsw;
62 62 }
63 63
64 64 unsecs = mstate_aggr_state(p, LMS_USER);
65 65 snsecs = mstate_aggr_state(p, LMS_SYSTEM);
66 66
67 67 do {
68 68 if (t->t_proc_flag & TP_LWPEXIT)
69 69 continue;
70 70
71 71 lwp = ttolwp(t);
72 72
73 73 r.ru_majflt += lwp->lwp_ru.majflt;
74 74 r.ru_minflt += lwp->lwp_ru.minflt;
75 75 r.ru_nswap += lwp->lwp_ru.nswap;
76 76 r.ru_inblock += lwp->lwp_ru.inblock;
77 77 r.ru_oublock += lwp->lwp_ru.oublock;
78 78 r.ru_msgsnd += lwp->lwp_ru.msgsnd;
79 79 r.ru_msgrcv += lwp->lwp_ru.msgrcv;
80 80 r.ru_nsignals += lwp->lwp_ru.nsignals;
81 81 r.ru_nvcsw += lwp->lwp_ru.nvcsw;
82 82 r.ru_nivcsw += lwp->lwp_ru.nivcsw;
83 83
84 84 } while ((t = t->t_forw) != curthread);
85 85
86 86 mutex_exit(&p->p_lock);
87 87
88 88 hrt2tv(unsecs, &r.ru_utime);
89 89 hrt2tv(snsecs, &r.ru_stime);
90 90
91 91 #ifdef _SYSCALL32_IMPL
92 92 if (get_udatamodel() == DATAMODEL_ILP32) {
93 93 struct rusage32 r32;
94 94
95 95 bzero(&r32, sizeof (struct rusage32));
96 96
97 97 r32.ru_utime.tv_sec = r.ru_utime.tv_sec;
98 98 r32.ru_utime.tv_usec = r.ru_utime.tv_usec;
99 99 r32.ru_stime.tv_sec = r.ru_stime.tv_sec;
100 100 r32.ru_stime.tv_usec = r.ru_stime.tv_usec;
101 101
102 102 r32.ru_majflt = (int32_t)r.ru_majflt;
103 103 r32.ru_minflt = (int32_t)r.ru_minflt;
104 104 r32.ru_nswap = (int32_t)r.ru_nswap;
105 105 r32.ru_inblock = (int32_t)r.ru_inblock;
106 106 r32.ru_oublock = (int32_t)r.ru_oublock;
107 107 r32.ru_msgsnd = (int32_t)r.ru_msgsnd;
108 108 r32.ru_msgrcv = (int32_t)r.ru_msgrcv;
109 109 r32.ru_nsignals = (int32_t)r.ru_nsignals;
110 110 r32.ru_nvcsw = (int32_t)r.ru_nvcsw;
111 111 r32.ru_nivcsw = (int32_t)r.ru_nivcsw;
112 112 if (copyout(&r32, user_rusage, sizeof (r32)) != 0)
113 113 return (set_errno(EFAULT));
114 114 } else
115 115 #endif /* _SYSCALL32_IMPL */
116 116
117 117 if (copyout(&r, user_rusage, sizeof (r)) != 0)
118 118 return (set_errno(EFAULT));
119 119
120 120 return (0);
121 121 }
122 122
123 123 static int
124 124 getrusage_chld(void *user_rusage)
125 125 {
126 126 struct rusage r;
127 127 kthread_t *t = curthread;
128 128 proc_t *p = ttoproc(t);
129 129 hrtime_t snsecs, unsecs;
130 130
131 131 bzero(&r, sizeof (struct rusage));
132 132
133 133 mutex_enter(&p->p_lock);
134 134
135 135 unsecs = p->p_cacct[LMS_USER];
136 136 snsecs = p->p_cacct[LMS_SYSTEM] + p->p_cacct[LMS_TRAP];
137 137
138 138 r.ru_majflt = p->p_cru.majflt;
139 139 r.ru_minflt = p->p_cru.minflt;
140 140 r.ru_nswap = p->p_cru.nswap;
141 141 r.ru_inblock = p->p_cru.inblock;
142 142 r.ru_oublock = p->p_cru.oublock;
143 143 r.ru_msgsnd = p->p_cru.msgsnd;
144 144 r.ru_msgrcv = p->p_cru.msgrcv;
145 145 r.ru_nsignals = p->p_cru.nsignals;
146 146 r.ru_nvcsw = p->p_cru.nvcsw;
147 147 r.ru_nivcsw = p->p_cru.nivcsw;
148 148
149 149 mutex_exit(&p->p_lock);
150 150
151 151 hrt2tv(unsecs, &r.ru_utime);
152 152 hrt2tv(snsecs, &r.ru_stime);
153 153 #ifdef _SYSCALL32_IMPL
154 154 if (get_udatamodel() == DATAMODEL_ILP32) {
155 155 struct rusage32 r32;
156 156
157 157 bzero(&r32, sizeof (struct rusage32));
158 158
159 159 r32.ru_utime.tv_sec = r.ru_utime.tv_sec;
160 160 r32.ru_utime.tv_usec = r.ru_utime.tv_usec;
161 161 r32.ru_stime.tv_sec = r.ru_stime.tv_sec;
162 162 r32.ru_stime.tv_usec = r.ru_stime.tv_usec;
163 163
164 164 r32.ru_majflt = (int32_t)r.ru_majflt;
165 165 r32.ru_minflt = (int32_t)r.ru_minflt;
166 166 r32.ru_nswap = (int32_t)r.ru_nswap;
167 167 r32.ru_inblock = (int32_t)r.ru_inblock;
168 168 r32.ru_oublock = (int32_t)r.ru_oublock;
169 169 r32.ru_msgsnd = (int32_t)r.ru_msgsnd;
170 170 r32.ru_msgrcv = (int32_t)r.ru_msgrcv;
171 171 r32.ru_nsignals = (int32_t)r.ru_nsignals;
172 172 r32.ru_nvcsw = (int32_t)r.ru_nvcsw;
173 173 r32.ru_nivcsw = (int32_t)r.ru_nivcsw;
174 174 if (copyout(&r32, user_rusage, sizeof (r32)) != 0)
175 175 return (set_errno(EFAULT));
176 176 } else
177 177 #endif /* _SYSCALL32_IMPL */
178 178
179 179 if (copyout(&r, user_rusage, sizeof (r)) != 0)
180 180 return (set_errno(EFAULT));
181 181
182 182 return (0);
183 183 }
184 184
185 185 static int
186 186 getrusage_lwp(void *user_rusage)
187 187 {
188 188 struct rusage r;
189 189 kthread_t *t = curthread;
190 190 klwp_t *lwp;
191 191 hrtime_t snsecs, unsecs;
192 192 struct mstate *ms;
193 193
194 194 bzero(&r, sizeof (struct rusage));
195 195
196 196 lwp = ttolwp(t);
197 197 ms = &lwp->lwp_mstate;
198 198 unsecs = ms->ms_acct[LMS_USER];
199 199 snsecs = ms->ms_acct[LMS_SYSTEM] + ms->ms_acct[LMS_TRAP];
200 200 scalehrtime(&unsecs);
201 201 scalehrtime(&snsecs);
202 202 r.ru_majflt = lwp->lwp_ru.majflt;
203 203 r.ru_minflt = lwp->lwp_ru.minflt;
204 204 r.ru_nswap = lwp->lwp_ru.nswap;
205 205 r.ru_inblock = lwp->lwp_ru.inblock;
206 206 r.ru_oublock = lwp->lwp_ru.oublock;
207 207 r.ru_msgsnd = lwp->lwp_ru.msgsnd;
208 208 r.ru_msgrcv = lwp->lwp_ru.msgrcv;
209 209 r.ru_nsignals = lwp->lwp_ru.nsignals;
210 210 r.ru_nvcsw = lwp->lwp_ru.nvcsw;
211 211 r.ru_nivcsw = lwp->lwp_ru.nivcsw;
212 212
213 213 hrt2tv(unsecs, &r.ru_utime);
214 214 hrt2tv(snsecs, &r.ru_stime);
215 215 #ifdef _SYSCALL32_IMPL
216 216 if (get_udatamodel() == DATAMODEL_ILP32) {
217 217 struct rusage32 r32;
218 218
219 219 bzero(&r32, sizeof (struct rusage32));
220 220
221 221 r32.ru_utime.tv_sec = r.ru_utime.tv_sec;
222 222 r32.ru_utime.tv_usec = r.ru_utime.tv_usec;
223 223 r32.ru_stime.tv_sec = r.ru_stime.tv_sec;
224 224 r32.ru_stime.tv_usec = r.ru_stime.tv_usec;
225 225
226 226 r32.ru_majflt = (int32_t)r.ru_majflt;
227 227 r32.ru_minflt = (int32_t)r.ru_minflt;
228 228 r32.ru_nswap = (int32_t)r.ru_nswap;
229 229 r32.ru_inblock = (int32_t)r.ru_inblock;
230 230 r32.ru_oublock = (int32_t)r.ru_oublock;
231 231 r32.ru_msgsnd = (int32_t)r.ru_msgsnd;
232 232 r32.ru_msgrcv = (int32_t)r.ru_msgrcv;
233 233 r32.ru_nsignals = (int32_t)r.ru_nsignals;
234 234 r32.ru_nvcsw = (int32_t)r.ru_nvcsw;
235 235 r32.ru_nivcsw = (int32_t)r.ru_nivcsw;
236 236 if (copyout(&r32, user_rusage, sizeof (r32)) != 0)
237 237 return (set_errno(EFAULT));
238 238 } else
239 239 #endif /* _SYSCALL32_IMPL */
240 240
241 241 if (copyout(&r, user_rusage, sizeof (r)) != 0)
242 242 return (set_errno(EFAULT));
243 243
244 244 return (0);
245 245 }
246 246
247 247 int
248 248 rusagesys(int code, void *arg1, void *arg2, void *arg3, void *arg4)
249 249 {
250 250 switch (code) {
251 251
252 252 case _RUSAGESYS_GETRUSAGE:
253 253 return (getrusage(arg1));
254 254 case _RUSAGESYS_GETRUSAGE_CHLD:
255 255 return (getrusage_chld(arg1));
256 256 case _RUSAGESYS_GETRUSAGE_LWP:
257 257 return (getrusage_lwp(arg1));
258 258 case _RUSAGESYS_GETVMUSAGE:
259 259 return (vm_getusage((uint_t)(uintptr_t)arg1, (time_t)arg2,
260 260 (vmusage_t *)arg3, (size_t *)arg4, 0));
261 261 case _RUSAGESYS_INVALMAP:
262 262 /*
263 263 * SPARC sfmmu hat does not support HAT_CURPROC_PGUNLOAD
264 264 * handling so callers on SPARC should get simple sync
265 265 * handling with invalidation to all processes.
266 266 */
267 267 #if defined(__sparc)
268 268 return (memcntl((caddr_t)arg2, (size_t)arg3, MC_SYNC,
269 269 (caddr_t)(MS_ASYNC | MS_INVALIDATE), 0, 0));
270 270 #else
271 271 return (vm_map_inval((pid_t)(uintptr_t)arg1, (caddr_t)arg2,
272 272 (size_t)arg3));
273 273 #endif
274 274 default:
275 275 return (set_errno(EINVAL));
276 276 }
277 277 }
|
↓ open down ↓ |
277 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX