svn commit: r341178 - head/sys/kern
Mateusz Guzik
mjg at FreeBSD.org
Thu Nov 29 03:44:04 UTC 2018
Author: mjg
Date: Thu Nov 29 03:44:02 2018
New Revision: 341178
URL: https://svnweb.freebsd.org/changeset/base/341178
Log:
Tidy up hardclock.
- use fcmpset for updating ticks
- move (rarely used) itimer handling to a dedicated function
Sponsored by: The FreeBSD Foundation
Modified:
head/sys/kern/kern_clock.c
Modified: head/sys/kern/kern_clock.c
==============================================================================
--- head/sys/kern/kern_clock.c Thu Nov 29 03:39:11 2018 (r341177)
+++ head/sys/kern/kern_clock.c Thu Nov 29 03:44:02 2018 (r341178)
@@ -421,6 +421,36 @@ initclocks(void *dummy)
#endif
}
+static __noinline void
+hardclock_itimer(struct thread *td, struct pstats *pstats, int cnt, int usermode)
+{
+ struct proc *p;
+ int flags;
+
+ flags = 0;
+ p = td->td_proc;
+ if (usermode &&
+ timevalisset(&pstats->p_timer[ITIMER_VIRTUAL].it_value)) {
+ PROC_ITIMLOCK(p);
+ if (itimerdecr(&pstats->p_timer[ITIMER_VIRTUAL],
+ tick * cnt) == 0)
+ flags |= TDF_ALRMPEND | TDF_ASTPENDING;
+ PROC_ITIMUNLOCK(p);
+ }
+ if (timevalisset(&pstats->p_timer[ITIMER_PROF].it_value)) {
+ PROC_ITIMLOCK(p);
+ if (itimerdecr(&pstats->p_timer[ITIMER_PROF],
+ tick * cnt) == 0)
+ flags |= TDF_PROFPEND | TDF_ASTPENDING;
+ PROC_ITIMUNLOCK(p);
+ }
+ if (flags != 0) {
+ thread_lock(td);
+ td->td_flags |= flags;
+ thread_unlock(td);
+ }
+}
+
void
hardclock(int cnt, int usermode)
{
@@ -428,15 +458,14 @@ hardclock(int cnt, int usermode)
struct thread *td = curthread;
struct proc *p = td->td_proc;
int *t = DPCPU_PTR(pcputicks);
- int flags, global, newticks;
- int i;
+ int global, i, newticks;
/*
* Update per-CPU and possibly global ticks values.
*/
*t += cnt;
+ global = ticks;
do {
- global = ticks;
newticks = *t - global;
if (newticks <= 0) {
if (newticks < -1)
@@ -444,33 +473,16 @@ hardclock(int cnt, int usermode)
newticks = 0;
break;
}
- } while (!atomic_cmpset_int(&ticks, global, *t));
+ } while (!atomic_fcmpset_int(&ticks, &global, *t));
/*
* Run current process's virtual and profile time, as needed.
*/
pstats = p->p_stats;
- flags = 0;
- if (usermode &&
- timevalisset(&pstats->p_timer[ITIMER_VIRTUAL].it_value)) {
- PROC_ITIMLOCK(p);
- if (itimerdecr(&pstats->p_timer[ITIMER_VIRTUAL],
- tick * cnt) == 0)
- flags |= TDF_ALRMPEND | TDF_ASTPENDING;
- PROC_ITIMUNLOCK(p);
- }
- if (timevalisset(&pstats->p_timer[ITIMER_PROF].it_value)) {
- PROC_ITIMLOCK(p);
- if (itimerdecr(&pstats->p_timer[ITIMER_PROF],
- tick * cnt) == 0)
- flags |= TDF_PROFPEND | TDF_ASTPENDING;
- PROC_ITIMUNLOCK(p);
- }
- if (flags != 0) {
- thread_lock(td);
- td->td_flags |= flags;
- thread_unlock(td);
- }
+ if (__predict_false(
+ timevalisset(&pstats->p_timer[ITIMER_VIRTUAL].it_value) ||
+ timevalisset(&pstats->p_timer[ITIMER_PROF].it_value)))
+ hardclock_itimer(td, pstats, cnt, usermode);
#ifdef HWPMC_HOOKS
if (PMC_CPU_HAS_SAMPLES(PCPU_GET(cpuid)))
More information about the svn-src-all
mailing list