以下內容節選自本書
在Linux中,Futex系統調用的定義如下
#define __NR_futex 240
1. Futex系統調用的用法爲:
int futex (int *uaddr, int op,int val, const struct timespec *timeout,
int *uaddr2, int val3);
uaddr是Futex變量,一個共享的整型計數器。
op表示操作類型,有五種預定義的值,但是在Binoc中只使用了下面兩種:
1) FUTEX_WAIT:內核將檢查uaddr中計數器的值是否等於val,如果等於則掛起進程,直到在uaddr上到來了FUTEX_WAKE調用或者超時時間到。
2) FUTEX_WAKE:內核喚醒val個等待在uaddr上的進程。
val存放與操作op相關的值。
timeout用作操作FUTEX_WAIT中,表示等待超時時間。
uAddr2和val3很少使用。
2. 在Bionc中,提供了兩個函數來包裝Futex系統調用。
extern int __futex_wait(volatilevoid *ftx, int val, const struct timespec *timeout);
extern int __futex_wake(volatilevoid *ftx, int count);
Bionc中還有兩個類似的函數,它們的原型如下:
extern int __futex_wake_ex(volatile void *ftx, int pshared, intval);
extern int __futex_wait_ex(volatile void *ftx, int pshared, intval,
const struct timespec*timeout);
這兩個函數比前面的多了一個參數pshared。pshared的值爲true表示wake和wait操作是用於進程間的掛進和喚醒;值爲false表示操作用於進程內線程的掛進和喚醒。當pshared的值爲false時,執行Futex系統調用的操作碼爲:
FUTEX_WAIT|FUTEX_PRIVATE_FLAG,
FUTEX_WAKE|FUTEX_PRIVATE_FLAG
這樣內核如果檢測到操作有FUTEX_PRIVATE_FLAG標記,能以更快的速度執行掛起和喚醒操作。
__futex_wait和__futex_wake函數相當於pshared等於true的情況。
3. Android中有些模塊還會使用下面的Futex函數:
extern int__futex_syscall3(volatile void *ftx, int op, int val);
extern int__futex_syscall4(volatile void *ftx, int op, int val,
const struct timespec *timeout);
__futex_syscall3()相當於__futex_wake(),而__futex_syscall4()相當於__futex_wait()。這兩個函數與前面的區別是能指定操作碼op做爲參數。操作碼可以是FUTEX_WAIT,FUTEX_WAKE或者它們和FUTEX_PRIVATE_FLAG的組合。
Android中操作碼的定義如下:
#define FUTEX_WAIT 0
#define FUTEX_WAKE 1
#ifndefFUTEX_PRIVATE_FLAG
#defineFUTEX_PRIVATE_FLAG 128
#endif
#ifndefFUTEX_WAIT_PRIVATE
#defineFUTEX_WAIT_PRIVATE (FUTEX_WAIT|FUTEX_PRIVATE_FLAG)
#endif
#ifndefFUTEX_WAKE_PRIVATE
#defineFUTEX_WAKE_PRIVATE (FUTEX_WAKE|FUTEX_PRIVATE_FLAG)
#endif