diff --git a/lib/libthr/libthr.3 b/lib/libthr/libthr.3 --- a/lib/libthr/libthr.3 +++ b/lib/libthr/libthr.3 @@ -216,6 +216,12 @@ .Xr _umtx_op for more details. The default value is large enough for most useful applications. +.It Dv kern.ipc.umtx_min_timeout +The minimal amount of time, in nanoseconds, the thread is required to sleep +for pthread operations specifying a timeout. +If the operation requests a timeout less than the value of the MIB, +it is silently increased to the value. +The value of zero means no limit. .It Dv debug.umtx.robust_faults_verbose A non zero value makes kernel emit some diagnostic when the robust mutexes unlock was prematurely aborted after detecting some inconsistency, diff --git a/sys/kern/kern_umtx.c b/sys/kern/kern_umtx.c --- a/sys/kern/kern_umtx.c +++ b/sys/kern/kern_umtx.c @@ -151,6 +151,26 @@ &umtx_max_rb, 0, "Maximum number of robust mutexes allowed for each thread"); +static sbintime_t umtx_min_timeout; +static int +sysctl_umtx_min_timeout(SYSCTL_HANDLER_ARGS) +{ + int error, val; + + val = sbttons(umtx_min_timeout); + error = sysctl_handle_int(oidp, &val, 0, req); + if (error != 0 || req->newptr == NULL) + return (error); + if (val < 0) + return (EINVAL); + umtx_min_timeout = nstosbt(val); + return (0); +} +SYSCTL_PROC(_kern_ipc, OID_AUTO, umtx_min_timeout, + CTLFLAG_RW | CTLTYPE_UINT | CTLFLAG_MPSAFE, NULL, 0, + sysctl_umtx_min_timeout, "U", + "Minimal timeout for umtx in nanoseconds"); + static uma_zone_t umtx_pi_zone; static struct umtxq_chain umtxq_chains[2][UMTX_CHAINS]; static MALLOC_DEFINE(M_UMTX, "umtx", "UMTX queue memory"); @@ -700,6 +720,21 @@ (umtxtime->_flags & UMTX_ABSTIME) != 0, &umtxtime->_timeout); } +static void +umtx_abs_timeout_enforce_min(sbintime_t *sbt) +{ + struct bintime now; + sbintime_t when; + + if (umtx_min_timeout == 0) + return; + + getbinuptime(&now); + when = bttosbt(now) + umtx_min_timeout; + if (*sbt < when) + *sbt = when; +} + static int umtx_abs_timeout_getsbt(struct umtx_abs_timeout *timo, sbintime_t *sbt, int *flags) @@ -739,6 +774,7 @@ return (0); } *sbt = bttosbt(bt); + umtx_abs_timeout_enforce_min(sbt); /* * Check if the absolute time should be aligned to