自旋锁的结构体非常小,因此不分别提供静态初始化与动态创建的方法。
自旋锁的RAII机制守卫
自旋锁不同的锁模式具有不同的RAII机制守卫:
Spinlock::LkGrd : 普通上锁模式
- 构造函数关闭当前CPU调度器的抢占,然后上锁自旋锁。 上锁失败会自旋等待,直到上锁成功为止。
- 析构函数解锁自旋锁,开启当前CPU调度器的抢占。
- 示例
Spinlock::TryLkGrd : 普通尝试上锁模式
- 构造函数关闭并保存本地CPU的中断,关闭当前CPU调度器的抢占,上锁自旋锁。 上锁失败会自旋等待,直到上锁成功为止。
- 析构函数解锁自旋锁,开启当前CPU调度器的抢占, 用保存的中断标志恢复本地CPU的中断。
- 示例
void foo()
{
{
if (
XWOK == grd.getRc()) {
} else {
}
}
}
Spinlock::LkThGrd : CPU中断上锁模式
- 构造函数关闭并保存本地CPU的中断,关闭当前CPU调度器的抢占,上锁自旋锁。 上锁失败会自旋等待,直到上锁成功为止。
- 析构函数解锁自旋锁,开启当前CPU调度器的抢占, 用保存的中断标志恢复本地CPU的中断。
- 示例
Spinlock::TryLkThGrd : CPU中断尝试上锁模式
- 构造函数关闭并保存本地CPU的中断,关闭当前CPU调度器的抢占,上锁自旋锁。 上锁失败不会自旋等待,会开启当前CPU调度器的抢占, 用保存的中断标志恢复本地CPU的中断,并在
mRc
中返回 -EAGAIN
- 析构函数解锁自旋锁,开启当前CPU调度器的抢占, 用保存的中断标志恢复本地CPU的中断。
- 示例
void foo()
{
{
if (
XWOK == grd.getRc()) {
} else {
}
}
}
Spinlock::LkBhGrd : 中断底半部上锁模式
- 构造函数关闭当前CPU调度器的抢占,关闭本地CPU的中断底半部,然后上锁自旋锁。 上锁失败会自旋等待,直到上锁成功为止。
- 析构函数解锁自旋锁,开启本地CPU的中断底半部,开启当前CPU调度器的抢占。
- 示例
Spinlock::TryLkBhGrd : 中断底半部尝试上锁模式
- 构造函数关闭当前CPU调度器的抢占,关闭本地CPU的中断底半部, 然后尝试上锁自旋锁。 上锁失败不会自旋等待,会开启当前CPU调度器的抢占,开启本地CPU的中断底半部, 并在
mRc
中返回 -EAGAIN
。
- 析构函数解锁自旋锁,开启本地CPU的中断底半部,开启当前CPU调度器的抢占。
- 示例
void foo()
{
{
if (
XWOK == grd.getRc()) {
} else {
}
}
}
Spinlock::LkIrqsGrd : 部分中断上锁模式
- 构造函数关闭并保存模板参数列表内的中断,关闭当前CPU调度器的抢占,上锁自旋锁。 上锁失败会自旋等待,直到上锁成功为止。
- 析构函数解锁自旋锁,开启当前CPU调度器的抢占, 用保存的中断标志恢复模板参数列表内的中断。
- 示例
Spinlock::TryLkIrqsGrd : 部分中断尝试上锁模式
- 构造函数关闭并保存模板参数列表内的中断,关闭当前CPU调度器的抢占,上锁自旋锁。 上锁失败不会自旋等待,会开启当前CPU调度器的抢占, 用保存的中断标志恢复模板参数列表内的中断, 并在
mRc
中返回 -EAGAIN
。
- 析构函数解锁自旋锁,开启当前CPU调度器的抢占, 用保存的中断标志恢复模板参数列表内的中断。
- 示例
void foo()
{
{
if (
XWOK == grd.getRc()) {
} else {
}
}
}
C++ API
头文件: xwos/cxx/lock/Spinlock.hxx