Date: Fri, 26 Sep 2014 19:41:56 GMT From: John Baldwin <jhb@FreeBSD.org> To: Perforce Change Reviews <perforce@FreeBSD.org> Subject: PERFORCE change 1200842 for review Message-ID: <201409261941.s8QJfuRW085197@skunkworks.freebsd.org>
next in thread | raw e-mail | index | archive | help
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
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201409261941.s8QJfuRW085197>