1*51158207SWedson Almeida Filho // SPDX-License-Identifier: GPL-2.0 2*51158207SWedson Almeida Filho 3*51158207SWedson Almeida Filho //! RCU support. 4*51158207SWedson Almeida Filho //! 5*51158207SWedson Almeida Filho //! C header: [`include/linux/rcupdate.h`](srctree/include/linux/rcupdate.h) 6*51158207SWedson Almeida Filho 7*51158207SWedson Almeida Filho use crate::{bindings, types::NotThreadSafe}; 8*51158207SWedson Almeida Filho 9*51158207SWedson Almeida Filho /// Evidence that the RCU read side lock is held on the current thread/CPU. 10*51158207SWedson Almeida Filho /// 11*51158207SWedson Almeida Filho /// The type is explicitly not `Send` because this property is per-thread/CPU. 12*51158207SWedson Almeida Filho /// 13*51158207SWedson Almeida Filho /// # Invariants 14*51158207SWedson Almeida Filho /// 15*51158207SWedson Almeida Filho /// The RCU read side lock is actually held while instances of this guard exist. 16*51158207SWedson Almeida Filho pub struct Guard(NotThreadSafe); 17*51158207SWedson Almeida Filho 18*51158207SWedson Almeida Filho impl Guard { 19*51158207SWedson Almeida Filho /// Acquires the RCU read side lock and returns a guard. new() -> Self20*51158207SWedson Almeida Filho pub fn new() -> Self { 21*51158207SWedson Almeida Filho // SAFETY: An FFI call with no additional requirements. 22*51158207SWedson Almeida Filho unsafe { bindings::rcu_read_lock() }; 23*51158207SWedson Almeida Filho // INVARIANT: The RCU read side lock was just acquired above. 24*51158207SWedson Almeida Filho Self(NotThreadSafe) 25*51158207SWedson Almeida Filho } 26*51158207SWedson Almeida Filho 27*51158207SWedson Almeida Filho /// Explicitly releases the RCU read side lock. unlock(self)28*51158207SWedson Almeida Filho pub fn unlock(self) {} 29*51158207SWedson Almeida Filho } 30*51158207SWedson Almeida Filho 31*51158207SWedson Almeida Filho impl Default for Guard { default() -> Self32*51158207SWedson Almeida Filho fn default() -> Self { 33*51158207SWedson Almeida Filho Self::new() 34*51158207SWedson Almeida Filho } 35*51158207SWedson Almeida Filho } 36*51158207SWedson Almeida Filho 37*51158207SWedson Almeida Filho impl Drop for Guard { drop(&mut self)38*51158207SWedson Almeida Filho fn drop(&mut self) { 39*51158207SWedson Almeida Filho // SAFETY: By the type invariants, the RCU read side is locked, so it is ok to unlock it. 40*51158207SWedson Almeida Filho unsafe { bindings::rcu_read_unlock() }; 41*51158207SWedson Almeida Filho } 42*51158207SWedson Almeida Filho } 43*51158207SWedson Almeida Filho 44*51158207SWedson Almeida Filho /// Acquires the RCU read side lock. read_lock() -> Guard45*51158207SWedson Almeida Filhopub fn read_lock() -> Guard { 46*51158207SWedson Almeida Filho Guard::new() 47*51158207SWedson Almeida Filho } 48