-int bsd_hardclockinit = 0;
-/*ARGSUSED*/
-void
-bsd_hardclock(usermode, pc, numticks)
- boolean_t usermode;
- caddr_t pc;
- int numticks;
-{
- register struct proc *p;
- register int s;
- int ticks = numticks;
- extern int tickdelta;
- extern long timedelta;
- register thread_t thread;
- int nusecs = numticks * tick;
-
- if (!bsd_hardclockinit)
- return;
-
- thread = current_thread();
-
- /*
- * Charge the time out based on the mode the cpu is in.
- * Here again we fudge for the lack of proper interval timers
- * assuming that the current state has been around at least
- * one tick.
- */
- p = (struct proc *)get_bsdtask_info(current_task());
- if (p && ((p->p_flag & P_WEXIT) == NULL)) {
- if (usermode) {
- if (p) {
- if (p->p_stats && p->p_stats->p_prof.pr_scale) {
- p->p_flag |= P_OWEUPC;
- ast_on(AST_BSD);
- }
- }
-
- /*
- * CPU was in user state. Increment
- * user time counter, and process process-virtual time
- * interval timer.
- */
- if (p->p_stats &&
- timerisset(&p->p_stats->p_timer[ITIMER_VIRTUAL].it_value) &&
- itimerdecr(&p->p_stats->p_timer[ITIMER_VIRTUAL], nusecs) == 0) {
- extern void psignal_vtalarm(struct proc *);
-
- /* does psignal(p, SIGVTALRM) in a thread context */
- thread_call_func((thread_call_func_t)psignal_vtalarm, p, FALSE);
- }
- }
-
- /*
- * If the cpu is currently scheduled to a process, then
- * charge it with resource utilization for a tick, updating
- * statistics which run in (user+system) virtual time,
- * such as the cpu time limit and profiling timers.
- * This assumes that the current process has been running
- * the entire last tick.
- */
- if (p && !(is_thread_idle(thread)))
- {
- if (p->p_limit && (p->p_limit->pl_rlimit[RLIMIT_CPU].rlim_cur != RLIM_INFINITY)) {
- time_value_t sys_time, user_time;
-
- thread_read_times(thread, &user_time, &sys_time);
- if ((sys_time.seconds + user_time.seconds + 1) >
- p->p_limit->pl_rlimit[RLIMIT_CPU].rlim_cur) {
- extern void psignal_xcpu(struct proc *);
-
- /* does psignal(p, SIGXCPU) in a thread context */
- thread_call_func((thread_call_func_t)psignal_xcpu, p, FALSE);
-
- if (p->p_limit->pl_rlimit[RLIMIT_CPU].rlim_cur <
- p->p_limit->pl_rlimit[RLIMIT_CPU].rlim_max)
- p->p_limit->pl_rlimit[RLIMIT_CPU].rlim_cur += 5;
- }
- }
- if (timerisset(&p->p_stats->p_timer[ITIMER_PROF].it_value) &&
- itimerdecr(&p->p_stats->p_timer[ITIMER_PROF], nusecs) == 0) {
- extern void psignal_sigprof(struct proc *);
-
- /* does psignal(p, SIGPROF) in a thread context */
- thread_call_func((thread_call_func_t)psignal_sigprof, p, FALSE);
- }
- }
-
- /*
- * Increment the time-of-day, and schedule
- * processing of the callouts at a very low cpu priority,
- * so we don't keep the relatively high clock interrupt
- * priority any longer than necessary.
- */
-
- /*
- * Gather the statistics.
- */
- gatherstats(usermode, pc);