- 论坛徽章:
- 0
|
给你一个我的自旋锁实现,顺便请高人挑挑毛病,看看有啥问题没有
class FoundationAPI SpinLock : NonCopyable
{
private:
enum { LOCK = 0x20, UNLOCK };
typedef AtomicFunction AtomicF;
private:
volatile size_t m_state;
public:
class FoundationAPI ScopeLock
{
private:
SpinLock &m_lock;
public:
ScopeLock(SpinLock &lock);
~ScopeLock();
};
public:
SpinLock();
~SpinLock();
private:
void Lock();
void UnLock();
};
SpinLock::ScopeLock::ScopeLock(SpinLock &lock) :m_lock(lock)
{
m_lock.Lock();
}
SpinLock::ScopeLock::~ScopeLock()
{
m_lock.UnLock();
}
SpinLock::SpinLock() : m_state(UNLOCK)
{
}
SpinLock::~SpinLock()
{
assert(m_state == UNLOCK);
}
void SpinLock::Lock()
{
while(AtomicF::CompareExchange(&m_state, LOCK, UNLOCK) != UNLOCK)
{
Thread::YieldThread();
}
}
void SpinLock::UnLock()
{
assert(m_state == LOCK);
AtomicF::CompareExchange(&m_state, UNLOCK, LOCK);
}
F_NAKED size_t F_STDCALL AtomicFunction::CompareExchange(volatile size_t *dest, size_t val, size_t cmpval)
{
if(ProcessorCount == 1)
{
__asm{
mov eax, [esp + 12];//cmpval;
mov ecx, [esp + 8];//val;
mov edx, [esp + 4];//dest;
cmpxchg [edx], ecx;
ret 12; //eax作为返回值;
}
}else
{
__asm{
mov eax, [esp + 12];//cmpval;
mov ecx, [esp + 8];//val;
mov edx, [esp + 4];//dest;
lock cmpxchg [edx], ecx;
ret 12; //eax作为返回值;
}
}
}
多核下面,核心是这个lock,锁总线,至于总线上怎么实现的估计也是有一套复杂的协议和算法。
当然了,我认为一般系统无法获得锁之后,进入内核态,系统会把当前线程挂起来,选另一个线程运行,而后当解锁之后,会搜索哪些线程正在获得锁,而后选一个,将其继续执行。
[ 本帖最后由 Solidus 于 2007-10-10 05:47 编辑 ] |
|