---
# System prepended metadata

title: Non-scalable locks

---

# Non-scalable locks

LWN 上對於 spinlock 的描述[^LWN]，目前 kernel 是使用 ticket spinlock，加入了 FIFO 的佇列，讓單一個執行緒不會永久地等待鎖，改善以前版本的 spinlock 造成的 starvation 問題，以及增進整體取得鎖的延遲 (即時性能也可以提升)。

以下為簡化的 spinlock 實作[^fig1]

```c=1
struct spinlock_t {
    int current_ticket;
    int next_ticket;
}

void spin_lock(spinlock_t *lock) {
    int t = atomic_fetch_and_inc(&lock->next_ticket);
    while (t != lock->current_ticket) ; /* spin */ 
}

void spin_unlock(spinlock_t *lock) {
    lock->current_ticket++;
}
```
> 第七行 `atomic_fetch_and_inc` 做的事可以想成原子式的 `lock->next_ticket++`

spinlock 定義有兩個欄位 `current_ticket` 和 `next_ticket`，分別代表目前可取得鎖的號碼以及目前已發放的號碼。

ticket spinlock 可想成櫃台發放號碼牌，當一個客人 (task) 要進行一項服務時，他會先向櫃台取的一個號碼 (現在 `next_ticket` 的值)，櫃台這時會已發放的號碼 + 1，接著客人會比對手上的號碼牌與螢幕上的號碼 (`current_ticket`)，如果不相同就等待，當有其他客人完成後就會將螢幕上的號碼 + 1，直到螢幕上的號碼與手上的號碼牌相同時，就能進行服務。

spinlock 進行初始化時兩個值都會設為 0，取得鎖的條件為目前發放的號碼 `next_ticket` 與可取得鎖的號碼 `current_ticket` 相同，釋放鎖後將 `current_ticket` + 1，通知在等待的執行緒誰可以取得鎖。

> `current_ticket` 和 `next_ticket` 的型別會限制硬體的核心數，假設兩者都只有 8bit，那最多只能有 256 個核心等待一個 spinlock，比 256 個核心更多的處理器可能會讓多個核心上的 `t` 值相同。

## Cache corherence

現代處理器會使用快取 (cache) 加速記憶體存取的延遲，每個處理器核心會有自己私有快取，當多核同時存取一個共享變數，其值會被放到快取裡面，可以說每個核心都有自己的一份 copy，以下圖[^4]為例，P1 和 P2 共享一個變數 `x`，所以兩個核心的快取都有 x 的值 (1000)。

![](https://i.imgur.com/yrfFUbF.png)

當某一核修改了存在快取的變數的值，硬體必須提供機制讓其他核也能看到修改的值，這就是 cache coherence 的目的，讓軟體開發者不用處理這個問題。

cache coherence 的方式:

1. update-based protocols: 當一個共享的記憶體位址的值被修改，其值會被更新到任何有此記憶體位址的快取上
2. invalidation-based protocols: 當一個共享的記憶體位址的值被修改，將其他有此記憶體位址的快取設為 invalid，直到其他處理器核心產生一個 miss (存取此位址) 才會讀取資料，如較知名的 MSI, MESI 協議

Coherence 必須提供:
- **Write propagation**: guarantee that updates will propagate
- **Write serialization**: provide a consistent order seen by all
processors for the same memory location

下圖[^3]
![](https://i.imgur.com/NbHp3bq.png)



[^LWN]: LWM spinlock implementation: https://lwn.net/Articles/267968/
[^fig1]: Non-scalable locks are dangerous. Figure 1
[^3]: David Culler, J.P. Singh, Anoop Gupta,  Parallel Computer Architecture: A Hardware Software Approach (The Morgan Kaufmann Series in Computer Architecture and Design) (1998)

[^4]: ETHZ fall2019-lecture22-cachecoherence-afterlecture