1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87
/*********************************************************************************************************************** * Copyright (c) 2020 by the authors * * Author: André Borrmann <pspwizard@gmx.de> * License: Apache License 2.0 / MIT **********************************************************************************************************************/ #![doc(html_root_url = "https://docs.rs/ruspiro-lock/0.4.2")] #![cfg_attr(not(any(test, doctest)), no_std)] #![feature(llvm_asm)] //! # Atomic locks for Raspberry Pi baremetal systems //! //! This crate provides different kinds of locks and access guards to secure data access across cores and/or threads. //! Those locks are *Spinlock*, *Semaphore*, *Mutex* and *RWLock*. The * Semaphore*, *Mutex* and *RWLock* are available //! as `async` version as well to allow them to work in a *non blocking* fashion as required by `async` code. //! //! ## Usage Hint: //! As the locks depend on low level atomics they do only work on the Raspberry Pi if the MMU is properly configured. //! Otherwise using either of the lock functions will hang the core it has been used on. //! //! ## Features //! //! Feature | Usage //! --------|-------- //! async_locks | allows usage of the `async` lock versions. //! //! //! To share those locking primitives accross the Rasperry Pi cores they should be wrapped in an ``Arc``. //! //! # Usage //! //! ## Spinlock //! ``` //! use ruspiro_lock::sync::Spinlock; //! //! fn main() { //! let spin = Spinlock::new(); //! spin.aquire(); //! // following code is only executed if the lock could be aquired, the executing core pause till then //! let _ = 10 + 3; //! spin.release(); //! } //! ``` //! //! ## Semaphore //! ``` //! use ruspiro_lock::sync::Semaphore; //! //! fn main() { //! let sema = Semaphore::new(1); //! if sema.try_down().is_ok() { //! // we gained access to the semaphore, do something //! let _ = 20 /4; //! sema.up(); //! } //! } //! ``` //! //! ## Mutex //! ``` //! use ruspiro_lock::sync::Mutex; //! //! fn main() { //! let mutex = Mutex::new(0u32); //! if let Some(mut data) = mutex.try_lock() { //! *data = 20; //! } //! // once the data goes ot of scope the lock will be released //! if let Some(data) = mutex.try_lock() { //! println!("data: {}", *data); //! //! // another lock should fail inside this scope //! assert!(mutex.try_lock().is_none()); //! } //! //! // a blocking lock on the data will block the current execution until the lock get's available //! let mut data = mutex.lock(); //! *data = 12; //! } //! ``` // re-export the sync lock types, always at root level and witin the sync module pub mod sync; pub use sync::*; #[cfg(any(feature = "async_locks", doc))] pub mod r#async;