前言
在翻 futex man document 的時候,不小心看到 Linux Futex的设计与实现 這篇文章。文章中有提到在執行 sem_post 的時候,雖然沒有與其他 thread 競爭,還是會用到 fuxtex system call。當然文章中有提到原因,不過看了原因,覺得這看起來很明顯的效能問題,應該會被提出來並改進吧?後來翻了一下目前的 source code ,看到這個是 GLIBC_2_0 的版本(那篇文章也很久了,所以能想見當時的版本應該蠻舊的),而現在 GLIBC_2_1 就有把這部分改進,因此就來簡單記錄一下差異在哪裡吧~
Version
glibc 2.29
GLIBC_2_0 version
| |
從 source code 可以看到,在將 sem value + 1 後,就直接使用 lll_futex_wake 呼叫 futex wake system call,其原因在文章內也有提到,是因為當 sem value 加 1 後,當時的機制並無法確認是否有其他 thread 正在 wait。
也因此,才會有原文提到的:
| |
這樣的情形發生。
GLIBC_2_1 version
| |
在新版可以看到,為了解決無法確認當前是否有其他 threads 正在 wait的問題, sem value 被分為兩個部分: nwaiters and value,然後使用 bit shift 來取出 nwaiters number ,只有當 nwaiters > 0 時,才會呼叫 futex_wake 了。
接著就使用原文中的實驗程式,來看一下新版的結果:
| |
可以清楚看到,除了 pthread_join 的 futex wait 之外,並沒有發現如同舊版的 futex wake 了。
結論
目前看到很多大神的 source code 分析。其實都有點年代了,建議還是要再翻一次當前版本的 source code ,才不會只學到舊觀念,而沒跟上新版本呀!
附錄
實驗 source code
| |