src - FreeBSD source tree

5 min read Original article ↗

Reviewed by: ziaee Discussed with: Alex S <iwtcex@gmail.com> Sponsored by: The FreeBSD Foundation MFC after: 3 days Differential revision: https://reviews.freebsd.org/D57659

@@ -438,6 +438,7 @@ MAN= aac.4 \

${_ntb_hw_intel.4} \

${_ntb_hw_plx.4} \

${_ntb_transport.4} \

+ ntsync.4 \

${_nda.4} \

${_if_ntb.4} \

null.4 \

diff --git a/share/man/man4/ntsync.4 b/share/man/man4/ntsync.4
new file mode 100644
index 000000000000..2776a4b0e691
--- /dev/null
+++ b/share/man/man4/ntsync.4

@@ -0,0 +1,308 @@

+.\"

+.\" SPDX-License-Identifier: BSD-2-Clause

+.\"

+.\" Copyright 2026 The FreeBSD Foundation

+.\"

+.\" This documentation was written by Konstantin Belousov <kib@FreeBSD.org>

+.\" under sponsorship from the FreeBSD Foundation.

+.\"

+.Dd June 19, 2026

+.Dt NTSYNC 4

+.Os

+.Sh NAME

+.Nm ntsync

+.Nd NT-like synchronization operations device driver

+.Sh SYNOPSIS

+.In dev/ntsync/ntsync.h

+.Sh DESCRIPTION

+The

+.Nm

+device driver provides synchronization primitives that mimic the operations

+provided by the Windows NT kernel.

+The userspace interface is copied from the identically named driver written

+for the Linux kernel, with the goal of helping Wine implement Win32 API.

+.Pp

+The driver provides the

+.Pa /dev/ntsync

+special device node that handles

+.Xr ioctl 2

+requests of several groups:

+.Bl -tag -width "wait operations:"

+.It object creation:

+among them semaphores, mutexes, and events

+.It wait operations:

+waiting for the set of objects to become signaled, either all

+or any objects in the set can be waited for

+.El

+.Pp

+An

+.Xr open 2

+of the

+.Pa /dev/ntsync

+device returns the file descriptor which represents the synchronization

+domain.

+Each object created by the

+.Xr ioctl 2

+on the ntsync file descriptor belongs to it's domain.

+Wait requests must not mix the objects belonging to other domains.

+.Pp

+The synchronization objects are represented by file descriptors, each

+implementing type-specific set of ioctl requests.

+.Sh SEMAPHORES

+The semaphores operations usually take the

+.Bd -literal

+struct ntsync_sem_args {

+ uint32_t count;

+ uint32_t max;

+}

+.Ed

+as an argument.

+The semaphore requests are:

+.Bl -tag -width "NTSYNC_IOC_SEM_RELEASE"

+.It Dv NTSYNC_IOC_CREATE_SEM

+Creates the semaphore and returns the semaphore file descriptor.

+Must be issued on the

+.Pa /dev/ntsync

+file descriptor.

+.Pp

+Takes the

+.Va struct ntsync_sem_args

+argument, where

+.Dv count

+is the initial semaphore count, and

+.Dv max

+is the maximum allowed count.

+.It Dv NTSYNC_IOC_SEM_RELEASE

+Releases the semaphore.

+Takes the single

+.Va uint32_t

+value which is used to decrement the semaphore count.

+If the semaphore count reaches zero, the semaphore becomes signaled.

+.It Dv NTSYNC_IOC_SEM_READ

+Returns the current state of the semaphore in the

+.Va struct ntsync_sem_args .

+.El

+.Sh MUTEXES

+The mutexes operations usually take the

+.Bd -literal

+struct ntsync_mutex_args {

+ uint32_t owner;

+ uint32_t count;

+}

+.Ed

+as the argument.

+.Pp

+The mutex requests are:

+.Bl -tag -width "NTSYNC_IOC_CREATE_MUTEX"

+.It Dv NTSYNC_IOC_CREATE_MUTEX

+Creates the mutex and returns the mutex file descriptor.

+Must be issued on the

+.Pa /dev/ntsync

+file descriptor.

+.Pp

+Takes the

+.Va struct ntsync_mutex_args

+as the argument.

+The

+.Dv owner

+is an abstract 32bit number that identifies the current mutex owner.

+If

+.Dv owner

+is zero, the mutex is unowned, and

+.Dv count

+must be zero.

+If

+.Dv count

+is non-zero, indicating the owned mutex, a non-zero

+.Dv owner

+must be provided.

+.It Dv NTSYNC_IOC_MUTEX_UNLOCK

+Unlocks the mutex.

+Takes the

+.Va struct ntsync_mutex_args

+argument.

+.Pp

+The mutex must be owned by the argument's

+.Dv owner .

+Successful unlock decrements mutex' counter, and makes the mutex

+signaled and unowned if the counter reaches zero.

+.Pp

+The counter value before unlock is returned in the

+.Dv count

+member of the argument structure.

+.It Dv NTSYNC_IOC_MUTEX_KILL

+Abandon the mutex.

+Takes a single 32bit integer as the argument, indicating the current

+mutex owner.

+.Pp

+The specified owner must be equal to the current mutex owner.

+Then, the pending waiters are woken up, and get the

+.Ev EOWNERDEAD

+result.

+The mutex owner and counter are set to zero.

+.Pp

+The abandoned state is cleared by next successful wait on the mutex.

+.It Dv NTSYNC_IOC_MUTEX_READ

+Returns the current state of the mutex.

+Takes the

+.Va struct ntsync_mutex_args

+argument where the state is returned.

+For abandoned mutexes, the

+.Ev EOWNERDEAD

+error is returned in addition to the state.

+.El

+.Sh EVENTS

+The events operations usually take the

+.Bd -literal

+struct ntsync_event_args {

+ uint32_t manual;

+ uint32_t signaled;

+}

+.Ed

+.Pp

+The events requests are:

+.Bl -tag -width "NTSYNC_IOC_CREATE_EVENT"

+.It Dv NTSYNC_IOC_CREATE_EVENT

+Creates the event and returns the event file descriptor.

+Must be issued on the

+.Pa /dev/ntsync

+file descriptor.

+Takes the

+.Va struct ntsync_event_args

+argument.

+.Pp

+Events can be of two types: manual and automatic.

+Manual events needs to be reset by the request after being set.

+Automatic events are reset by the system after a wait is satisfied.

+.It Dv NTSYNC_IOC_EVENT_SET

+Set (arm) the event.

+Takes a 32bit integer argument where the state of the event before

+the operation is returned.

+.It Dv NTSYNC_IOC_EVENT_RESET

+Reset (dis-arms) the event.

+Takes a 32bit integer argument where the state of the event before

+the operation is returned.

+.It Dv NTSYNC_IOC_EVENT_PULSE

+Atomically sets and then resets the event.

+Takes a 32bit integer argument where the state of the event before

+the operation is returned.

+.It Dv NTSYNC_IOC_EVENT_READ

+Returns the current state of the event.

+Takes the

+.Va struct ntsync_event_args

+argument where the current event state is returned.

+.El

+.Sh WAIT OPERATIONS

+Wait operations take the

+.Bd -literal

+struct ntsync_wait_args {

+ uint64_t timeout;

+ uint64_t objs;

+ uint32_t count;

+ uint32_t index;

+ uint32_t flags;

+ uint32_t owner;

+ uint32_t alert;

+ uint32_t pad;

+}

+.Ed

+as the argument.

+.Pp

+The signaled state of the objects which cause the wait to

+become satisfied are consumed by the operation,

+e.g. the semaphore is acquired by incrementing its counter,

+the mutex is locked,

+and the manual event becomes not signaled.

+.Pp

+The

+.Dv timeout

+is in the nanoseconds.

+If

+.Dv timeout

+is zero, the wait request only returns when either the wait

+condition is satisfied, or a signal is queued.

+Otherwise, if the wait is not satisfied after the specified time,

+it is aborted anyway and the

+.Er ETIMEDOUT

+error is returned.

+.Pp

+The

+.Dv objs

+member points to the array of the synchronization object's file

+descriptors.

+Its size if passed in the

+.Dv count

+member.

+It might be as large as

+.Dv NTSYNC_MAX_WAIT_COUNT ,

+which is 64.

+.Pp

+The

+.Dv alert

+if non-zero specifies the event file descriptor,

+signaling of which finishes the wait regardless the state of

+other objects in the

+.Dv objs

+array.

+.Pp

+On non-error return from the wait requests, the

+.Dv index

+member contains the index of the signaled object that caused

+the wait request to be satisfied.

+If the object at the index is a semaphore, the

+.Dv owner

+member reports the owner of the signaled semaphore.

+If the

+.Dv alert

+event was signaled to abort the wait,

+.Dv index

+is set to

+.Dv count .

+.Pp

+The possible values for the

+.Va flags

+parameter are

+.Bl -tag -width "NTSYNC_WAIT_REALTIME"

+.It Dv NTSYNC_WAIT_REALTIME

+The specified timeout is for

+.Dv CLOCK_REALTIME

+absolute value, otherwise it is for

+.Dv CLOCK_MONOTONIC ,

+see

+.Xr clock_gettime 2 .

+.El

+.Pp

+The wait requests are:

+.Bl -tag -width "NTSYNC_IOC_WAIT_ANY"

+.It Dv NTSYNC_IOC_WAIT_ANY

+Wait for any of the objects to become signaled.

+.It Dv NTSYNC_IOC_WAIT_ALL

+Wait for all of the objects to become signaled.

+This means that the wait is satisfied only when all objects

+can be consumed together, which is done atomically.

+.Pp

+No duplicate objects are allowed in the

+.Dv objs

+array.

+The

+.Dv alert

+object is not allowed to be listed in the

+.Dv objs

+array.

+.El

+.Sh SEE ALSO

+Refer to the file

+.Pa Documentation/userspace-api/ntsync.rst

+in the Linux kernel sources for the Linux API reference,

+that was used for the implementation of the

+.Fx

+driver.

+.Sh HISTORY

+The

+.Nm

+driver and manual page first appeared in

+.Fx 15.2 .

+.Sh AUTHORS

+.An -nosplit

+The driver and the manual page were written by

+.An Konstantin Belousov Aq Mt kib@FreeBSD.org .