9.63 futex

struct futex_item {
    uint64_t addr;
    uint32_t expected;
    uint32_t flags;
};

#define FUTEX_WAIT 1
#define FUTEX_WAKE 2

int futex(int operation, struct futex_item *futexes, size_t count,
    struct timespec *time);

This syscall helps implement fast userland mutexes (futexes!). It is typically used as a blocking construct in the context of shared-memory synchronization.

When using futexes, the majority of the synchronization operations are performed in user space by atomically testing for a 32-bit value. User-space is to use futex only when it is likely that the program has to block for a longer time until the condition becomes true. Other futex operations can be used to wake any processes or threads waiting for an address.

When executing a futex operation that requests to block a thread, the kernel will block only if the futex contents has the value that the call suplied under expected. The loading of the futex’s contents and comparison of that value are atomic, and will be totally ordered with respect to concurrent operations performed by other threads on the same futex contents. Thus, the futex contents are used to connect the synchronization in user space with the implementation of blocking by the kernel. Analogously to an atomic compare-and-exchange operation that potentially changes shared memory, blocking via a futex is an atomic compare-and-block operation. When blocked, the kernel will calmly wait for waking by FUTEX_WAKE, waking is not automatic once the values are acquired.

Note that no explicit initialization or destruction is necessary to use futexes; the kernel maintains a futex only while operations such as FUTEX_WAIT are being performed on particular futex contents.

When compared with other implementations like Linux’s, Ironclad’s allows for waiting and waking several futexes at once, this is done as to ease handling several futexes at once.

The available futex operations are:

FUTEX_WAIT

The passed values in futexes will be waited for.

FUTEX_WAKE

The passed values in futexes will be woken up.

The syscall returns 0 on success or -1 on failure, with the following errno:

EFAULT

The passed addresses would fault if accessed.

EINVAL

The passed operation is not valid.