xref: /freebsd/share/man/man4/ntsync.4 (revision 65251c43415aa0993b7d43962cbb71d772870c83)
1f6b37f47SKonstantin Belousov.\"
2f6b37f47SKonstantin Belousov.\" SPDX-License-Identifier: BSD-2-Clause
3f6b37f47SKonstantin Belousov.\"
4f6b37f47SKonstantin Belousov.\" Copyright 2026 The FreeBSD Foundation
5f6b37f47SKonstantin Belousov.\"
6f6b37f47SKonstantin Belousov.\" This documentation was written by Konstantin Belousov <kib@FreeBSD.org>
7f6b37f47SKonstantin Belousov.\" under sponsorship from the FreeBSD Foundation.
8f6b37f47SKonstantin Belousov.\"
9f6b37f47SKonstantin Belousov.Dd June 19, 2026
10f6b37f47SKonstantin Belousov.Dt NTSYNC 4
11f6b37f47SKonstantin Belousov.Os
12f6b37f47SKonstantin Belousov.Sh NAME
13f6b37f47SKonstantin Belousov.Nm ntsync
14f6b37f47SKonstantin Belousov.Nd NT-like synchronization operations device driver
15f6b37f47SKonstantin Belousov.Sh SYNOPSIS
16f6b37f47SKonstantin Belousov.In dev/ntsync/ntsync.h
17f6b37f47SKonstantin Belousov.Sh DESCRIPTION
18f6b37f47SKonstantin BelousovThe
19f6b37f47SKonstantin Belousov.Nm
20f6b37f47SKonstantin Belousovdevice driver provides synchronization primitives that mimic the operations
21f6b37f47SKonstantin Belousovprovided by the Windows NT kernel.
22f6b37f47SKonstantin BelousovThe userspace interface is copied from the identically named driver written
23f6b37f47SKonstantin Belousovfor the Linux kernel, with the goal of helping Wine implement Win32 API.
24f6b37f47SKonstantin Belousov.Pp
25f6b37f47SKonstantin BelousovThe driver provides the
26f6b37f47SKonstantin Belousov.Pa /dev/ntsync
27f6b37f47SKonstantin Belousovspecial device node that handles
28f6b37f47SKonstantin Belousov.Xr ioctl 2
29f6b37f47SKonstantin Belousovrequests of several groups:
30f6b37f47SKonstantin Belousov.Bl -tag -width "wait operations:"
31f6b37f47SKonstantin Belousov.It object creation:
32f6b37f47SKonstantin Belousovamong them semaphores, mutexes, and events
33f6b37f47SKonstantin Belousov.It wait operations:
34f6b37f47SKonstantin Belousovwaiting for the set of objects to become signaled, either all
35f6b37f47SKonstantin Belousovor any objects in the set can be waited for
36f6b37f47SKonstantin Belousov.El
37f6b37f47SKonstantin Belousov.Pp
38f6b37f47SKonstantin BelousovAn
39f6b37f47SKonstantin Belousov.Xr open 2
40f6b37f47SKonstantin Belousovof the
41f6b37f47SKonstantin Belousov.Pa /dev/ntsync
42f6b37f47SKonstantin Belousovdevice returns the file descriptor which represents the synchronization
43f6b37f47SKonstantin Belousovdomain.
44f6b37f47SKonstantin BelousovEach object created by the
45f6b37f47SKonstantin Belousov.Xr ioctl 2
46f6b37f47SKonstantin Belousovon the ntsync file descriptor belongs to it's domain.
47f6b37f47SKonstantin BelousovWait requests must not mix the objects belonging to other domains.
48f6b37f47SKonstantin Belousov.Pp
49f6b37f47SKonstantin BelousovThe synchronization objects are represented by file descriptors, each
50f6b37f47SKonstantin Belousovimplementing type-specific set of ioctl requests.
51f6b37f47SKonstantin Belousov.Sh SEMAPHORES
52f6b37f47SKonstantin BelousovThe semaphores operations usually take the
53f6b37f47SKonstantin Belousov.Bd -literal
54f6b37f47SKonstantin Belousovstruct ntsync_sem_args {
55f6b37f47SKonstantin Belousov	uint32_t count;
56f6b37f47SKonstantin Belousov	uint32_t max;
57f6b37f47SKonstantin Belousov}
58f6b37f47SKonstantin Belousov.Ed
59f6b37f47SKonstantin Belousovas an argument.
60f6b37f47SKonstantin BelousovThe semaphore requests are:
61f6b37f47SKonstantin Belousov.Bl -tag -width "NTSYNC_IOC_SEM_RELEASE"
62f6b37f47SKonstantin Belousov.It Dv NTSYNC_IOC_CREATE_SEM
63f6b37f47SKonstantin BelousovCreates the semaphore and returns the semaphore file descriptor.
64f6b37f47SKonstantin BelousovMust be issued on the
65f6b37f47SKonstantin Belousov.Pa /dev/ntsync
66f6b37f47SKonstantin Belousovfile descriptor.
67f6b37f47SKonstantin Belousov.Pp
68f6b37f47SKonstantin BelousovTakes the
69f6b37f47SKonstantin Belousov.Va struct ntsync_sem_args
70f6b37f47SKonstantin Belousovargument, where
71f6b37f47SKonstantin Belousov.Dv count
72f6b37f47SKonstantin Belousovis the initial semaphore count, and
73f6b37f47SKonstantin Belousov.Dv max
74f6b37f47SKonstantin Belousovis the maximum allowed count.
75f6b37f47SKonstantin Belousov.It Dv NTSYNC_IOC_SEM_RELEASE
76f6b37f47SKonstantin BelousovReleases the semaphore.
77f6b37f47SKonstantin BelousovTakes the single
78f6b37f47SKonstantin Belousov.Va uint32_t
79f6b37f47SKonstantin Belousovvalue which is used to decrement the semaphore count.
80f6b37f47SKonstantin BelousovIf the semaphore count reaches zero, the semaphore becomes signaled.
81f6b37f47SKonstantin Belousov.It Dv NTSYNC_IOC_SEM_READ
82f6b37f47SKonstantin BelousovReturns the current state of the semaphore in the
83f6b37f47SKonstantin Belousov.Va struct ntsync_sem_args .
84f6b37f47SKonstantin Belousov.El
85f6b37f47SKonstantin Belousov.Sh MUTEXES
86f6b37f47SKonstantin BelousovThe mutexes operations usually take the
87f6b37f47SKonstantin Belousov.Bd -literal
88f6b37f47SKonstantin Belousovstruct ntsync_mutex_args {
89f6b37f47SKonstantin Belousov	uint32_t owner;
90f6b37f47SKonstantin Belousov	uint32_t count;
91f6b37f47SKonstantin Belousov}
92f6b37f47SKonstantin Belousov.Ed
93f6b37f47SKonstantin Belousovas the argument.
94f6b37f47SKonstantin Belousov.Pp
95f6b37f47SKonstantin BelousovThe mutex requests are:
96f6b37f47SKonstantin Belousov.Bl -tag -width "NTSYNC_IOC_CREATE_MUTEX"
97f6b37f47SKonstantin Belousov.It Dv NTSYNC_IOC_CREATE_MUTEX
98f6b37f47SKonstantin BelousovCreates the mutex and returns the mutex file descriptor.
99f6b37f47SKonstantin BelousovMust be issued on the
100f6b37f47SKonstantin Belousov.Pa /dev/ntsync
101f6b37f47SKonstantin Belousovfile descriptor.
102f6b37f47SKonstantin Belousov.Pp
103f6b37f47SKonstantin BelousovTakes the
104f6b37f47SKonstantin Belousov.Va struct ntsync_mutex_args
105f6b37f47SKonstantin Belousovas the argument.
106f6b37f47SKonstantin BelousovThe
107f6b37f47SKonstantin Belousov.Dv owner
108f6b37f47SKonstantin Belousovis an abstract 32bit number that identifies the current mutex owner.
109f6b37f47SKonstantin BelousovIf
110f6b37f47SKonstantin Belousov.Dv owner
111f6b37f47SKonstantin Belousovis zero, the mutex is unowned, and
112f6b37f47SKonstantin Belousov.Dv count
113f6b37f47SKonstantin Belousovmust be zero.
114f6b37f47SKonstantin BelousovIf
115f6b37f47SKonstantin Belousov.Dv count
116f6b37f47SKonstantin Belousovis non-zero, indicating the owned mutex, a non-zero
117f6b37f47SKonstantin Belousov.Dv owner
118f6b37f47SKonstantin Belousovmust be provided.
119f6b37f47SKonstantin Belousov.It Dv NTSYNC_IOC_MUTEX_UNLOCK
120f6b37f47SKonstantin BelousovUnlocks the mutex.
121f6b37f47SKonstantin BelousovTakes the
122f6b37f47SKonstantin Belousov.Va struct ntsync_mutex_args
123f6b37f47SKonstantin Belousovargument.
124f6b37f47SKonstantin Belousov.Pp
125f6b37f47SKonstantin BelousovThe mutex must be owned by the argument's
126f6b37f47SKonstantin Belousov.Dv owner .
127f6b37f47SKonstantin BelousovSuccessful unlock decrements mutex' counter, and makes the mutex
128f6b37f47SKonstantin Belousovsignaled and unowned if the counter reaches zero.
129f6b37f47SKonstantin Belousov.Pp
130f6b37f47SKonstantin BelousovThe counter value before unlock is returned in the
131f6b37f47SKonstantin Belousov.Dv count
132f6b37f47SKonstantin Belousovmember of the argument structure.
133f6b37f47SKonstantin Belousov.It Dv NTSYNC_IOC_MUTEX_KILL
134f6b37f47SKonstantin BelousovAbandon the mutex.
135f6b37f47SKonstantin BelousovTakes a single 32bit integer as the argument, indicating the current
136f6b37f47SKonstantin Belousovmutex owner.
137f6b37f47SKonstantin Belousov.Pp
138f6b37f47SKonstantin BelousovThe specified owner must be equal to the current mutex owner.
139f6b37f47SKonstantin BelousovThen, the pending waiters are woken up, and get the
140f6b37f47SKonstantin Belousov.Ev EOWNERDEAD
141f6b37f47SKonstantin Belousovresult.
142f6b37f47SKonstantin BelousovThe mutex owner and counter are set to zero.
143f6b37f47SKonstantin Belousov.Pp
144f6b37f47SKonstantin BelousovThe abandoned state is cleared by next successful wait on the mutex.
145f6b37f47SKonstantin Belousov.It Dv NTSYNC_IOC_MUTEX_READ
146f6b37f47SKonstantin BelousovReturns the current state of the mutex.
147f6b37f47SKonstantin BelousovTakes the
148f6b37f47SKonstantin Belousov.Va struct ntsync_mutex_args
149f6b37f47SKonstantin Belousovargument where the state is returned.
150f6b37f47SKonstantin BelousovFor abandoned mutexes, the
151f6b37f47SKonstantin Belousov.Ev EOWNERDEAD
152f6b37f47SKonstantin Belousoverror is returned in addition to the state.
153f6b37f47SKonstantin Belousov.El
154f6b37f47SKonstantin Belousov.Sh EVENTS
155f6b37f47SKonstantin BelousovThe events operations usually take the
156f6b37f47SKonstantin Belousov.Bd -literal
157f6b37f47SKonstantin Belousovstruct ntsync_event_args {
158f6b37f47SKonstantin Belousov	uint32_t manual;
159f6b37f47SKonstantin Belousov	uint32_t signaled;
160f6b37f47SKonstantin Belousov}
161f6b37f47SKonstantin Belousov.Ed
162f6b37f47SKonstantin Belousov.Pp
163f6b37f47SKonstantin BelousovThe events requests are:
164f6b37f47SKonstantin Belousov.Bl -tag -width "NTSYNC_IOC_CREATE_EVENT"
165f6b37f47SKonstantin Belousov.It Dv NTSYNC_IOC_CREATE_EVENT
166f6b37f47SKonstantin BelousovCreates the event and returns the event file descriptor.
167f6b37f47SKonstantin BelousovMust be issued on the
168f6b37f47SKonstantin Belousov.Pa /dev/ntsync
169f6b37f47SKonstantin Belousovfile descriptor.
170f6b37f47SKonstantin BelousovTakes the
171f6b37f47SKonstantin Belousov.Va struct ntsync_event_args
172f6b37f47SKonstantin Belousovargument.
173f6b37f47SKonstantin Belousov.Pp
174f6b37f47SKonstantin BelousovEvents can be of two types: manual and automatic.
175f6b37f47SKonstantin BelousovManual events needs to be reset by the request after being set.
176f6b37f47SKonstantin BelousovAutomatic events are reset by the system after a wait is satisfied.
177f6b37f47SKonstantin Belousov.It Dv NTSYNC_IOC_EVENT_SET
178f6b37f47SKonstantin BelousovSet (arm) the event.
179f6b37f47SKonstantin BelousovTakes a 32bit integer argument where the state of the event before
180f6b37f47SKonstantin Belousovthe operation is returned.
181f6b37f47SKonstantin Belousov.It Dv NTSYNC_IOC_EVENT_RESET
182f6b37f47SKonstantin BelousovReset (dis-arms) the event.
183f6b37f47SKonstantin BelousovTakes a 32bit integer argument where the state of the event before
184f6b37f47SKonstantin Belousovthe operation is returned.
185f6b37f47SKonstantin Belousov.It Dv NTSYNC_IOC_EVENT_PULSE
186*65251c43SKonstantin BelousovAtomically sets the event, wakes up eligible waiters,
187*65251c43SKonstantin Belousovand then resets the event.
188f6b37f47SKonstantin BelousovTakes a 32bit integer argument where the state of the event before
189f6b37f47SKonstantin Belousovthe operation is returned.
190*65251c43SKonstantin Belousov.Pp
191*65251c43SKonstantin BelousovIf the manual event is pulsed, it wakes up all waiters,
192*65251c43SKonstantin Belousovafter which it is reset.
193*65251c43SKonstantin BelousovOn the other hand, the automatic event is reset after
194*65251c43SKonstantin Belousovwaking up at most a single waiter.
195f6b37f47SKonstantin Belousov.It Dv NTSYNC_IOC_EVENT_READ
196f6b37f47SKonstantin BelousovReturns the current state of the event.
197f6b37f47SKonstantin BelousovTakes the
198f6b37f47SKonstantin Belousov.Va struct ntsync_event_args
199f6b37f47SKonstantin Belousovargument where the current event state is returned.
200f6b37f47SKonstantin Belousov.El
201f6b37f47SKonstantin Belousov.Sh WAIT OPERATIONS
202f6b37f47SKonstantin BelousovWait operations take the
203f6b37f47SKonstantin Belousov.Bd -literal
204f6b37f47SKonstantin Belousovstruct ntsync_wait_args {
205f6b37f47SKonstantin Belousov	uint64_t timeout;
206f6b37f47SKonstantin Belousov	uint64_t objs;
207f6b37f47SKonstantin Belousov	uint32_t count;
208f6b37f47SKonstantin Belousov	uint32_t index;
209f6b37f47SKonstantin Belousov	uint32_t flags;
210f6b37f47SKonstantin Belousov	uint32_t owner;
211f6b37f47SKonstantin Belousov	uint32_t alert;
212f6b37f47SKonstantin Belousov	uint32_t pad;
213f6b37f47SKonstantin Belousov}
214f6b37f47SKonstantin Belousov.Ed
215f6b37f47SKonstantin Belousovas the argument.
216f6b37f47SKonstantin Belousov.Pp
217f6b37f47SKonstantin BelousovThe signaled state of the objects which cause the wait to
218f6b37f47SKonstantin Belousovbecome satisfied are consumed by the operation,
219f6b37f47SKonstantin Belousove.g. the semaphore is acquired by incrementing its counter,
220f6b37f47SKonstantin Belousovthe mutex is locked,
221f6b37f47SKonstantin Belousovand the manual event becomes not signaled.
222f6b37f47SKonstantin Belousov.Pp
223f6b37f47SKonstantin BelousovThe
224f6b37f47SKonstantin Belousov.Dv timeout
225f6b37f47SKonstantin Belousovis in the nanoseconds.
226f6b37f47SKonstantin BelousovIf
227f6b37f47SKonstantin Belousov.Dv timeout
228f6b37f47SKonstantin Belousovis zero, the wait request only returns when either the wait
229f6b37f47SKonstantin Belousovcondition is satisfied, or a signal is queued.
230f6b37f47SKonstantin BelousovOtherwise, if the wait is not satisfied after the specified time,
231f6b37f47SKonstantin Belousovit is aborted anyway and the
232f6b37f47SKonstantin Belousov.Er ETIMEDOUT
233f6b37f47SKonstantin Belousoverror is returned.
234f6b37f47SKonstantin Belousov.Pp
235f6b37f47SKonstantin BelousovThe
236f6b37f47SKonstantin Belousov.Dv objs
237f6b37f47SKonstantin Belousovmember points to the array of the synchronization object's file
238f6b37f47SKonstantin Belousovdescriptors.
239f6b37f47SKonstantin BelousovIts size if passed in the
240f6b37f47SKonstantin Belousov.Dv count
241f6b37f47SKonstantin Belousovmember.
242f6b37f47SKonstantin BelousovIt might be as large as
243f6b37f47SKonstantin Belousov.Dv NTSYNC_MAX_WAIT_COUNT ,
244f6b37f47SKonstantin Belousovwhich is 64.
245f6b37f47SKonstantin Belousov.Pp
246f6b37f47SKonstantin BelousovThe
247f6b37f47SKonstantin Belousov.Dv alert
248f6b37f47SKonstantin Belousovif non-zero specifies the event file descriptor,
249f6b37f47SKonstantin Belousovsignaling of which finishes the wait regardless the state of
250f6b37f47SKonstantin Belousovother objects in the
251f6b37f47SKonstantin Belousov.Dv objs
252f6b37f47SKonstantin Belousovarray.
253f6b37f47SKonstantin Belousov.Pp
254f6b37f47SKonstantin BelousovOn non-error return from the wait requests, the
255f6b37f47SKonstantin Belousov.Dv index
256f6b37f47SKonstantin Belousovmember contains the index of the signaled object that caused
257f6b37f47SKonstantin Belousovthe wait request to be satisfied.
258f6b37f47SKonstantin BelousovIf the object at the index is a semaphore, the
259f6b37f47SKonstantin Belousov.Dv owner
260f6b37f47SKonstantin Belousovmember reports the owner of the signaled semaphore.
261f6b37f47SKonstantin BelousovIf the
262f6b37f47SKonstantin Belousov.Dv alert
263f6b37f47SKonstantin Belousovevent was signaled to abort the wait,
264f6b37f47SKonstantin Belousov.Dv index
265f6b37f47SKonstantin Belousovis set to
266f6b37f47SKonstantin Belousov.Dv count .
267f6b37f47SKonstantin Belousov.Pp
268f6b37f47SKonstantin BelousovThe possible values for the
269f6b37f47SKonstantin Belousov.Va flags
270f6b37f47SKonstantin Belousovparameter are
271f6b37f47SKonstantin Belousov.Bl -tag -width "NTSYNC_WAIT_REALTIME"
272f6b37f47SKonstantin Belousov.It Dv NTSYNC_WAIT_REALTIME
273f6b37f47SKonstantin BelousovThe specified timeout is for
274f6b37f47SKonstantin Belousov.Dv CLOCK_REALTIME
275f6b37f47SKonstantin Belousovabsolute value, otherwise it is for
276f6b37f47SKonstantin Belousov.Dv CLOCK_MONOTONIC ,
277f6b37f47SKonstantin Belousovsee
278f6b37f47SKonstantin Belousov.Xr clock_gettime 2 .
279f6b37f47SKonstantin Belousov.El
280f6b37f47SKonstantin Belousov.Pp
281f6b37f47SKonstantin BelousovThe wait requests are:
282f6b37f47SKonstantin Belousov.Bl -tag -width "NTSYNC_IOC_WAIT_ANY"
283f6b37f47SKonstantin Belousov.It Dv NTSYNC_IOC_WAIT_ANY
284f6b37f47SKonstantin BelousovWait for any of the objects to become signaled.
285f6b37f47SKonstantin Belousov.It Dv NTSYNC_IOC_WAIT_ALL
286f6b37f47SKonstantin BelousovWait for all of the objects to become signaled.
287f6b37f47SKonstantin BelousovThis means that the wait is satisfied only when all objects
288f6b37f47SKonstantin Belousovcan be consumed together, which is done atomically.
289f6b37f47SKonstantin Belousov.Pp
290f6b37f47SKonstantin BelousovNo duplicate objects are allowed in the
291f6b37f47SKonstantin Belousov.Dv objs
292f6b37f47SKonstantin Belousovarray.
293f6b37f47SKonstantin BelousovThe
294f6b37f47SKonstantin Belousov.Dv alert
295f6b37f47SKonstantin Belousovobject is not allowed to be listed in the
296f6b37f47SKonstantin Belousov.Dv objs
297f6b37f47SKonstantin Belousovarray.
298f6b37f47SKonstantin Belousov.El
299f6b37f47SKonstantin Belousov.Sh SEE ALSO
300f6b37f47SKonstantin BelousovRefer to the file
301f6b37f47SKonstantin Belousov.Pa Documentation/userspace-api/ntsync.rst
302f6b37f47SKonstantin Belousovin the Linux kernel sources for the Linux API reference,
303f6b37f47SKonstantin Belousovthat was used for the implementation of the
304f6b37f47SKonstantin Belousov.Fx
305f6b37f47SKonstantin Belousovdriver.
306f6b37f47SKonstantin Belousov.Sh HISTORY
307f6b37f47SKonstantin BelousovThe
308f6b37f47SKonstantin Belousov.Nm
309f6b37f47SKonstantin Belousovdriver and manual page first appeared in
310f6b37f47SKonstantin Belousov.Fx 15.2 .
311f6b37f47SKonstantin Belousov.Sh AUTHORS
312f6b37f47SKonstantin Belousov.An -nosplit
313f6b37f47SKonstantin BelousovThe driver and the manual page were written by
314f6b37f47SKonstantin Belousov.An Konstantin Belousov Aq Mt kib@FreeBSD.org .
315