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