dmake: do not set MAKEFLAGS=k
[unleashed/tickless.git] / kernel / syscall / rusagesys.c
blob3e0e63f4c07451ac0d83395020aad1765cfd9009
1 /*
2 * CDDL HEADER START
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
19 * CDDL HEADER END
22 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
27 * Implement fast getrusage call
30 #include <sys/types.h>
31 #include <sys/systm.h>
32 #include <sys/time.h>
33 #include <sys/errno.h>
34 #include <sys/resource.h>
35 #include <sys/vm_usage.h>
37 static int
38 getrusage(void *user_rusage)
40 struct rusage r;
41 kthread_t *t = curthread;
42 proc_t *p = ttoproc(t);
43 hrtime_t snsecs, unsecs;
44 klwp_t *lwp;
46 bzero(&r, sizeof (struct rusage));
48 mutex_enter(&p->p_lock);
50 if (p->p_defunct > 0) {
51 r.ru_majflt = p->p_ru.majflt;
52 r.ru_minflt = p->p_ru.minflt;
53 r.ru_nswap = p->p_ru.nswap;
54 r.ru_inblock = p->p_ru.inblock;
55 r.ru_oublock = p->p_ru.oublock;
56 r.ru_msgsnd = p->p_ru.msgsnd;
57 r.ru_msgrcv = p->p_ru.msgrcv;
58 r.ru_nsignals = p->p_ru.nsignals;
59 r.ru_nvcsw = p->p_ru.nvcsw;
60 r.ru_nivcsw = p->p_ru.nivcsw;
63 unsecs = mstate_aggr_state(p, LMS_USER);
64 snsecs = mstate_aggr_state(p, LMS_SYSTEM);
66 do {
67 if (t->t_proc_flag & TP_LWPEXIT)
68 continue;
70 lwp = ttolwp(t);
72 r.ru_majflt += lwp->lwp_ru.majflt;
73 r.ru_minflt += lwp->lwp_ru.minflt;
74 r.ru_nswap += lwp->lwp_ru.nswap;
75 r.ru_inblock += lwp->lwp_ru.inblock;
76 r.ru_oublock += lwp->lwp_ru.oublock;
77 r.ru_msgsnd += lwp->lwp_ru.msgsnd;
78 r.ru_msgrcv += lwp->lwp_ru.msgrcv;
79 r.ru_nsignals += lwp->lwp_ru.nsignals;
80 r.ru_nvcsw += lwp->lwp_ru.nvcsw;
81 r.ru_nivcsw += lwp->lwp_ru.nivcsw;
83 } while ((t = t->t_forw) != curthread);
85 mutex_exit(&p->p_lock);
87 hrt2tv(unsecs, &r.ru_utime);
88 hrt2tv(snsecs, &r.ru_stime);
90 #ifdef _SYSCALL32_IMPL
91 if (get_udatamodel() == DATAMODEL_ILP32) {
92 struct rusage32 r32;
94 bzero(&r32, sizeof (struct rusage32));
96 r32.ru_utime.tv_sec = r.ru_utime.tv_sec;
97 r32.ru_utime.tv_usec = r.ru_utime.tv_usec;
98 r32.ru_stime.tv_sec = r.ru_stime.tv_sec;
99 r32.ru_stime.tv_usec = r.ru_stime.tv_usec;
101 r32.ru_majflt = (int32_t)r.ru_majflt;
102 r32.ru_minflt = (int32_t)r.ru_minflt;
103 r32.ru_nswap = (int32_t)r.ru_nswap;
104 r32.ru_inblock = (int32_t)r.ru_inblock;
105 r32.ru_oublock = (int32_t)r.ru_oublock;
106 r32.ru_msgsnd = (int32_t)r.ru_msgsnd;
107 r32.ru_msgrcv = (int32_t)r.ru_msgrcv;
108 r32.ru_nsignals = (int32_t)r.ru_nsignals;
109 r32.ru_nvcsw = (int32_t)r.ru_nvcsw;
110 r32.ru_nivcsw = (int32_t)r.ru_nivcsw;
111 if (copyout(&r32, user_rusage, sizeof (r32)) != 0)
112 return (set_errno(EFAULT));
113 } else
114 #endif /* _SYSCALL32_IMPL */
116 if (copyout(&r, user_rusage, sizeof (r)) != 0)
117 return (set_errno(EFAULT));
119 return (0);
122 static int
123 getrusage_chld(void *user_rusage)
125 struct rusage r;
126 kthread_t *t = curthread;
127 proc_t *p = ttoproc(t);
128 hrtime_t snsecs, unsecs;
130 bzero(&r, sizeof (struct rusage));
132 mutex_enter(&p->p_lock);
134 unsecs = p->p_cacct[LMS_USER];
135 snsecs = p->p_cacct[LMS_SYSTEM] + p->p_cacct[LMS_TRAP];
137 r.ru_majflt = p->p_cru.majflt;
138 r.ru_minflt = p->p_cru.minflt;
139 r.ru_nswap = p->p_cru.nswap;
140 r.ru_inblock = p->p_cru.inblock;
141 r.ru_oublock = p->p_cru.oublock;
142 r.ru_msgsnd = p->p_cru.msgsnd;
143 r.ru_msgrcv = p->p_cru.msgrcv;
144 r.ru_nsignals = p->p_cru.nsignals;
145 r.ru_nvcsw = p->p_cru.nvcsw;
146 r.ru_nivcsw = p->p_cru.nivcsw;
148 mutex_exit(&p->p_lock);
150 hrt2tv(unsecs, &r.ru_utime);
151 hrt2tv(snsecs, &r.ru_stime);
152 #ifdef _SYSCALL32_IMPL
153 if (get_udatamodel() == DATAMODEL_ILP32) {
154 struct rusage32 r32;
156 bzero(&r32, sizeof (struct rusage32));
158 r32.ru_utime.tv_sec = r.ru_utime.tv_sec;
159 r32.ru_utime.tv_usec = r.ru_utime.tv_usec;
160 r32.ru_stime.tv_sec = r.ru_stime.tv_sec;
161 r32.ru_stime.tv_usec = r.ru_stime.tv_usec;
163 r32.ru_majflt = (int32_t)r.ru_majflt;
164 r32.ru_minflt = (int32_t)r.ru_minflt;
165 r32.ru_nswap = (int32_t)r.ru_nswap;
166 r32.ru_inblock = (int32_t)r.ru_inblock;
167 r32.ru_oublock = (int32_t)r.ru_oublock;
168 r32.ru_msgsnd = (int32_t)r.ru_msgsnd;
169 r32.ru_msgrcv = (int32_t)r.ru_msgrcv;
170 r32.ru_nsignals = (int32_t)r.ru_nsignals;
171 r32.ru_nvcsw = (int32_t)r.ru_nvcsw;
172 r32.ru_nivcsw = (int32_t)r.ru_nivcsw;
173 if (copyout(&r32, user_rusage, sizeof (r32)) != 0)
174 return (set_errno(EFAULT));
175 } else
176 #endif /* _SYSCALL32_IMPL */
178 if (copyout(&r, user_rusage, sizeof (r)) != 0)
179 return (set_errno(EFAULT));
181 return (0);
184 static int
185 getrusage_lwp(void *user_rusage)
187 struct rusage r;
188 kthread_t *t = curthread;
189 klwp_t *lwp;
190 hrtime_t snsecs, unsecs;
191 struct mstate *ms;
193 bzero(&r, sizeof (struct rusage));
195 lwp = ttolwp(t);
196 ms = &lwp->lwp_mstate;
197 unsecs = ms->ms_acct[LMS_USER];
198 snsecs = ms->ms_acct[LMS_SYSTEM] + ms->ms_acct[LMS_TRAP];
199 scalehrtime(&unsecs);
200 scalehrtime(&snsecs);
201 r.ru_majflt = lwp->lwp_ru.majflt;
202 r.ru_minflt = lwp->lwp_ru.minflt;
203 r.ru_nswap = lwp->lwp_ru.nswap;
204 r.ru_inblock = lwp->lwp_ru.inblock;
205 r.ru_oublock = lwp->lwp_ru.oublock;
206 r.ru_msgsnd = lwp->lwp_ru.msgsnd;
207 r.ru_msgrcv = lwp->lwp_ru.msgrcv;
208 r.ru_nsignals = lwp->lwp_ru.nsignals;
209 r.ru_nvcsw = lwp->lwp_ru.nvcsw;
210 r.ru_nivcsw = lwp->lwp_ru.nivcsw;
212 hrt2tv(unsecs, &r.ru_utime);
213 hrt2tv(snsecs, &r.ru_stime);
214 #ifdef _SYSCALL32_IMPL
215 if (get_udatamodel() == DATAMODEL_ILP32) {
216 struct rusage32 r32;
218 bzero(&r32, sizeof (struct rusage32));
220 r32.ru_utime.tv_sec = r.ru_utime.tv_sec;
221 r32.ru_utime.tv_usec = r.ru_utime.tv_usec;
222 r32.ru_stime.tv_sec = r.ru_stime.tv_sec;
223 r32.ru_stime.tv_usec = r.ru_stime.tv_usec;
225 r32.ru_majflt = (int32_t)r.ru_majflt;
226 r32.ru_minflt = (int32_t)r.ru_minflt;
227 r32.ru_nswap = (int32_t)r.ru_nswap;
228 r32.ru_inblock = (int32_t)r.ru_inblock;
229 r32.ru_oublock = (int32_t)r.ru_oublock;
230 r32.ru_msgsnd = (int32_t)r.ru_msgsnd;
231 r32.ru_msgrcv = (int32_t)r.ru_msgrcv;
232 r32.ru_nsignals = (int32_t)r.ru_nsignals;
233 r32.ru_nvcsw = (int32_t)r.ru_nvcsw;
234 r32.ru_nivcsw = (int32_t)r.ru_nivcsw;
235 if (copyout(&r32, user_rusage, sizeof (r32)) != 0)
236 return (set_errno(EFAULT));
237 } else
238 #endif /* _SYSCALL32_IMPL */
240 if (copyout(&r, user_rusage, sizeof (r)) != 0)
241 return (set_errno(EFAULT));
243 return (0);
247 rusagesys(int code, void *arg1, void *arg2, void *arg3, void *arg4)
249 switch (code) {
251 case _RUSAGESYS_GETRUSAGE:
252 return (getrusage(arg1));
253 case _RUSAGESYS_GETRUSAGE_CHLD:
254 return (getrusage_chld(arg1));
255 case _RUSAGESYS_GETRUSAGE_LWP:
256 return (getrusage_lwp(arg1));
257 case _RUSAGESYS_GETVMUSAGE:
258 return (vm_getusage((uint_t)(uintptr_t)arg1, (time_t)arg2,
259 (vmusage_t *)arg3, (size_t *)arg4, 0));
260 default:
261 return (set_errno(EINVAL));