From owner-p4-projects@FreeBSD.ORG Fri Sep 26 19:41:56 2014 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id CDD0AE66; Fri, 26 Sep 2014 19:41:56 +0000 (UTC) Delivered-To: perforce@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) (using TLSv1 with cipher ADH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id 901D0E64 for ; Fri, 26 Sep 2014 19:41:56 +0000 (UTC) Received: from skunkworks.freebsd.org (skunkworks.freebsd.org [IPv6:2001:1900:2254:2068::682:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 7BCE9BCD for ; Fri, 26 Sep 2014 19:41:56 +0000 (UTC) Received: from skunkworks.freebsd.org ([127.0.1.74]) by skunkworks.freebsd.org (8.14.9/8.14.9) with ESMTP id s8QJfuHe085200 for ; Fri, 26 Sep 2014 19:41:56 GMT (envelope-from jhb@freebsd.org) Received: (from perforce@localhost) by skunkworks.freebsd.org (8.14.9/8.14.9/Submit) id s8QJfuRW085197 for perforce@freebsd.org; Fri, 26 Sep 2014 19:41:56 GMT (envelope-from jhb@freebsd.org) Date: Fri, 26 Sep 2014 19:41:56 GMT Message-Id: <201409261941.s8QJfuRW085197@skunkworks.freebsd.org> X-Authentication-Warning: skunkworks.freebsd.org: perforce set sender to jhb@freebsd.org using -f From: John Baldwin Subject: PERFORCE change 1200842 for review To: Perforce Change Reviews Precedence: bulk X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.18-1 List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 26 Sep 2014 19:41:57 -0000 http://p4web.freebsd.org/@@1200842?ac=10 Change 1200842 by jhb@jhb_ralph on 2014/09/26 19:41:06 Finish the pass over this. Affected files ... .. //depot/projects/smpng/share/man/man9/timeout.9#14 edit Differences ... ==== //depot/projects/smpng/share/man/man9/timeout.9#14 (text+ko) ==== @@ -136,7 +136,7 @@ They may not acquire any sleepable locks, wait on condition variables, perform blocking allocation requests, -or invoke any other action which may sleep. +or invoke any other action that might sleep. .Pp Each callout structure must be initialized by .Fn callout_init , @@ -163,9 +163,9 @@ .Fn callout_init_rm , and .Fn callout_init_rw -functions are initialize a callout structure in -.Fa c that is associated with -a specific lock. +functions initialize a callout structure in +.Fa c +that is associated with a specific lock. The lock is specified by the .Fa mtx , .Fa rm , @@ -174,11 +174,11 @@ parameter, respectively. The callout subsystem acquires the associated lock before calling the callout function. -The subsystem then checks if the pending callout has been cancelled -while waiting for the associated lock. -If it has, +The subsystem then checks if the pending callout was cancelled +while it waited for the associated lock. +If it was, the callout function is not called and the associated lock is released. -If it has not, +If it was not, the callout function is called and the associated lock is released by the subsystem after the callout function returns. In addition, @@ -290,6 +290,7 @@ .Fa ticks are silently converted to the value .Sq 1 . +.Pp The .Fa sbt , .Fa pr , @@ -355,11 +356,14 @@ functions specify the function to be called when the time expires via the .Fa func argument. -The +It should be a pointer to a function that takes a +.Fa void * +argument. +Upon invocation, +.Fa func +will receive .Fa arg -value is passed to -.Fn func -as its sole argument when it is invoked. +as its only argument. The .Fn callout_schedule functions reuse the @@ -368,7 +372,7 @@ .Fa arg arguments from the previous callout. Note that one of the -.Fa callout_reset +.Fn callout_reset functions must always be called to initialize .Fa func and @@ -376,7 +380,6 @@ before one of the .Fn callout_schedule functions can be used. - .Pp Normally callouts are scheduled to execute on the softclock thread they were associated with previously. @@ -396,6 +399,7 @@ and .Fn callout_schedule_curcpu functions associate the callout with the softclock thread for the current CPU. +.Pp The softclock threads are not pinned to their respective CPUs by default. The softclock thread for CPU 0 can be pinned to CPU by setting the .Va kern.pin_default_swi @@ -447,50 +451,61 @@ .Em does not clear it when a callout expires normally via the execution of the callout function. - - - .Ss "Avoiding Race Conditions" -The callout subsystem invokes callout functions from its own timer +The callout subsystem invokes callout functions from its own thread context. Without some kind of synchronization it is possible that a callout function will be invoked concurrently with an attempt to stop or reset the callout by another thread. -In particular, since callout functions typically acquire a mutex as +In particular, since callout functions typically acquire a lock as their first action, the callout function may have already been invoked, -but be blocked waiting for that mutex at the time that another thread +but be blocked waiting for that lock at the time that another thread tries to reset or stop the callout. .Pp -The callout subsystem provides a number of mechanisms to address these -synchronization concerns: +One of the following approaches can be used to address these +synchronization concerns, though the first approach is preferred when +possible as it is the simplest: .Bl -enum -offset indent .It -If the callout has an associated mutex that was specified using the -.Fn callout_init_mtx -function (or implicitly specified as the -.Va Giant -mutex using +Callouts can be associated with a specific lock when they are initialized +by +.Fn callout_init_mtx , +.Fn callout_init_rm , +or +.Fn callout_init_rw . +When a callout is associated with a lock, +the callout subsystem acquires the lock before the callout function is +invoked. +This allows the callout subsystem to handle races between callout cancellation, +scheduling, +and execution transparently. +Note that the associated lock must be acquired before calling +.Fn callout_stop +or one of the +.Fn callout_reset +or +.Fn callout_schedule +functions to provide this safety. +.Pp +A callout initialized via .Fn callout_init with .Fa mpsafe -set to -.Dv FALSE ) , -then this mutex is used to avoid the race conditions. -The associated mutex must be acquired by the caller before calling -.Fn callout_stop -or -.Fn callout_reset -and it is guaranteed that the callout will be correctly stopped -or reset as expected. -Note that it is still necessary to use -.Fn callout_drain -before destroying the callout or its associated mutex. +set to zero is implicitly associated with the +.Va Giant +mutex. +If +.Va Giant +is held when cancelling or rescheduling the callout, +then it's use will prevent races with the callout function. .It The return value from .Fn callout_stop +and the +.Fn callout_reset and -.Fn callout_reset -indicates whether or not the callout was removed. +.Fn callout_schedule +function families indicate whether or not the callout was removed. If it is known that the callout was set and the callout function has not yet executed, then a return value of .Dv FALSE @@ -624,6 +639,9 @@ To ensure that the callout is completely finished, a call to .Fn callout_drain should be used. +In particular, +a callout should always be drained prior to destroying its associated lock +or releasing the storage for the callout structure. .Sh LEGACY API .Bf Sy The functions below are a legacy API that will be removed in a future release. @@ -719,17 +737,36 @@ Thus they are protected from re-entrancy. .Sh RETURN VALUES The -.Fn timeout -function returns a -.Ft struct callout_handle -that can be passed to -.Fn untimeout . +.Fn callout_active +macro returns the state of a callout's +.Em active +flag. +.Pp +The +.Fn callout_pending +macro returns the state of a callout's +.Em pending +flag. +.Pp +The +.Fn callout_reset +and +.Fn callout_schedule +function families return non-zero if the callout was pending before the new +function invocation was scheduled. +.Pp The .Fn callout_stop and .Fn callout_drain functions return non-zero if the callout was still pending when it was called or zero otherwise. +The +.Fn timeout +function returns a +.Ft struct callout_handle +that can be passed to +.Fn untimeout . .Sh HISTORY The current timeout and untimeout routines are based on the work of .An Adam M. Costello