summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndy Fiddaman <omnios@citrus-it.co.uk>2022-02-18 00:32:27 +0000
committerAndy Fiddaman <omnios@citrus-it.co.uk>2022-03-16 00:02:44 +0000
commit7bb0eb348e1119aed76a61d633a9106b6b9912f1 (patch)
treeacaa58321439ba3f834df192a741eacc65f1bc71
parent499bc737cd392291f0c92dcebcb576970689f5d8 (diff)
downloadillumos-joyent-7bb0eb348e1119aed76a61d633a9106b6b9912f1.tar.gz
14521 bhyve should use error checking mutexes and check results
14522 Provide PTHREAD_{ERRORCHECK,RECURSIVE}_MUTEX_INITIALIZER_NP Portions contributed by: Robert Mustacchi <rm@fingolfin.org> Reviewed by: Robert Mustacchi <rm@fingolfin.org> Reviewed by: Jason King <jason.brian.king@gmail.com> Approved by: Dan McDonald <danmcd@joyent.com>
-rw-r--r--usr/src/cmd/bhyve/mevent.c2
-rw-r--r--usr/src/cmd/bhyve/pci_nvme.c10
-rw-r--r--usr/src/cmd/bhyve/pci_virtio_console.c4
-rw-r--r--usr/src/cmd/bhyve/pci_virtio_rnd.c4
-rw-r--r--usr/src/cmd/bhyve/rfb.c4
-rw-r--r--usr/src/compat/bhyve/pthread.h61
-rw-r--r--usr/src/head/pthread.h15
-rw-r--r--usr/src/lib/libc/port/mapfile-vers2
-rw-r--r--usr/src/lib/libc/port/threads/synch.c18
-rw-r--r--usr/src/man/man3c/pthread_mutex_init.3c349
-rw-r--r--usr/src/man/man3head/pthread.h.3head239
11 files changed, 386 insertions, 322 deletions
diff --git a/usr/src/cmd/bhyve/mevent.c b/usr/src/cmd/bhyve/mevent.c
index 576ba3390e..09f39ed06b 100644
--- a/usr/src/cmd/bhyve/mevent.c
+++ b/usr/src/cmd/bhyve/mevent.c
@@ -669,8 +669,6 @@ mevent_handle_pe(port_event_t *pe)
{
struct mevent *mevp = pe->portev_user;
- mevent_qunlock();
-
(*mevp->me_func)(mevp->me_fd, mevp->me_type, mevp->me_param);
mevent_qlock();
diff --git a/usr/src/cmd/bhyve/pci_nvme.c b/usr/src/cmd/bhyve/pci_nvme.c
index 73e8ab0371..a69c49a388 100644
--- a/usr/src/cmd/bhyve/pci_nvme.c
+++ b/usr/src/cmd/bhyve/pci_nvme.c
@@ -460,8 +460,13 @@ pci_nvme_init_queues(struct pci_nvme_softc *sc, uint32_t nsq, uint32_t ncq)
} else {
struct nvme_submission_queue *sq = sc->submit_queues;
+#ifndef __FreeBSD__
+ for (i = 0; i < sc->num_squeues + 1; i++)
+ pthread_mutex_init(&sq[i].mtx, NULL);
+#else
for (i = 0; i < sc->num_squeues; i++)
pthread_mutex_init(&sq[i].mtx, NULL);
+#endif
}
/*
@@ -483,8 +488,13 @@ pci_nvme_init_queues(struct pci_nvme_softc *sc, uint32_t nsq, uint32_t ncq)
} else {
struct nvme_completion_queue *cq = sc->compl_queues;
+#ifndef __FreeBSD__
+ for (i = 0; i < sc->num_cqueues + 1; i++)
+ pthread_mutex_init(&cq[i].mtx, NULL);
+#else
for (i = 0; i < sc->num_cqueues; i++)
pthread_mutex_init(&cq[i].mtx, NULL);
+#endif
}
}
diff --git a/usr/src/cmd/bhyve/pci_virtio_console.c b/usr/src/cmd/bhyve/pci_virtio_console.c
index 998d5e1d4c..a153dc7ae3 100644
--- a/usr/src/cmd/bhyve/pci_virtio_console.c
+++ b/usr/src/cmd/bhyve/pci_virtio_console.c
@@ -725,6 +725,10 @@ pci_vtcon_init(struct vmctx *ctx, struct pci_devinst *pi, nvlist_t *nvl)
sc->vsc_config->cols = 80;
sc->vsc_config->rows = 25;
+#ifndef __FreeBSD__
+ pthread_mutex_init(&sc->vsc_mtx, NULL);
+#endif
+
vi_softc_linkup(&sc->vsc_vs, &vtcon_vi_consts, sc, pi, sc->vsc_queues);
sc->vsc_vs.vs_mtx = &sc->vsc_mtx;
diff --git a/usr/src/cmd/bhyve/pci_virtio_rnd.c b/usr/src/cmd/bhyve/pci_virtio_rnd.c
index 7807bac7a8..8e7f995e9f 100644
--- a/usr/src/cmd/bhyve/pci_virtio_rnd.c
+++ b/usr/src/cmd/bhyve/pci_virtio_rnd.c
@@ -179,6 +179,10 @@ pci_vtrnd_init(struct vmctx *ctx, struct pci_devinst *pi, nvlist_t *nvl)
sc = calloc(1, sizeof(struct pci_vtrnd_softc));
+#ifndef __FreeBSD__
+ pthread_mutex_init(&sc->vrsc_mtx, NULL);
+#endif
+
vi_softc_linkup(&sc->vrsc_vs, &vtrnd_vi_consts, sc, pi, &sc->vrsc_vq);
sc->vrsc_vs.vs_mtx = &sc->vrsc_mtx;
diff --git a/usr/src/cmd/bhyve/rfb.c b/usr/src/cmd/bhyve/rfb.c
index a441deb398..86b0d6d456 100644
--- a/usr/src/cmd/bhyve/rfb.c
+++ b/usr/src/cmd/bhyve/rfb.c
@@ -1361,9 +1361,9 @@ rfb_init_unix(const char *path, int wait, char *password, const char *name)
if (wait) {
DPRINTF(("Waiting for rfb client...\n"));
- VERIFY3S(pthread_mutex_lock(&rc->mtx), ==, 0);
+ pthread_mutex_lock(&rc->mtx);
VERIFY3S(pthread_cond_wait(&rc->cond, &rc->mtx), ==, 0);
- VERIFY3S(pthread_mutex_unlock(&rc->mtx), ==, 0);
+ pthread_mutex_unlock(&rc->mtx);
}
return (0);
diff --git a/usr/src/compat/bhyve/pthread.h b/usr/src/compat/bhyve/pthread.h
new file mode 100644
index 0000000000..de975971b5
--- /dev/null
+++ b/usr/src/compat/bhyve/pthread.h
@@ -0,0 +1,61 @@
+/*
+ * This file and its contents are supplied under the terms of the
+ * Common Development and Distribution License ("CDDL"), version 1.0.
+ * You may only use this file in accordance with the terms of version
+ * 1.0 of the CDDL.
+ *
+ * A full copy of the text of the CDDL should have accompanied this
+ * source. A copy of the CDDL is also available via the Internet at
+ * http://www.illumos.org/license/CDDL.
+ */
+
+/*
+ * Copyright 2022 OmniOS Community Edition (OmniOSce) Association.
+ */
+
+#ifndef _COMPAT_FREEBSD_PTHREAD_H_
+#define _COMPAT_FREEBSD_PTHREAD_H_
+
+#include <sys/debug.h>
+#include_next <pthread.h>
+
+/*
+ * Mutexes on FreeBSD are error-checking by default. Wrap pthread_mutex_*()
+ * to deliver the same, and check for errors.
+ */
+
+#undef PTHREAD_MUTEX_INITIALIZER
+#define PTHREAD_MUTEX_INITIALIZER PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP
+
+static __inline int
+checked_pthread_mutex_init(pthread_mutex_t *restrict mutex,
+ const pthread_mutexattr_t *restrict cattr)
+{
+ if (cattr != NULL) {
+ VERIFY0(pthread_mutex_init(mutex, cattr));
+ } else {
+ pthread_mutexattr_t attr = { 0 };
+
+ VERIFY0(pthread_mutexattr_init(&attr));
+ VERIFY0(pthread_mutexattr_settype(&attr,
+ PTHREAD_MUTEX_ERRORCHECK));
+ VERIFY0(pthread_mutex_init(mutex, &attr));
+ VERIFY0(pthread_mutexattr_destroy(&attr));
+ }
+
+ return (0);
+}
+
+static __inline int
+checked_pthread_mutex_destroy(pthread_mutex_t *mutex)
+{
+ VERIFY0(pthread_mutex_destroy(mutex));
+ return (0);
+}
+
+#define pthread_mutex_init(m, a) checked_pthread_mutex_init(m, a)
+#define pthread_mutex_destroy(m) checked_pthread_mutex_destroy(m)
+#define pthread_mutex_lock(m) pthread_mutex_enter_np(m)
+#define pthread_mutex_unlock(m) pthread_mutex_exit_np(m)
+
+#endif /* _COMPAT_FREEBSD_PTHREAD_H_ */
diff --git a/usr/src/head/pthread.h b/usr/src/head/pthread.h
index 490a93f1b2..a4db3e262b 100644
--- a/usr/src/head/pthread.h
+++ b/usr/src/head/pthread.h
@@ -22,6 +22,7 @@
/*
* Copyright 2014 Garrett D'Amore <garrett@damore.org>
* Copyright 2018 Joyent, Inc.
+ * Copyright 2022 OmniOS Community Edition (OmniOSce) Association.
*
* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
@@ -110,6 +111,14 @@ extern "C" {
#define PTHREAD_MUTEX_INITIALIZER /* = DEFAULTMUTEX */ \
{{0, 0, 0, PTHREAD_PROCESS_PRIVATE, _MUTEX_MAGIC}, {{{0}}}, 0}
+#define PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP /* = ERRORCHECKMUTEX */ \
+ {{0, 0, 0, PTHREAD_PROCESS_PRIVATE | PTHREAD_MUTEX_ERRORCHECK, \
+ _MUTEX_MAGIC}, {{{0}}}, 0}
+
+#define PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP /* = RECURSIVEMUTEX */ \
+ {{0, 0, 0, PTHREAD_PROCESS_PRIVATE | PTHREAD_MUTEX_RECURSIVE | \
+ PTHREAD_MUTEX_ERRORCHECK, _MUTEX_MAGIC}, {{{0}}}, 0}
+
#define PTHREAD_COND_INITIALIZER /* = DEFAULTCV */ \
{{{0, 0, 0, 0}, PTHREAD_PROCESS_PRIVATE, _COND_MAGIC}, 0}
@@ -346,9 +355,11 @@ extern int pthread_mutexattr_getrobust_np(
* These are non-standardized extensions that we provide. Their origins are
* documented in their manual pages.
*/
-#if !defined(_STRICT_SYMBOLS) || defined(__EXTENSIONS__)
+#if !defined(_STRICT_SYMBOLS)
extern int pthread_attr_get_np(pthread_t, pthread_attr_t *);
-#endif /* !_STRICT_SYMBOLS || __EXTENSIONS__ */
+extern void pthread_mutex_enter_np(pthread_mutex_t *);
+extern void pthread_mutex_exit_np(pthread_mutex_t *);
+#endif /* !_STRICT_SYMBOLS */
#endif /* _ASM */
diff --git a/usr/src/lib/libc/port/mapfile-vers b/usr/src/lib/libc/port/mapfile-vers
index 8b9a2f170b..4bf82c55ff 100644
--- a/usr/src/lib/libc/port/mapfile-vers
+++ b/usr/src/lib/libc/port/mapfile-vers
@@ -3756,6 +3756,8 @@ $endif
_psignal;
pthread_attr_getdaemonstate_np;
pthread_attr_setdaemonstate_np;
+ pthread_mutex_enter_np;
+ pthread_mutex_exit_np;
_pthread_setcleanupinit;
__putwchar_xpg5;
__putwc_xpg5;
diff --git a/usr/src/lib/libc/port/threads/synch.c b/usr/src/lib/libc/port/threads/synch.c
index 3ec76f7c21..b2c5980f9a 100644
--- a/usr/src/lib/libc/port/threads/synch.c
+++ b/usr/src/lib/libc/port/threads/synch.c
@@ -1781,7 +1781,7 @@ stall(void)
*/
int
mutex_lock_queue(ulwp_t *self, tdb_mutex_stats_t *msp, mutex_t *mp,
- timespec_t *tsp)
+ timespec_t *tsp)
{
uberdata_t *udp = curthread->ul_uberdata;
queue_head_t *qp;
@@ -2316,6 +2316,7 @@ mutex_lock(mutex_t *mp)
return (mutex_lock_impl(mp, NULL));
}
+#pragma weak pthread_mutex_enter_np = mutex_enter
void
mutex_enter(mutex_t *mp)
{
@@ -2341,7 +2342,7 @@ mutex_enter(mutex_t *mp)
int
pthread_mutex_timedlock(pthread_mutex_t *_RESTRICT_KYWD mp,
- const struct timespec *_RESTRICT_KYWD abstime)
+ const struct timespec *_RESTRICT_KYWD abstime)
{
timespec_t tslocal;
int error;
@@ -2356,7 +2357,7 @@ pthread_mutex_timedlock(pthread_mutex_t *_RESTRICT_KYWD mp,
int
pthread_mutex_reltimedlock_np(pthread_mutex_t *_RESTRICT_KYWD mp,
- const struct timespec *_RESTRICT_KYWD reltime)
+ const struct timespec *_RESTRICT_KYWD reltime)
{
timespec_t tslocal;
int error;
@@ -2598,6 +2599,7 @@ slow_unlock:
return (mutex_unlock_internal(mp, 0));
}
+#pragma weak pthread_mutex_exit_np = mutex_exit
void
mutex_exit(mutex_t *mp)
{
@@ -3574,7 +3576,7 @@ cond_wait(cond_t *cvp, mutex_t *mp)
*/
int
pthread_cond_wait(pthread_cond_t *_RESTRICT_KYWD cvp,
- pthread_mutex_t *_RESTRICT_KYWD mp)
+ pthread_mutex_t *_RESTRICT_KYWD mp)
{
int error;
@@ -3633,8 +3635,8 @@ cond_timedwait(cond_t *cvp, mutex_t *mp, const timespec_t *abstime)
*/
int
pthread_cond_timedwait(pthread_cond_t *_RESTRICT_KYWD cvp,
- pthread_mutex_t *_RESTRICT_KYWD mp,
- const struct timespec *_RESTRICT_KYWD abstime)
+ pthread_mutex_t *_RESTRICT_KYWD mp,
+ const struct timespec *_RESTRICT_KYWD abstime)
{
int error;
@@ -3677,8 +3679,8 @@ cond_reltimedwait(cond_t *cvp, mutex_t *mp, const timespec_t *reltime)
int
pthread_cond_reltimedwait_np(pthread_cond_t *_RESTRICT_KYWD cvp,
- pthread_mutex_t *_RESTRICT_KYWD mp,
- const struct timespec *_RESTRICT_KYWD reltime)
+ pthread_mutex_t *_RESTRICT_KYWD mp,
+ const struct timespec *_RESTRICT_KYWD reltime)
{
int error;
diff --git a/usr/src/man/man3c/pthread_mutex_init.3c b/usr/src/man/man3c/pthread_mutex_init.3c
index afaccd3574..2c34ddbe3a 100644
--- a/usr/src/man/man3c/pthread_mutex_init.3c
+++ b/usr/src/man/man3c/pthread_mutex_init.3c
@@ -43,192 +43,183 @@
.\" Copyright 1991, 1992, 1994, The X/Open Company Ltd.
.\" Copyright (c) 2001, The IEEE and The Open Group. All Rights Reserved.
.\" Copyright (c) 2008, Sun Microsystems, Inc. All Rights Reserved.
+.\" Copyright 2022 OmniOS Community Edition (OmniOSce) Association.
.\"
-.TH PTHREAD_MUTEX_INIT 3C "Nov 11, 2008"
-.SH NAME
-pthread_mutex_init, pthread_mutex_destroy \- initialize or destroy a mutex
-.SH SYNOPSIS
-.LP
-.nf
-cc -mt [ \fIflag\fR... ] \fIfile\fR... -lpthread [ \fIlibrary\fR... ]
-#include <pthread.h>
-
-\fBint\fR \fBpthread_mutex_init\fR(\fBpthread_mutex_t *restrict\fR \fImutex\fR,
- \fBconst pthread_mutexattr_t *restrict\fR \fIattr\fR);
-.fi
-
-.LP
-.nf
-\fBint\fR \fBpthread_mutex_destroy\fR(\fBpthread_mutex_t *\fR\fImutex\fR);
-.fi
-
-.LP
-.nf
-\fBpthread_mutex_t\fR \fImutex\fR= \fBPTHREAD_MUTEX_INITIALIZER\fR;
-.fi
-
-.SH DESCRIPTION
-.sp
-.LP
-The \fBpthread_mutex_init()\fR function initializes the mutex referenced by
-\fImutex\fR with attributes specified by \fIattr\fR. If \fIattr\fR is
-\fINULL\fR, the default mutex attributes are used; the effect is the same as
-passing the address of a default mutex attributes object. Upon successful
+.Dd February 18, 2022
+.Dt PTHREAD_MUTEX_INIT 3C
+.Os
+.Sh NAME
+.Nm pthread_mutex_init ,
+.Nm pthread_mutex_destroy
+.Nd initialize or destroy a mutex
+.Sh SYNOPSIS
+.In pthread.h
+.Ft int
+.Fo pthread_mutex_init
+.Fa "pthread_mutex_t *restrict mutex"
+.Fa "const pthread_mutexattr_t *restrict attr"
+.Fc
+.Ft int
+.Fo pthread_mutex_destroy
+.Fa "pthread_mutex_t *mutex"
+.Fc
+.Vt pthread_mutex_t
+.Va mutex
+.No =
+.Dv PTHREAD_MUTEX_INITIALIZER ;
+.Vt pthread_mutex_t
+.Va ecmutex
+.No =
+.Dv PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP ;
+.Vt pthread_mutex_t
+.Va rmutex
+.No =
+.Dv PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP ;
+.Sh DESCRIPTION
+The
+.Fn pthread_mutex_init
+function initializes the mutex referenced by
+.Fa mutex
+with attributes specified by
+.Fa attr .
+If
+.Fa attr
+is
+.Dv NULL ,
+the default mutex attributes are used; the effect is the same as
+passing the address of a default mutex attributes object.
+Upon successful
initialization, the state of the mutex becomes initialized and unlocked.
-.sp
-.LP
+.Pp
Except for robust mutexes, attempting to initialize an already initialized
mutex results in undefined behavior.
-.sp
-.LP
-The \fBpthread_mutex_destroy()\fR function destroys the mutex object referenced
-by \fImutex\fR; the mutex object becomes, in effect, uninitialized. A destroyed
-mutex object can be re-initialized using \fBpthread_mutex_init()\fR; the
-results of otherwise referencing the object after it has been destroyed are
+.Pp
+The
+.Fn pthread_mutex_destroy
+function destroys the mutex object referenced by
+.Fa mutex ;
+the mutex object becomes, in effect, uninitialized.
+A destroyed mutex object can be re-initialized using
+.Fn pthread_mutex_init ;
+the results of otherwise referencing the object after it has been destroyed are
undefined.
-.sp
-.LP
-It is safe to destroy an initialized mutex that is unlocked. Attempting to
-destroy a locked mutex results in undefined behavior.
-.sp
-.LP
+.Pp
+It is safe to destroy an initialized mutex that is unlocked.
+Attempting to destroy a locked mutex results in undefined behavior.
+.Pp
In cases where default mutex attributes are appropriate, the macro
-\fBPTHREAD_MUTEX_INITIALIZER\fR can be used to initialize mutexes that are
-statically allocated. The effect is equivalent to dynamic initialization by a
-call to \fBpthread_mutex_init()\fR with parameter \fIattr\fR specified as
-\fINULL\fR, except that no error checks are performed.
-.SH RETURN VALUES
-.sp
-.LP
-If successful, the \fBpthread_mutex_init()\fR and \fBpthread_mutex_destroy()\fR
-functions return \fB0\fR. Otherwise, an error number is returned to indicate
-the error.
-.SH ERRORS
-.sp
-.LP
-The \fBpthread_mutex_init()\fR function will fail if:
-.sp
-.ne 2
-.na
-\fB\fBEAGAIN\fR\fR
-.ad
-.RS 10n
-The system lacked the necessary resources (other than memory) to initialize
-another mutex.
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fBEBUSY\fR\fR
-.ad
-.RS 10n
-An attempt was detected to re-initialize a robust mutex previously initialized
-but not yet destroyed. See \fBpthread_mutexattr_setrobust\fR(3C).
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fBEINVAL\fR\fR
-.ad
-.RS 10n
+.Dv PTHREAD_MUTEX_INITIALIZER
+can be used to initialize mutexes that are statically allocated.
+The effect is equivalent to dynamic initialization by a call to
+.Fn pthread_mutex_init
+with parameter
+.Fa attr
+specified as
+.Dv NULL .
+.Pp
+In cases where error checking mutex attributes are appropriate, the macro
+.Dv PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP
+can be used to initialize mutexes that are statically allocated.
+The effect is equivalent to dynamic initialization by a call to
+.Fn pthread_mutex_init
+with parameter
+.Fa attr
+initialized with
+.Xr pthread_mutexattr_init 3C
+and its type set to
+.Dv PTHREAD_MUTEX_ERRORCHECK .
+.Pp
+In cases where recursive mutex attributes are appropriate, the macro
+.Dv PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP
+can be used to initialize mutexes that are statically allocated.
+The effect is equivalent to dynamic initialization by a call to
+.Fn pthread_mutex_init
+with parameter
+.Fa attr
+initialized with
+.Xr pthread_mutexattr_init 3C
+and its type set to
+.Dv PTHREAD_MUTEX_RECURSIVE .
+.Sh RETURN VALUES
+If successful, the
+.Fn pthread_mutex_init
+and
+.Fn pthread_mutex_destroy
+functions return
+.Sy 0 .
+Otherwise, an error number is returned to indicate the error.
+.Sh ERRORS
+The
+.Fn pthread_mutex_init
+function will fail if:
+.Bl -tag -width Er
+.It Er EAGAIN
+The system lacked the necessary resources
+.Pq other than memory
+to initialize another mutex.
+.It Er EBUSY
An attempt was detected to re-initialize a robust mutex previously initialized
-with a different set of attributes. See \fBpthread_mutexattr_setrobust\fR(3C).
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fBENOMEM\fR\fR
-.ad
-.RS 10n
+but not yet destroyed.
+See
+.Xr pthread_mutexattr_setrobust 3C .
+.It Ev EINVAL
+An attempt was detected to re-initialize a robust mutex previously initialized
+with a different set of attributes.
+See
+.Xr pthread_mutexattr_setrobust 3C .
+.It Er ENOMEM
Insufficient memory exists to initialize the mutex.
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fBEPERM\fR\fR
-.ad
-.RS 10n
+.It Er EPERM
The caller does not have the privilege to perform the operation.
-.RE
-
-.sp
-.LP
-The \fBpthread_mutex_init()\fR function may fail if:
-.sp
-.ne 2
-.na
-\fB\fBEBUSY\fR\fR
-.ad
-.RS 10n
-An attempt was detected to re-initialize the object referenced by \fImutex\fR,
+.El
+.Pp
+The
+.Fn pthread_mutex_init
+function may fail if:
+.Bl -tag -width Er
+.It Er EBUSY
+An attempt was detected to re-initialize the object referenced by
+.Fa mutex ,
a mutex previously initialized but not yet destroyed.
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fBEINVAL\fR\fR
-.ad
-.RS 10n
-The value specified by \fIattr\fR or \fImutex\fR is invalid.
-.RE
-
-.sp
-.LP
-The \fBpthread_mutex_destroy()\fR function may fail if:
-.sp
-.ne 2
-.na
-\fB\fBEBUSY\fR\fR
-.ad
-.RS 10n
-An attempt was detected to destroy the object referenced by \fImutex\fR while
-it is locked or referenced (for example, while being used in a
-\fBpthread_cond_wait\fR(3C) or \fBpthread_cond_timedwait\fR(3C)) by another
-thread.
-.RE
-
-.sp
-.ne 2
-.na
-\fB\fBEINVAL\fR\fR
-.ad
-.RS 10n
-The value specified by \fImutex\fR is invalid.
-.RE
-
-.SH ATTRIBUTES
-.sp
-.LP
-See \fBattributes\fR(7) for descriptions of the following attributes:
-.sp
-
-.sp
-.TS
-box;
-c | c
-l | l .
-ATTRIBUTE TYPE ATTRIBUTE VALUE
-_
-Interface Stability Standard
-_
-MT-Level MT-Safe
-.TE
-
-.SH SEE ALSO
-.sp
-.LP
-.BR pthread_cond_wait (3C),
-.BR pthread_mutex_lock (3C),
-.BR pthread_mutexattr_setprioceiling (3C),
-.BR pthread_mutexattr_setprotocol (3C),
-.BR pthread_mutexattr_setpshared (3C),
-.BR pthread_mutexattr_setrobust (3C),
-.BR pthread_mutexattr_settype (3C),
-.BR attributes (7),
-.BR mutex (7),
-.BR standards (7)
+.It Er EINVAL
+The value specified by
+.Fa attr
+or
+.Fa mutex
+is invalid.
+.El
+.Pp
+The
+.Fn pthread_mutex_destroy
+function may fail if:
+.Bl -tag -width Er
+.It Er EBUSY
+An attempt was detected to destroy the object referenced by
+.Fa mutex
+while it is locked or referenced
+.Po
+for example, while being used in a
+.Xr pthread_cond_wait 3C
+or
+.Xr pthread_cond_timedwait 3C
+.Pc
+by another thread.
+.It Er EINVAL
+The value specified by
+.Fa mutex
+is invalid.
+.El
+.Sh INTERFACE STABILITY
+.Sy Committed
+.Sh MT-LEVEL
+.Sy MT-Safe
+.Sh SEE ALSO
+.Xr pthread_cond_timedwait 3C ,
+.Xr pthread_cond_wait 3C ,
+.Xr pthread_muteattr_init 3C ,
+.Xr pthread_mutex_lock 3C ,
+.Xr pthread_mutexattr_init 3C ,
+.Xr pthread_mutexattr_setrobust 3C ,
+.Xr pthread_mutexattr_settype 3C ,
+.Xr attributes 7 ,
+.Xr mutex 7
diff --git a/usr/src/man/man3head/pthread.h.3head b/usr/src/man/man3head/pthread.h.3head
index 174969ad5f..d5094d2b2d 100644
--- a/usr/src/man/man3head/pthread.h.3head
+++ b/usr/src/man/man3head/pthread.h.3head
@@ -42,133 +42,114 @@
.\"
.\" Copyright (c) 2001, The IEEE and The Open Group. All Rights Reserved.
.\" Portions Copyright (c) 2008, Sun Microsystems, Inc. All Rights Reserved.
+.\" Copyright 2022 OmniOS Community Edition (OmniOSce) Association.
.\"
-.TH PTHREAD.H 3HEAD "Nov 11, 2008"
-.SH NAME
-pthread.h, pthread \- threads
-.SH SYNOPSIS
-.LP
-.nf
-#include <\fBpthread.h\fR>
-.fi
-
-.SH DESCRIPTION
-.sp
-.LP
-The <\fBpthread.h\fR> header defines the following symbols:
-.sp
-.in +2
-.nf
-PTHREAD_BARRIER_SERIAL_THREAD
-PTHREAD_CANCEL_ASYNCHRONOUS
-PTHREAD_CANCEL_ENABLE
-PTHREAD_CANCEL_DEFERRED
-PTHREAD_CANCEL_DISABLE
-PTHREAD_CANCELED
-PTHREAD_COND_INITIALIZER
-PTHREAD_CREATE_DETACHED
-PTHREAD_CREATE_JOINABLE
-PTHREAD_EXPLICIT_SCHED
-PTHREAD_INHERIT_SCHED
-PTHREAD_MUTEX_DEFAULT
-PTHREAD_MUTEX_ERRORCHECK
-PTHREAD_MUTEX_INITIALIZER
-PTHREAD_MUTEX_NORMAL
-PTHREAD_MUTEX_RECURSIVE
-PTHREAD_MUTEX_ROBUST
-PTHREAD_MUTEX_STALLED
-PTHREAD_ONCE_INIT
-PTHREAD_PRIO_INHERIT
-PTHREAD_PRIO_NONE
-PTHREAD_PRIO_PROTECT
-PTHREAD_PROCESS_SHARED
-PTHREAD_PROCESS_PRIVATE
-PTHREAD_RWLOCK_INITIALIZER
-PTHREAD_SCOPE_PROCESS
-PTHREAD_SCOPE_SYSTEM
-.fi
-.in -2
-
-.sp
-.LP
-The types listed below are defined as described in <\fBsys/types.h\fR>. See
-\fBtypes.h\fR(3HEAD).
-.sp
-.in +2
-.nf
-pthread_attr_t
-pthread_barrier_t
-pthread_barrierattr_t
-pthread_cond_t
-pthread_condattr_t
-pthread_key_t
-pthread_mutex_t
-pthread_mutexattr_t
-pthread_once_t
-pthread_rwlock_t
-pthread_rwlockattr_t
-pthread_spinlock_t
-pthread_t
-.fi
-.in -2
-
-.SH ATTRIBUTES
-.sp
-.LP
-See \fBattributes\fR(7) for descriptions of the following attributes:
-.sp
-
-.sp
-.TS
-box;
-c | c
-l | l .
-ATTRIBUTE TYPE ATTRIBUTE VALUE
-_
-Interface Stability Standard
-.TE
-
-.SH SEE ALSO
-.sp
-.LP
-.BR pthread_attr_getguardsize (3C),
-.BR pthread_attr_init (3C),
-.BR pthread_attr_setscope (3C),
-.BR pthread_cancel (3C),
-.BR pthread_cleanup_pop (3C),
-.BR pthread_cond_init (3C),
-.BR pthread_cond_signal (3C),
-.BR pthread_cond_wait (3C),
-.BR pthread_condattr_init (3C),
-.BR pthread_create (3C),
-.BR pthread_detach (3C),
-.BR pthread_equal (3C),
-.BR pthread_exit (3C),
-.BR pthread_getconcurrency (3C),
-.BR pthread_getschedparam (3C),
-.BR pthread_join (3C),
-.BR pthread_key_create (3C),
-.BR pthread_key_delete (3C),
-.BR pthread_mutex_consistent (3C),
-.BR pthread_mutex_init (3C),
-.BR pthread_mutex_lock (3C),
-.BR pthread_mutex_setprioceiling (3C),
-.BR pthread_mutexattr_getprotocol (3C),
-.BR pthread_mutexattr_getrobust (3C),
-.BR pthread_mutexattr_gettype (3C),
-.BR pthread_mutexattr_init (3C),
-.BR pthread_once (3C),
-.BR pthread_rwlock_init (3C),
-.BR pthread_rwlock_rdlock (3C),
-.BR pthread_rwlock_unlock (3C),
-.BR pthread_rwlock_wrlock (3C),
-.BR pthread_rwlockattr_getpshared (3C),
-.BR pthread_rwlockattr_init (3C),
-.BR pthread_self (3C),
-.BR pthread_setcancelstate (3C),
-.BR pthread_setspecific (3C),
-.BR sched.h (3HEAD),
-.BR time.h (3HEAD),
-.BR types.h (3HEAD),
-.BR attributes (7),
-.BR standards (7)
+.Dd February 19, 2022
+.Dt PTHREAD.H 3HEAD
+.Os
+.Sh NAME
+.Nm pthread.h ,
+.Nm pthread
+.Nd threads
+.Sh SYNOPSIS
+.In pthread.h
+.Sh DESCRIPTION
+The
+.In pthread.h
+header defines the following symbols:
+.Pp
+.Bl -inset -offset Ds -compact
+.It Dv PTHREAD_BARRIER_SERIAL_THREAD
+.It Dv PTHREAD_CANCEL_ASYNCHRONOUS
+.It Dv PTHREAD_CANCEL_ENABLE
+.It Dv PTHREAD_CANCEL_DEFERRED
+.It Dv PTHREAD_CANCEL_DISABLE
+.It Dv PTHREAD_CANCELED
+.It Dv PTHREAD_COND_INITIALIZER
+.It Dv PTHREAD_CREATE_DETACHED
+.It Dv PTHREAD_CREATE_JOINABLE
+.It Dv PTHREAD_EXPLICIT_SCHED
+.It Dv PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP
+.It Dv PTHREAD_INHERIT_SCHED
+.It Dv PTHREAD_MUTEX_DEFAULT
+.It Dv PTHREAD_MUTEX_ERRORCHECK
+.It Dv PTHREAD_MUTEX_INITIALIZER
+.It Dv PTHREAD_MUTEX_NORMAL
+.It Dv PTHREAD_MUTEX_RECURSIVE
+.It Dv PTHREAD_MUTEX_ROBUST
+.It Dv PTHREAD_MUTEX_STALLED
+.It Dv PTHREAD_ONCE_INIT
+.It Dv PTHREAD_PRIO_INHERIT
+.It Dv PTHREAD_PRIO_NONE
+.It Dv PTHREAD_PRIO_PROTECT
+.It Dv PTHREAD_PROCESS_SHARED
+.It Dv PTHREAD_PROCESS_PRIVATE
+.It Dv PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP
+.It Dv PTHREAD_RWLOCK_INITIALIZER
+.It Dv PTHREAD_SCOPE_PROCESS
+.It Dv PTHREAD_SCOPE_SYSTEM
+.El
+.Pp
+The types listed below are defined as described in
+.In sys/types.h .
+See
+.Xr types.h 3HEAD .
+.Pp
+.Bl -inset -offset Ds -compact
+.It Vt pthread_attr_t
+.It Vt pthread_barrier_t
+.It Vt pthread_barrierattr_t
+.It Vt pthread_cond_t
+.It Vt pthread_condattr_t
+.It Vt pthread_key_t
+.It Vt pthread_mutex_t
+.It Vt pthread_mutexattr_t
+.It Vt pthread_once_t
+.It Vt pthread_rwlock_t
+.It Vt pthread_rwlockattr_t
+.It Vt pthread_spinlock_t
+.It Vt pthread_t
+.El
+.Sh INTERFACE STABILITY
+.Sy Committed
+.Sh SEE ALSO
+.Xr pthread_attr_getguardsize 3C ,
+.Xr pthread_attr_init 3C ,
+.Xr pthread_attr_setscope 3C ,
+.Xr pthread_cancel 3C ,
+.Xr pthread_cleanup_pop 3C ,
+.Xr pthread_cond_init 3C ,
+.Xr pthread_cond_signal 3C ,
+.Xr pthread_cond_wait 3C ,
+.Xr pthread_condattr_init 3C ,
+.Xr pthread_create 3C ,
+.Xr pthread_detach 3C ,
+.Xr pthread_equal 3C ,
+.Xr pthread_exit 3C ,
+.Xr pthread_getconcurrency 3C ,
+.Xr pthread_getschedparam 3C ,
+.Xr pthread_join 3C ,
+.Xr pthread_key_create 3C ,
+.Xr pthread_key_delete 3C ,
+.Xr pthread_mutex_consistent 3C ,
+.Xr pthread_mutex_init 3C ,
+.Xr pthread_mutex_lock 3C ,
+.Xr pthread_mutex_setprioceiling 3C ,
+.Xr pthread_mutexattr_getprotocol 3C ,
+.Xr pthread_mutexattr_getrobust 3C ,
+.Xr pthread_mutexattr_gettype 3C ,
+.Xr pthread_mutexattr_init 3C ,
+.Xr pthread_once 3C ,
+.Xr pthread_rwlock_init 3C ,
+.Xr pthread_rwlock_rdlock 3C ,
+.Xr pthread_rwlock_unlock 3C ,
+.Xr pthread_rwlock_wrlock 3C ,
+.Xr pthread_rwlockattr_getpshared 3C ,
+.Xr pthread_rwlockattr_init 3C ,
+.Xr pthread_self 3C ,
+.Xr pthread_setcancelstate 3C ,
+.Xr pthread_setspecific 3C ,
+.Xr sched.h 3HEAD ,
+.Xr time.h 3HEAD ,
+.Xr types.h 3HEAD ,
+.Xr attributes 7