contributed by < leewei05
>
Hazard pointer 是由 hazard pointers 以及 retire list 所組成。其目的是為了實作 lock-free 的記憶體回收機制,適用於 Write-Rarely-Read-Many 的場景。
實作注意事項:
以下是 Hazard pointer 的簡化 C11 實作,搭配 GNU extension:
封裝 GNU built-in functions
配置一個新的空間並把新加入的 node 插入至 linked list 的 head。
Built-in Function: type __atomic_load_n (type *ptr, int memorder)
This built-in function implements an atomic load operation. It returns the contents of *ptr.
Built-in Function: bool __atomic_compare_exchange_n (type *ptr, type *expected, type desired, bool weak, int success_memorder, int failure_memorder)
This built-in function implements an atomic compare and exchange operation. This compares the contents of *ptr with the contents of *expected. If equal, the operation is a read-modify-write operation that writes desired into *ptr. If they are not equal, the operation is a read and the current contents of *ptr are written into *expected.
If desired is written into *ptr then true is returned and memory is affected according to the memory order specified by success_memorder. There are no restrictions on what memory order can be used here.
Otherwise, false is returned and memory is affected according to failure_memorder.
expected
為 0 表示該 node 的指標物件是空的,可以直接寫入指標至該 node;atomic_cas
回傳 true 則表示 ptr
順利寫入至 &node->ptr
。
比對 node 的 ptr 與欲移除的 ptr 是否相同,相同則寫入 0 至 node 的 ptr,但並沒有清除 node 的記憶體空間。如果之後執行緒要移除某個物件,可以直接把該物件的指標寫入至空的 node。
顧名思義,該執行緒的 retire list 是否存在某個物件。
釋放 retire list 裡所有 node 的記憶體空間。比較好奇NOT THREAD SAFE
的註解,retire list 不是只有單一執行緒可以存取嗎?
list_
開頭的函式最初的設計目標是達到通用性質,模組化的程式碼應該儘量思考到後續的重用 (reusability),因此及早標注其限制就變得重要
定義 domain_t
來封裝 hazard pointers 物件。
寫入 prot_ptr 至 hazard pointer。
Built-in Function: void __builtin_unreachable (void)
If control flow reaches the point of the __builtin_unreachable, the program is undefined. It is useful in situations where the compiler cannot deduce the unreachability of the code.
執行緒用完 shared object 之後必須呼叫 drop
,list_remove
將會寫入 0 至 node 的 ptr,但並沒有清除 node 的記憶體空間。程式碼會執行 __builtin_unreachable
是沒有定義的狀況,因為執行緒現在使用的 shared object 一定會在 linked list 中。故 list_remove
回傳 false 一定是有其他不預期的原因。
把 shared pointer 的值跟 new pointer 互換,之後再釋放 shared pointer 原本佔用的記憶體空間。
推斷 EXP3
, EXP4
皆為 list_remove(&dom->retired, ptr)
。
cleanup 要用在哪?測試程式最後也沒有呼叫 cleanup
這就是要讓你擴充的,你推測其作用,撰寫對應的測試程式
jservImage Not Showing Possible ReasonsLearn More →
- The image file may be corrupted
- The server hosting the image is unavailable
- The image path is incorrect
- The image format is not supported
測試程式