【发布时间】:2014-02-16 04:19:51
【问题描述】:
我在使用 linux 2.6 和位于 mmap 文件支持的内存中的互斥锁时遇到了一个奇怪的并发问题。这是一个闩锁管理器模块。页面错误逻辑是否会重新启动完全包含锁定前缀的指令?它的行为就像它在重新启动时不包含锁定前缀一样。如果我在 mmap 调用中设置 MAP_LOCKED 属性,问题就解决了。有人有经验吗?
// mode & definition for hash latch implementation
enum {
Mutex = 1,
Write = 2,
Pending = 4,
Share = 8
} LockMode;
// mutex locks the other fields
// exclusive is set for write access
// share is count of read accessors
typedef struct {
volatile ushort mutex:1;
volatile ushort exclusive:1;
volatile ushort pending:1;
volatile ushort share:13;
} BtSpinLatch;
// wait for other read and write latches to relinquish
void bt_spinwritelock(BtSpinLatch *latch)
{
do {
#ifdef unix
while( __sync_fetch_and_or((ushort *)latch, Mutex | Pending) & Mutex )
sched_yield();
#else
while( _InterlockedOr16((ushort *)latch, Mutex | Pending) & Mutex )
SwitchToThread();
#endif
if( !(latch->share | latch->exclusive) ) {
#ifdef unix
__sync_fetch_and_or((ushort *)latch, Write);
__sync_fetch_and_and ((ushort *)latch, ~(Mutex | Pending));
#else
_InterlockedOr16((ushort *)latch, Write);
_InterlockedAnd16((ushort *)latch, ~(Mutex | Pending));
#endif
return;
}
#ifdef unix
__sync_fetch_and_and ((ushort *)latch, ~Mutex);
sched_yield();
#else
_InterlockedAnd16((ushort *)latch, ~Mutex);
SwitchToThread();
#endif
} while( 1 );
}
void bt_spinreadlock(BtSpinLatch *latch)
{
ushort prev;
do {
#ifdef unix
while( __sync_fetch_and_or((ushort *)latch, Mutex) & Mutex )
sched_yield();
#else
while( _InterlockedOr16((ushort *)latch, Mutex) & Mutex )
SwitchToThread();
#endif
// see if exclusive request is granted or pending
if( prev = !(latch->exclusive | latch->pending) )
#ifdef unix
__sync_fetch_and_add((ushort *)latch, Share);
#else
_InterlockedExchangeAdd16 ((ushort *)latch, Share);
#endif
#ifdef unix
__sync_fetch_and_and ((ushort *)latch, ~Mutex);
#else
_InterlockedAnd16((ushort *)latch, ~Mutex);
#endif
if( prev )
return;
#ifdef unix
} while( sched_yield(), 1 );
#else
} while( SwitchToThread(), 1 );
#endif
}
【问题讨论】:
-
你能展示在 mmap 内存中创建和初始化互斥锁的代码吗?
-
我附上了读写器独占请求代码。它使用 ushort 的低位作为互斥体。
-
锁存器被创建并初始化为零值。
-
有什么理由不将进程共享互斥锁和条件变量放在共享内存中?
-
是的,它们太大了。这些读/写锁是 ushorts。我需要它们来保护哈希表条目。