Expose raw-pointer futex wake/wait APIs instead of only &AtomicU32

Aperta
#1,603 0 commenti 0 reazioni 0 assegnatari Vedi su GitHub

I maintainer di solito rispondono entro 1 giorno

Nessuno ha ancora preso questa issue.

Valutazione

Difficoltà
4/5
Tempo stimato
3-5 giorni
Idoneità per principianti
45/100
Tipo di issue
Funzionalità
Chiarezza
Abbastanza chiara
Stato di attività
Tranquilla
Stack tecnologico
linux, rust

Direzione di ricerca

Inizia con rustix:🧵:futex::wake e la sua chiamata a futex_val2, quindi esamina le API futex circostanti e le relative convenzioni per la gestione dei puntatori. Determina l’API per raw pointer e il contratto di sicurezza adatti all’interfaccia esistente; il lavoro è completo quando viene esposta un’operazione wake unsafe basata sull’indirizzo senza richiedere un riferimento Rust fabbricato.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Descrizione

enhancement

rustix::thread::futex::wake currently requires a Rust reference:

#[inline]
pub fn wake(uaddr: &AtomicU32, flags: Flags, val: u32) -> io::Result<usize> {
    // SAFETY: The raw pointers come from references or null.
    unsafe { futex_val2(uaddr, Operation::Wake, flags, val, 0, ptr::null(), 0) }
}

This is too restrictive for some valid futex use cases.

The kernel futex interface fundamentally operates on an address. In some synchronization designs, the caller only has a raw pointer to the futex word, and creating an &AtomicU32 is not justified by Rust’s reference rules.

A concrete example is a futex embedded in a node or frame owned by another thread, including stack allocation. The waking thread may only know the target futex address via a raw pointer stored in a queue. Once the waiter is woken, it may return immediately and destroy the node / stack frame before the waking function returns. In that situation, requiring &AtomicU32 forces the caller to materialize a reference where only a raw-pointer contract is actually available.

Sketch:

struct Node {
    state: AtomicU32,
    next: AtomicPtr<Node>,
}

fn waiter_thread() {
    let node = Node {
        state: AtomicU32::new(0),
        next: AtomicPtr::new(core::ptr::null_mut()),
    };

    enqueue(&node as *const Node);

    unsafe {
        // blocks while state == 0
        futex_wait_raw(core::ptr::addr_of!(node.state), 0);
    }

    // after wake, this stack frame may exit immediately
}

fn waking_thread(node: *const Node) {
    let futex_ptr = unsafe { core::ptr::addr_of!((*node).state) };

    unsafe {
        // This is the shape we need.
        // Constructing `&AtomicU32` here is the problem.
        futex_wake_raw(futex_ptr, Flags::PRIVATE, 1);
    }
}

Today, libraries built on top of rustix end up needing to do one of these:

  1. Manufacture &AtomicU32 from a raw pointer even though they only truly have an address-based contract.
  2. Avoid rustix for this case.
  3. Carry extra ownership/borrowing structure that the kernel API does not require.

The problem is not that a raw-pointer API would be “safe”; it should be unsafe. The point is that the unsafety boundary should match the actual contract: “caller must provide a valid futex address for the duration of the syscall”, not “caller must already have a Rust reference”.

Proposed addition:

pub unsafe fn wake_ptr(
    uaddr: *const AtomicU32,
    flags: Flags,
    val: u32,
) -> io::Result<usize>;

or perhaps

pub unsafe fn wake_ptr(
    uaddr: NonNull<AtomicU32>,
    flags: Flags,
    val: u32,
) -> io::Result<usize>;

That would let higher-level synchronization code express the correct contract without fabricating references where only raw-pointer validity is available.

Lingua principale
Rust
Stelle
2.1k
Fork
322
Merge medio
5g 16h
PR unite (30g)
9

Preparare l'ambiente

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Altre issue di bytecodealliance/rustix

Tutte le issue di bytecodealliance/rustix

Issue simili

Altre issue su Rust

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.