一種簡單的跨平臺使用者態自旋鎖
阿新 • • 發佈:2018-12-27
自旋鎖作為一種併發同步的手段,特別適用於競爭少和鎖時間短的情況,在驅動及核心程式碼中經常被用到,本文講述一種適合使用者態程式的自旋鎖,支援Windows和Linux(GCC>=4.1.2)平臺,並提供了C語言的介面和實現。
介面
spin_trylock如果獲取成功返回1,否則返回0;spin_is_lock如果已加鎖,返回1,否則返回0。 1typedef struct 2{
3 volatilelong flag_;
4 volatilelong* spin_;
5}spin_lock_t;
6
7void spin_init(spin_lock_t*lock,long* flag);
8
9void spin_lock(spin_lock_t*lock);
10
11int spin_trylock(spin_lock_t*lock);
12
13 void spin_unlock(spin_lock_t*lock);
14
15int 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 supported10#endif11
12void spin_init(spin_lock_t*lock,long* flag)
13{
14#ifdef _MSC_VER
15 InterlockedExchange((volatilelong*)&lock->flag_,0);
16 InterlockedExchange((volatilelong*)&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#endif21}22
23void spin_lock(spin_lock_t*lock)
24{
25#ifdef _MSC_VER
26 for (;0!=InterlockedExchange((volatilelong*)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#endif36}37
38int spin_trylock(spin_lock_t*lock)
39{
40#ifdef _MSC_VER
41 return!InterlockedExchange((volatilelong*)lock->spin_,1);
42#elif defined(__GNUC__)43 return!__sync_fetch_and_or(lock->spin_,1);
44#endif45}46
47void spin_unlock(spin_lock_t*lock)
48{
49#ifdef _MSC_VER
50 InterlockedExchange((volatilelong*)lock->spin_,0);
51#elif defined(__GNUC__)52 __sync_and_and_fetch(lock->spin_,0);
53#endif54}55
56int spin_is_lock(spin_lock_t*lock)
57{
58#ifdef _MSC_VER
59 return InterlockedExchangeAdd((volatilelong*)lock->spin_,0);
60#elif defined(__GNUC__)61 return __sync_add_and_fetch(lock->spin_,0);
62#endif63}
posted on 2012-06-13 21:02 春秋十二月 閱讀(2307) 評論(3) 編輯 收藏 引用 所屬分類: C/C++
介面
spin_trylock如果獲取成功返回1,否則返回0;spin_is_lock如果已加鎖,返回1,否則返回0。 1typedef struct 2{
3 volatilelong flag_;
4 volatilelong* spin_;
5}spin_lock_t;
6
7void spin_init(spin_lock_t*lock,long* flag);
8
9void spin_lock(spin_lock_t*lock);
10
11int spin_trylock(spin_lock_t*lock);
12
13
14
15int 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
12void spin_init(spin_lock_t*lock,long* flag)
13{
14#ifdef _MSC_VER
15 InterlockedExchange((volatilelong*)&lock->flag_,0);
16 InterlockedExchange((volatilelong*)&lock->spin_,flag?(long)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#endif21}22
23void spin_lock(spin_lock_t*lock)
24{
25#ifdef _MSC_VER
26 for (;0!=InterlockedExchange((volatilelong*)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#endif36}37
38int spin_trylock(spin_lock_t*lock)
39{
40#ifdef _MSC_VER
41 return!InterlockedExchange((volatilelong*)lock->spin_,1);
42#elif defined(__GNUC__)43 return!__sync_fetch_and_or(lock->spin_,1);
44#endif45}46
47void spin_unlock(spin_lock_t*lock)
48{
49#ifdef _MSC_VER
50 InterlockedExchange((volatilelong*)lock->spin_,0);
51#elif defined(__GNUC__)52 __sync_and_and_fetch(lock->spin_,0);
53#endif54}55
56int spin_is_lock(spin_lock_t*lock)
57{
58#ifdef _MSC_VER
59 return InterlockedExchangeAdd((volatilelong*)lock->spin_,0);
60#elif defined(__GNUC__)61 return __sync_add_and_fetch(lock->spin_,0);
62#endif63}