5 min read
最近踩到 compiler optimization 的一個小坑,gcc5 版本以上,開啟 optimization level 2 時,會將 malloc + memeset 轉換成 calloc。看起來似乎蠻有道理的改善,卻因為我在進行客製化 malloc 時,沒有這注意到這點,導致最後程式執行的是 libc 的 calloc 而不是我的 wrap_malloc。
起因
使用 void *__wrap_malloc(size_t size) 將 malloc function 進行額外的處理 (How to wrap a system call (libc function) in Linux),其中一段 code 為:
4 min read
前言
在翻 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
1
2
3
4
5
6
7
8
9
10
11
12
13
| int attribute_compat_text_section __old_sem_post (sem_t *sem)
{
int *futex = (int *) sem;
atomic_write_barrier ();
(void) atomic_increment_val (futex);
int err = lll_futex_wake(futex, 1, LLL_SHARED);
if (__builtin_expect (err, 0) < 0)
{
__set_errno (-err);
return -1;
}
return 0;
}
|
從 source code 可以看到,在將 sem value + 1 後,就直接使用 lll_futex_wake 呼叫 futex wake system call,其原因在文章內也有提到,是因為當 sem value 加 1 後,當時的機制並無法確認是否有其他 thread 正在 wait。