- 论坛徽章:
- 0
|
本帖最后由 71v5 于 2014-06-25 21:46 编辑
当statclock超时时,就会调用statclock_cnt进行相应的处理:- /**************************************************************************
- * Statistics clock. Updates rusage information and calls the scheduler
- * to adjust priorities of the active thread.
- *
- * This should be called by all active processors.
- 参数描述:
- cnt:statclock超时的次数。
- usermode:发生APIC TIMER中断时cpu是否处于用户态。
- ***********************************/
- 708 void
- 709 statclock_cnt(int cnt, int usermode)
- 710 {
- 711 struct rusage *ru;
- 712 struct vmspace *vm;
- 713 struct thread *td;
- 714 struct proc *p;
- 715 long rss;
- 716 long *cp_time;
- 717
- 718 td = curthread;
- 719 p = td->td_proc;
- 720
- /***********************************************************************************************************
- * struct pcpu数据对象的pc_cp_time成员定义如下:
- long pc_cp_time[CPUSTATES]; /* statclock ticks */
- 数组pc_cp_time的索引可以取值如下:
- #define CP_USER 0
- #define CP_NICE 1
- #define CP_SYS 2
- #define CP_INTR 3
- #define CP_IDLE 4
- #define CPUSTATES 5
- #define NZERO 0 /* default "nice" */
- signed char p_nice; /* (c) Process "nice" value. */
- 通过722-756之间代码,可以看出什么条件下递增struct thread对象的下列成员,这些成员
- 都是对statclock超时次数进行计数:
- td_pticks:APIC TIMER中断发生时线程运行在内核态,并且线程不是中断线程或者线程的
- 中断嵌套小于2,此时递增td_pticks。
- u_int td_pticks; /* (t) Statclock hits for profiling */
- td_sticks:同td_pticks
- u_int td_sticks; /* (t) Statclock hits in system mode. */
- td_iticks:APIC TIMER中断发生时线程运行在内核态,并且线程是中断线程或者线程的
- 中断嵌套大于2,此时递增td_iticks。
- u_int td_iticks; /* (t) Statclock hits in intr mode. */
- td_uticks:APIC TIMER中断发生时线程运行在用户态,此时递增td_uticks。
- u_int td_uticks; /* (t) Statclock hits in user mode. */
-
- pc_cp_time数组元素也是对statclock的超时次数进行计数,只不过使用另外一种方式
- 来描述,含义是显而易见的。
- 722-731:cpu处于用户态。
- 731-756:cpu处于内核态。
- ************************************************************************************************/
- 721 cp_time = (long *)PCPU_PTR(cp_time);
- 722 if (usermode) {
- 723 /*
- 724 * Charge the time as appropriate.
- 725 */
- 726 td->td_uticks += cnt;
- 727 if (p->p_nice > NZERO)
- 728 cp_time[CP_NICE] += cnt;
- 729 else
- 730 cp_time[CP_USER] += cnt;
- 731 } else {
- 732 /*
- 733 * Came from kernel mode, so we were:
- 734 * - handling an interrupt,
- 735 * - doing syscall or trap work on behalf of the current
- 736 * user process, or
- 737 * - spinning in the idle loop.
- 738 * Whichever it is, charge the time as appropriate.
- 739 * Note that we charge interrupts to the current process,
- 740 * regardless of whether they are ``for'' that process,
- 741 * so that we know how much of its real time was spent
- 742 * in ``non-process'' (i.e., interrupt) work.
- 743 */
- 744 if ((td->td_pflags & TDP_ITHREAD) ||
- 745 td->td_intr_nesting_level >= 2) {
- 746 td->td_iticks += cnt;
- 747 cp_time[CP_INTR] += cnt;
- 748 } else {
- 749 td->td_pticks += cnt;
- 750 td->td_sticks += cnt;
- 751 if (!TD_IS_IDLETHREAD(td))
- 752 cp_time[CP_SYS] += cnt;
- 753 else
- 754 cp_time[CP_IDLE] += cnt;
- 755 }
- 756 }
- 757
- 758
- /*********************************************************
- * Update resource usage integrals and maximums.
- 760-767:进程资源使用量相关处理,暂时略过。
- ********************************/
- 759 MPASS(p->p_vmspace != NULL);
- 760 vm = p->p_vmspace;
- 761 ru = &td->td_ru;
- 762 ru->ru_ixrss += pgtok(vm->vm_tsize) * cnt;
- 763 ru->ru_idrss += pgtok(vm->vm_dsize) * cnt;
- 764 ru->ru_isrss += pgtok(vm->vm_ssize) * cnt;
- 765 rss = pgtok(vmspace_resident_count(vm));
- 766 if (ru->ru_maxrss < rss)
- 767 ru->ru_maxrss = rss;
- 768 KTR_POINT2(KTR_SCHED, "thread", sched_tdname(td), "statclock",
- 769 "prio:%d", td->td_priority, "stathz:%d", (stathz)?stathz:hz);
- 770 SDT_PROBE2(sched, , , tick, td, td->td_proc);
- 771 thread_lock_flags(td, MTX_QUIET);
- /******************************************************
- * 772-773: 重点
- 调度程序相关的sched_clock函数。
- **************************/
- 772 for ( ; cnt > 0; cnt--)
- 773 sched_clock(td);
- 774 thread_unlock(td);
- 775 #ifdef HWPMC_HOOKS
- 776 if (td->td_intr_frame != NULL)
- 777 PMC_SOFT_CALL_TF( , , clock, stat, td->td_intr_frame);
- 778 #endif
- 779 }
复制代码 [ULE调度程序的sched_clock函数]: |
|