151158207SWedson Almeida Filho // SPDX-License-Identifier: GPL-2.0 251158207SWedson Almeida Filho 351158207SWedson Almeida Filho //! RCU support. 451158207SWedson Almeida Filho //! 551158207SWedson Almeida Filho //! C header: [`include/linux/rcupdate.h`](srctree/include/linux/rcupdate.h) 651158207SWedson Almeida Filho 751158207SWedson Almeida Filho use crate::{bindings, types::NotThreadSafe}; 851158207SWedson Almeida Filho 951158207SWedson Almeida Filho /// Evidence that the RCU read side lock is held on the current thread/CPU. 1051158207SWedson Almeida Filho /// 1151158207SWedson Almeida Filho /// The type is explicitly not `Send` because this property is per-thread/CPU. 1251158207SWedson Almeida Filho /// 1351158207SWedson Almeida Filho /// # Invariants 1451158207SWedson Almeida Filho /// 1551158207SWedson Almeida Filho /// The RCU read side lock is actually held while instances of this guard exist. 1651158207SWedson Almeida Filho pub struct Guard(NotThreadSafe); 1751158207SWedson Almeida Filho 1851158207SWedson Almeida Filho impl Guard { 1951158207SWedson Almeida Filho /// Acquires the RCU read side lock and returns a guard. 20*9520371eSI Hsin Cheng #[inline] 2151158207SWedson Almeida Filho pub fn new() -> Self { 2251158207SWedson Almeida Filho // SAFETY: An FFI call with no additional requirements. 2351158207SWedson Almeida Filho unsafe { bindings::rcu_read_lock() }; 2451158207SWedson Almeida Filho // INVARIANT: The RCU read side lock was just acquired above. 2551158207SWedson Almeida Filho Self(NotThreadSafe) 2651158207SWedson Almeida Filho } 2751158207SWedson Almeida Filho 2851158207SWedson Almeida Filho /// Explicitly releases the RCU read side lock. 29*9520371eSI Hsin Cheng #[inline] 3051158207SWedson Almeida Filho pub fn unlock(self) {} 3151158207SWedson Almeida Filho } 3251158207SWedson Almeida Filho 3351158207SWedson Almeida Filho impl Default for Guard { 34*9520371eSI Hsin Cheng #[inline] 3551158207SWedson Almeida Filho fn default() -> Self { 3651158207SWedson Almeida Filho Self::new() 3751158207SWedson Almeida Filho } 3851158207SWedson Almeida Filho } 3951158207SWedson Almeida Filho 4051158207SWedson Almeida Filho impl Drop for Guard { 41*9520371eSI Hsin Cheng #[inline] 4251158207SWedson Almeida Filho fn drop(&mut self) { 4351158207SWedson Almeida Filho // SAFETY: By the type invariants, the RCU read side is locked, so it is ok to unlock it. 4451158207SWedson Almeida Filho unsafe { bindings::rcu_read_unlock() }; 4551158207SWedson Almeida Filho } 4651158207SWedson Almeida Filho } 4751158207SWedson Almeida Filho 4851158207SWedson Almeida Filho /// Acquires the RCU read side lock. 49*9520371eSI Hsin Cheng #[inline] 5051158207SWedson Almeida Filho pub fn read_lock() -> Guard { 5151158207SWedson Almeida Filho Guard::new() 5251158207SWedson Almeida Filho } 53