---
name: "FUTEX_LOCK_PI"
section: "2const"
platform: "linux"
package: "man-pages"
version: "6.19-1"
release: "Arch Linux 2026-11-01"
platforms: ["linux"]
url: "https://new.carta.tech/FUTEX_LOCK_PI"
---

# FUTEX\_LOCK\_PI(2const)

lock a priority-inheritance futex

## NAME

FUTEX\_LOCK\_PI - lock a priority-inheritance futex

## LIBRARY

Standard C library (*libc*, *-lc*)

## SYNOPSIS

```
#include <linux/futex.h>  /* Definition of FUTEX_* constants */
#include <sys/syscall.h>  /* Definition of SYS_* constants */
#include <unistd.h>
```

**long syscall(SYS\_futex, uint32\_t \****uaddr***, FUTEX\_LOCK\_PI, 0,**              **const struct timespec \****timeout***);**

## DESCRIPTION

This operation is used after an attempt to acquire the lock via an atomic user-mode instruction failed because the futex word has a nonzero value—specifically, because it contained the (PID-namespace-specific) TID of the lock owner.

The operation checks the value of the futex word at the address *uaddr*. If the value is 0, then the kernel tries to atomically set the futex value to the caller's TID. If the futex word's value is nonzero, the kernel atomically sets the **FUTEX\_WAITERS** bit, which signals the futex owner that it cannot unlock the futex in user space atomically by setting the futex value to 0. After that, the kernel:

- (1)

  Tries to find the thread which is associated with the owner TID.

- (2)

  Creates or reuses kernel state on behalf of the owner. (If this is the first waiter, there is no kernel state for this futex, so kernel state is created by locking the RT-mutex and the futex owner is made the owner of the RT-mutex. If there are existing waiters, then the existing state is reused.)

- (3)

  Attaches the waiter to the futex (i.e., the waiter is enqueued on the RT-mutex waiter list).

If more than one waiter exists, the enqueueing of the waiter is in descending priority order. (For information on priority ordering, see the discussion of the **SCHED\_DEADLINE**, **SCHED\_FIFO**, and **SCHED\_RR** scheduling policies in [**sched**(7)](/sched/7.md).) The owner inherits either the waiter's CPU bandwidth (if the waiter is scheduled under the **SCHED\_DEADLINE** policy) or the waiter's priority (if the waiter is scheduled under the **SCHED\_RR** or **SCHED\_FIFO** policy). This inheritance follows the lock chain in the case of nested locking and performs deadlock detection.

The *timeout* argument provides a timeout for the lock attempt. If *timeout* is not NULL, the structure it points to specifies an absolute timeout. If *timeout* is NULL, the operation will block indefinitely.

## RETURN VALUE

On error, -1 is returned, and *errno* is set to indicate the error.

On success, **FUTEX\_LOCK\_PI** returns 0 if the futex was successfully locked.

## ERRORS

See [**futex**(2)](/futex/2.md).

- **EAGAIN**

  The futex owner thread ID of *uaddr* is about to exit, but has not yet handled the internal state cleanup. Try again.

- **EDEADLK**

  The futex word at *uaddr* is already locked by the caller.

- **EFAULT**

  *timeout* did not point to a valid user-space address.

- **EINVAL**

  The supplied *timeout* argument was invalid (*tv\_sec* was less than zero, or *tv\_nsec* was not less than 1,000,000,000).

- **EINVAL**

  The kernel detected an inconsistency between the user-space state at *uaddr* and the kernel state. This indicates either state corruption or that the kernel found a waiter on *uaddr* which is waiting via [**FUTEX\_WAIT**(2const)](/FUTEX_WAIT/2const.md) or [**FUTEX\_WAIT\_BITSET**(2const)](/FUTEX_WAIT_BITSET/2const.md).

- **ENOMEM**

  The kernel could not allocate memory to hold state information.

- **ENOSYS**

  A run-time check determined that the operation is not available. The PI-futex operations are not implemented on all architectures and are not supported on some CPU variants.

- **EPERM**

  The caller is not allowed to attach itself to the futex at *uaddr*. (This may be caused by a state corruption in user space.)

- **ESRCH**

  The thread ID in the futex word at *uaddr* does not exist.

- **ETIMEDOUT**

  The timeout expired before the operation completed.

## STANDARDS

Linux.

## HISTORY

Linux 2.6.18.

## CAVEATS

Unlike other [**futex**(2)](/futex/2.md) operations, the timeout is measured against the **CLOCK\_REALTIME** clock.

## SEE ALSO

[**futex**(2)](/futex/2.md)
