自旋鎖作為一種并發同步的手段,特別適用于競爭少和鎖時間短的情況,在驅動及內核代碼中經常被用到,本文講述一種適合用戶態程序的自旋鎖,支持Windows和Linux(GCC>=4.1.2)平臺,并提供了C語言的接口和實現。
接口
spin_trylock如果獲取成功返回1,否則返回0;spin_is_lock如果已加鎖,返回1,否則返回0。
1
typedef struct
2

{
3
volatile long flag_;
4
volatile long* spin_;
5
}spin_lock_t;
6
7
void spin_init(spin_lock_t* lock,long* flag);
8
9
void spin_lock(spin_lock_t* lock);
10
11
int spin_trylock(spin_lock_t* lock);
12
13
void spin_unlock(spin_lock_t* lock);
14
15
int spin_is_lock(spin_lock_t* lock);
實現
1
#ifdef _MSC_VER
2
#include <windows.h>
3
#elif defined(__GNUC__)
4
#if __GNUC__<4 || (__GNUC__==4 && __GNUC_MINOR__<1)
5
#error GCC version must be greater or equal than 4.1.2
6
#endif
7
#include <sched.h>
8
#else
9
#error Currently only windows and linux os are supported
10
#endif
11
12
void spin_init(spin_lock_t* lock,long* flag)
13

{
14
#ifdef _MSC_VER
15
InterlockedExchange((volatile long*)&lock->flag_,0);
16
InterlockedExchange((volatile long*)&lock->spin_,flag?(long)flag:(long)&lock->flag_);
17
#elif defined(__GNUC__)
18
__sync_and_and_fetch((long*)&lock->flag_,0);
19
__sync_lock_test_and_set((long*)&lock->spin_,flag?(long)flag:(long)&lock->flag_);
20
#endif
21
}
22
23
void spin_lock(spin_lock_t* lock)
24

{
25
#ifdef _MSC_VER
26
for (;0!=InterlockedExchange((volatile long*)lock->spin_,1);)
27
{
28
Sleep(1);
29
}
30
#elif defined(__GNUC__)
31
for (;0!=__sync_fetch_and_or(lock->spin_,1);)
32
{
33
sched_yield();
34
}
35
#endif
36
}
37
38
int spin_trylock(spin_lock_t* lock)
39

{
40
#ifdef _MSC_VER
41
return !InterlockedExchange((volatile long*)lock->spin_,1);
42
#elif defined(__GNUC__)
43
return !__sync_fetch_and_or(lock->spin_,1);
44
#endif
45
}
46
47
void spin_unlock(spin_lock_t* lock)
48

{
49
#ifdef _MSC_VER
50
InterlockedExchange((volatile long*)lock->spin_,0);
51
#elif defined(__GNUC__)
52
__sync_and_and_fetch(lock->spin_,0);
53
#endif
54
}
55
56
int spin_is_lock(spin_lock_t* lock)
57

{
58
#ifdef _MSC_VER
59
return InterlockedExchangeAdd((volatile long*)lock->spin_,0);
60
#elif defined(__GNUC__)
61
return __sync_add_and_fetch(lock->spin_,0);
62
#endif
63
}
posted on 2012-06-13 21:02
春秋十二月 閱讀(3054)
評論(3) 編輯 收藏 引用 所屬分類:
C/C++