Expand description
XWOS RUST:自旋锁
自旋锁是多核系统中为防止多个处理器同时访问临界区而引入的一种锁。 当一个CPU获得自旋锁并访问临界区时,其他CPU只能 自旋 等待。 所谓 自旋 ,是指不断循环测试锁的是否可用。
自旋锁内的操作是不可被打断的。因此,自旋锁还伴随其他操作, 例如关闭调度器的抢占,关闭中断底半部,关闭中断等。
在单核(UP)系统中,只有一个CPU,不需要自旋过程,单核系统为了软件接口与多核系统兼容, 也会实现自旋锁,这种自旋锁只需关闭抢占、中断底半部或中断。
自旋锁可用在 任何上下文(Context) :
- 当临界区只被多个线程访问时,需使用关闭抢占的模式:
SpinlockMode::Lock
- 当临界区被中断底半部访问时,需使用关闭中断底半部的模式:
SpinlockMode::LockBh
- 当临界区被多个线程和单一中断访问时,需使用关闭全局中断的模式:
SpinlockMode::LockCpuirq
- 当临界区被多个中断上下文访问时,需使用保存中断全局标志并关闭全局中断的模式:
SpinlockMode::LockCpuirqSave(None)
创建
XWOS RUST的互斥锁可使用 Spinlock::new()
创建:
- 可以创建具有静态生命周期
static
约束的全局变量:
use xwrust::xwos::lock::spinlock::*;
static GLOBAL_SPINLOCK: Spinlock<u32> = Spinlock::new(0);
- 也可以使用
alloc::sync::Arc
在heap中创建:
extern crate alloc;
use alloc::sync::Arc;
use xwrust::xwos::lock::spinlock::*;
pub fn xwrust_example_spinlock() {
let spinlock: Arc<Spinlock<u32>> = Arc::new(Spinlock::new(0));
}
初始化
无论以何种方式创建的自旋锁,都必须在使用前调用 Spinlock::init()
进行初始化:
pub fn xwrust_example_spinlock() {
GLOBAL_SPINLOCK.init();
spinlock.init();
}
解锁
上锁后返回的 SpinlockGuard
。 SpinlockGuard
的生命周期结束时,会自动解锁。
也可调用 Spinlock::unlock()
主动消费掉 SpinlockGuard
来解锁。
上锁
上锁的方法 Spinlock::lock()
除了 自旋 等待,还会根据上锁模式增加额外操作:
- 只关闭抢占的模式:
SpinlockMode::Lock
- 关闭中断底半部的模式:
SpinlockMode::LockBh
- 关闭全局中断的模式:
SpinlockMode::LockCpuirq
- 保存中断全局标志并关闭全局中断的模式:
SpinlockMode::LockCpuirqSave(None)
尝试上锁
尝试上锁的方法 Spinlock::trylock()
只会测试一下锁,不会 自旋 等待,上锁成功后还会根据上锁模式增加额外操作:
- 只关闭抢占的模式:
SpinlockMode::Lock
- 关闭中断底半部的模式:
SpinlockMode::LockBh
- 关闭全局中断的模式:
SpinlockMode::LockCpuirq
- 保存中断全局标志并关闭全局中断的模式:
SpinlockMode::LockCpuirqSave(None)
示例
Structs
- 自旋锁结构体
- 自旋锁的RAII Guard
Enums
- 自旋锁的错误码
- 自旋锁的上锁模式
Constants
- XWOS自旋锁占用的内存大小