自旋锁作为一种并发同步的手段,特别适用于竞争少和锁时间短的情况,在驱动及内核代码中经常被用到,本文讲述一种适合用户态程序的自旋锁,支持Windows和Linux(GCC>=4.1.2)平台,并提供了C语言的接口和实现。
接口
spin_trylock如果获取成功返回1,否则返回0;spin_is_lock如果已加锁,返回1,否则返回0。
1typedef struct
2{
3 volatile long flag_;
4 volatile long* 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
13void 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 supported
10#endif
11
12void 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
23void 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
38int 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
47void 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
56int 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
春秋十二月 阅读(3015)
评论(3) 编辑 收藏 引用 所属分类:
C/C++