Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 29 Nov 2018 03:44:02 +0000 (UTC)
From:      Mateusz Guzik <mjg@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r341178 - head/sys/kern
Message-ID:  <201811290344.wAT3i2Ai032661@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
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)))



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201811290344.wAT3i2Ai032661>