Linux x86_64IPC & sincronização#202
futex
Primitiva de sincronização de baixo nível ('fast userspace mutex') usada para implementar mutexes, condvars e semáforos eficientes.
Descrição
No caminho comum (sem contenção), mutexes em espaço de usuário nunca chamam essa syscall — apenas fazem operações atômicas na própria memória. `futex` só entra em ação para bloquear/acordar threads quando há contenção real, tornando-a a base de desempenho de praticamente toda sincronização de threads no Linux (pthreads, pthread_mutex, std::mutex do C++, etc.).
Header:
linux/futex.hman 2Desde o kernel 2.5.7Nota
Praticamente nunca chamada diretamente por aplicações — é implementação interna de glibc (pthreads) e de runtimes de linguagem.
Assinatura
long futex(
uint32_t * uaddr,
int futex_op,
uint32_t val,
const struct timespec * timeout,
uint32_t * uaddr2,
uint32_t val3
);Parâmetros
| Parâmetro | Tipo | Descrição |
|---|---|---|
| uaddr | uint32_t * | Endereço da palavra de 32 bits em memória compartilhada usada como futex. |
| futex_op | int | Operação: FUTEX_WAIT, FUTEX_WAKE, FUTEX_REQUEUE, FUTEX_CMP_REQUEUE, etc., combinável com FUTEX_PRIVATE_FLAG. |
| val | uint32_t | Valor esperado em *uaddr (FUTEX_WAIT) ou número de threads a acordar (FUTEX_WAKE), conforme a operação. |
| timeout | const struct timespec * | Timeout para operações de espera, ou NULL. |
| uaddr2 | uint32_t * | Segundo endereço futex, usado por operações de requeue. |
| val3 | uint32_t | Argumento adicional, cujo significado depende da operação. |
Registradores (x86_64)
| Registrador | Papel | Argumento |
|---|---|---|
| rax | número da syscall (chamada) / valor de retorno (após SYSCALL) | — |
| rdi | argumento 1 | uaddruint32_t * |
| rsi | argumento 2 | futex_opint |
| rdx | argumento 3 | valuint32_t |
| r10 | argumento 4 | timeoutconst struct timespec * |
| r8 | argumento 5 | uaddr2uint32_t * |
| r9 | argumento 6 | val3uint32_t |
Valor de retorno
Depende da operação (frequentemente 0 em sucesso); -1 em erro, com errno definido.
Códigos de erro (errno)
- EAGAIN(11)
- Recurso temporariamente indisponível (tente novamente); também conhecido como EWOULDBLOCK.
- EINTR(4)
- Chamada interrompida por um sinal.
- EINVAL(22)
- Argumento inválido.
- ETIMEDOUT(110)
- Conexão expirou (timeout).
- EFAULT(14)
- Endereço de memória inválido (ponteiro fora do espaço de endereçamento válido).