kern_time.c (225617) | kern_time.c (239347) |
---|---|
1/*- 2 * Copyright (c) 1982, 1986, 1989, 1993 3 * The Regents of the University of California. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 16 unchanged lines hidden (view full) --- 25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 * SUCH DAMAGE. 28 * 29 * @(#)kern_time.c 8.1 (Berkeley) 6/10/93 30 */ 31 32#include <sys/cdefs.h> | 1/*- 2 * Copyright (c) 1982, 1986, 1989, 1993 3 * The Regents of the University of California. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 16 unchanged lines hidden (view full) --- 25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 * SUCH DAMAGE. 28 * 29 * @(#)kern_time.c 8.1 (Berkeley) 6/10/93 30 */ 31 32#include <sys/cdefs.h> |
33__FBSDID("$FreeBSD: head/sys/kern/kern_time.c 225617 2011-09-16 13:58:51Z kmacy $"); | 33__FBSDID("$FreeBSD: head/sys/kern/kern_time.c 239347 2012-08-17 02:26:31Z davidxu $"); |
34 35#include <sys/param.h> 36#include <sys/systm.h> 37#include <sys/limits.h> 38#include <sys/clock.h> 39#include <sys/lock.h> 40#include <sys/mutex.h> 41#include <sys/sysproto.h> --- 11 unchanged lines hidden (view full) --- 53#include <sys/timers.h> 54#include <sys/timetc.h> 55#include <sys/vnode.h> 56 57#include <vm/vm.h> 58#include <vm/vm_extern.h> 59 60#define MAX_CLOCKS (CLOCK_MONOTONIC+1) | 34 35#include <sys/param.h> 36#include <sys/systm.h> 37#include <sys/limits.h> 38#include <sys/clock.h> 39#include <sys/lock.h> 40#include <sys/mutex.h> 41#include <sys/sysproto.h> --- 11 unchanged lines hidden (view full) --- 53#include <sys/timers.h> 54#include <sys/timetc.h> 55#include <sys/vnode.h> 56 57#include <vm/vm.h> 58#include <vm/vm_extern.h> 59 60#define MAX_CLOCKS (CLOCK_MONOTONIC+1) |
61#define CPUCLOCK_BIT 0x80000000 62#define CPUCLOCK_PROCESS_BIT 0x40000000 63#define CPUCLOCK_ID_MASK (~(CPUCLOCK_BIT|CPUCLOCK_PROCESS_BIT)) 64#define MAKE_THREAD_CPUCLOCK(tid) (CPUCLOCK_BIT|(tid)) 65#define MAKE_PROCESS_CPUCLOCK(pid) \ 66 (CPUCLOCK_BIT|CPUCLOCK_PROCESS_BIT|(pid)) |
|
61 62static struct kclock posix_clocks[MAX_CLOCKS]; 63static uma_zone_t itimer_zone = NULL; 64 65/* 66 * Time of day and interval timer support. 67 * 68 * These routines provide the kernel entry points to get and set --- 91 unchanged lines hidden (view full) --- 160 mtx_lock(&Giant); 161 tc_setclock(&ts); 162 resettodr(); 163 mtx_unlock(&Giant); 164 return (0); 165} 166 167#ifndef _SYS_SYSPROTO_H_ | 67 68static struct kclock posix_clocks[MAX_CLOCKS]; 69static uma_zone_t itimer_zone = NULL; 70 71/* 72 * Time of day and interval timer support. 73 * 74 * These routines provide the kernel entry points to get and set --- 91 unchanged lines hidden (view full) --- 166 mtx_lock(&Giant); 167 tc_setclock(&ts); 168 resettodr(); 169 mtx_unlock(&Giant); 170 return (0); 171} 172 173#ifndef _SYS_SYSPROTO_H_ |
174struct clock_getcpuclockid2_args { 175 id_t id; 176 int which, 177 clockid_t *clock_id; 178}; 179#endif 180/* ARGSUSED */ 181int 182sys_clock_getcpuclockid2(struct thread *td, struct clock_getcpuclockid2_args *uap) 183{ 184 clockid_t clk_id; 185 struct proc *p; 186 pid_t pid; 187 lwpid_t tid; 188 int error; 189 190 switch(uap->which) { 191 case CPUCLOCK_WHICH_PID: 192 if (uap->id != 0) { 193 p = pfind(uap->id); 194 if (p == NULL) 195 return (ESRCH); 196 error = p_cansee(td, p); 197 PROC_UNLOCK(p); 198 if (error) 199 return (error); 200 pid = uap->id; 201 } else { 202 pid = td->td_proc->p_pid; 203 } 204 clk_id = MAKE_PROCESS_CPUCLOCK(pid); 205 break; 206 case CPUCLOCK_WHICH_TID: 207 if (uap->id == 0) 208 tid = td->td_tid; 209 else 210 tid = uap->id; 211 clk_id = MAKE_THREAD_CPUCLOCK(tid); 212 break; 213 default: 214 return (EINVAL); 215 } 216 return (copyout(&clk_id, uap->clock_id, sizeof(clockid_t))); 217} 218 219#ifndef _SYS_SYSPROTO_H_ |
|
168struct clock_gettime_args { 169 clockid_t clock_id; 170 struct timespec *tp; 171}; 172#endif 173/* ARGSUSED */ 174int 175sys_clock_gettime(struct thread *td, struct clock_gettime_args *uap) 176{ 177 struct timespec ats; 178 int error; 179 180 error = kern_clock_gettime(td, uap->clock_id, &ats); 181 if (error == 0) 182 error = copyout(&ats, uap->tp, sizeof(ats)); 183 184 return (error); 185} 186 | 220struct clock_gettime_args { 221 clockid_t clock_id; 222 struct timespec *tp; 223}; 224#endif 225/* ARGSUSED */ 226int 227sys_clock_gettime(struct thread *td, struct clock_gettime_args *uap) 228{ 229 struct timespec ats; 230 int error; 231 232 error = kern_clock_gettime(td, uap->clock_id, &ats); 233 if (error == 0) 234 error = copyout(&ats, uap->tp, sizeof(ats)); 235 236 return (error); 237} 238 |
239static inline void 240cputick2timespec(uint64_t runtime, struct timespec *ats) 241{ 242 runtime = cputick2usec(runtime); 243 ats->tv_sec = runtime / 1000000; 244 ats->tv_nsec = runtime % 1000000 * 1000; 245} 246 247static void 248get_thread_cputime(struct thread *targettd, struct timespec *ats) 249{ 250 uint64_t runtime, curtime, switchtime; 251 252 if (targettd == NULL) { /* current thread */ 253 critical_enter(); 254 switchtime = PCPU_GET(switchtime); 255 curtime = cpu_ticks(); 256 runtime = curthread->td_runtime; 257 critical_exit(); 258 runtime += curtime - switchtime; 259 } else { 260 thread_lock(targettd); 261 runtime = targettd->td_runtime; 262 thread_unlock(targettd); 263 } 264 cputick2timespec(runtime, ats); 265} 266 267static void 268get_process_cputime(struct proc *targetp, struct timespec *ats) 269{ 270 uint64_t runtime; 271 struct rusage ru; 272 273 PROC_SLOCK(targetp); 274 rufetch(targetp, &ru); 275 runtime = targetp->p_rux.rux_runtime; 276 PROC_SUNLOCK(targetp); 277 cputick2timespec(runtime, ats); 278} 279 280static int 281get_cputime(struct thread *td, clockid_t clock_id, struct timespec *ats) 282{ 283 struct proc *p, *p2; 284 struct thread *td2; 285 lwpid_t tid; 286 pid_t pid; 287 int error; 288 289 p = td->td_proc; 290 if ((clock_id & CPUCLOCK_PROCESS_BIT) == 0) { 291 tid = clock_id & CPUCLOCK_ID_MASK; 292 td2 = tdfind(tid, p->p_pid); 293 if (td2 == NULL) 294 return (EINVAL); 295 get_thread_cputime(td2, ats); 296 PROC_UNLOCK(td2->td_proc); 297 } else { 298 pid = clock_id & CPUCLOCK_ID_MASK; 299 p2 = pfind(pid); 300 if (p2 == NULL) 301 return (EINVAL); 302 error = p_cansee(td, p2); 303 if (error) { 304 PROC_UNLOCK(p2); 305 return (EINVAL); 306 } 307 get_process_cputime(p2, ats); 308 PROC_UNLOCK(p2); 309 } 310 return (0); 311} 312 |
|
187int 188kern_clock_gettime(struct thread *td, clockid_t clock_id, struct timespec *ats) 189{ 190 struct timeval sys, user; 191 struct proc *p; | 313int 314kern_clock_gettime(struct thread *td, clockid_t clock_id, struct timespec *ats) 315{ 316 struct timeval sys, user; 317 struct proc *p; |
192 uint64_t runtime, curtime, switchtime; | |
193 194 p = td->td_proc; 195 switch (clock_id) { 196 case CLOCK_REALTIME: /* Default to precise. */ 197 case CLOCK_REALTIME_PRECISE: 198 nanotime(ats); 199 break; 200 case CLOCK_REALTIME_FAST: --- 26 unchanged lines hidden (view full) --- 227 case CLOCK_MONOTONIC_FAST: 228 getnanouptime(ats); 229 break; 230 case CLOCK_SECOND: 231 ats->tv_sec = time_second; 232 ats->tv_nsec = 0; 233 break; 234 case CLOCK_THREAD_CPUTIME_ID: | 318 319 p = td->td_proc; 320 switch (clock_id) { 321 case CLOCK_REALTIME: /* Default to precise. */ 322 case CLOCK_REALTIME_PRECISE: 323 nanotime(ats); 324 break; 325 case CLOCK_REALTIME_FAST: --- 26 unchanged lines hidden (view full) --- 352 case CLOCK_MONOTONIC_FAST: 353 getnanouptime(ats); 354 break; 355 case CLOCK_SECOND: 356 ats->tv_sec = time_second; 357 ats->tv_nsec = 0; 358 break; 359 case CLOCK_THREAD_CPUTIME_ID: |
235 critical_enter(); 236 switchtime = PCPU_GET(switchtime); 237 curtime = cpu_ticks(); 238 runtime = td->td_runtime; 239 critical_exit(); 240 runtime = cputick2usec(runtime + curtime - switchtime); 241 ats->tv_sec = runtime / 1000000; 242 ats->tv_nsec = runtime % 1000000 * 1000; | 360 get_thread_cputime(NULL, ats); |
243 break; | 361 break; |
362 case CLOCK_PROCESS_CPUTIME_ID: 363 PROC_LOCK(p); 364 get_process_cputime(p, ats); 365 PROC_UNLOCK(p); 366 break; |
|
244 default: | 367 default: |
245 return (EINVAL); | 368 if ((int)clock_id >= 0) 369 return (EINVAL); 370 return (get_cputime(td, clock_id, ats)); |
246 } 247 return (0); 248} 249 250#ifndef _SYS_SYSPROTO_H_ 251struct clock_settime_args { 252 clockid_t clock_id; 253 const struct timespec *tp; --- 77 unchanged lines hidden (view full) --- 331 /* Accurately round up here because we can do so cheaply. */ 332 ts->tv_nsec = (1000000000 + hz - 1) / hz; 333 break; 334 case CLOCK_SECOND: 335 ts->tv_sec = 1; 336 ts->tv_nsec = 0; 337 break; 338 case CLOCK_THREAD_CPUTIME_ID: | 371 } 372 return (0); 373} 374 375#ifndef _SYS_SYSPROTO_H_ 376struct clock_settime_args { 377 clockid_t clock_id; 378 const struct timespec *tp; --- 77 unchanged lines hidden (view full) --- 456 /* Accurately round up here because we can do so cheaply. */ 457 ts->tv_nsec = (1000000000 + hz - 1) / hz; 458 break; 459 case CLOCK_SECOND: 460 ts->tv_sec = 1; 461 ts->tv_nsec = 0; 462 break; 463 case CLOCK_THREAD_CPUTIME_ID: |
464 case CLOCK_PROCESS_CPUTIME_ID: 465 cputime: |
|
339 /* sync with cputick2usec */ 340 ts->tv_nsec = 1000000 / cpu_tickrate(); 341 if (ts->tv_nsec == 0) 342 ts->tv_nsec = 1000; 343 break; 344 default: | 466 /* sync with cputick2usec */ 467 ts->tv_nsec = 1000000 / cpu_tickrate(); 468 if (ts->tv_nsec == 0) 469 ts->tv_nsec = 1000; 470 break; 471 default: |
472 if ((int)clock_id < 0) 473 goto cputime; |
|
345 return (EINVAL); 346 } 347 return (0); 348} 349 350static int nanowait; 351 352int --- 1144 unchanged lines hidden --- | 474 return (EINVAL); 475 } 476 return (0); 477} 478 479static int nanowait; 480 481int --- 1144 unchanged lines hidden --- |