首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >linux页面故障内存中的互斥

linux页面故障内存中的互斥
EN

Stack Overflow用户
提问于 2014-02-16 12:19:51
回答 1查看 257关注 0票数 1

我在Linux2.6和一个位于mmap文件备份内存中的互斥锁上遇到了一个奇怪的并发问题。这是一个锁存器管理器模块。页面错误逻辑会完全重新启动包含锁定前缀的指令吗?当它重新启动时,它的行为就像不包含lock前缀一样。如果我在mmap调用中设置了MAP_LOCKED属性,问题就会消失。有没有人有经验?

代码语言:javascript
复制
//  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
}
EN

回答 1

Stack Overflow用户

发布于 2014-02-18 23:52:10

这可能是由页面错误引入的延迟暴露了否则看不到的竞争条件。

我建议从pthread_spinlock_t (它只是一个int)开始,在实现您自己的自旋锁之前,确保您的软件工作正常。错误可能出在其他地方。

该代码有几个问题:

  1. 混合访问BtSpinLatch* latch as BtSpinLatchushort会违反别名规则,从而导致未定义的行为。将BtSpinLatch设为ushort,并且只使用位掩码和移位来访问位。
  2. 当一个写入器获得锁时,它会清除pending,即使有另一个未决写入器也是如此。
  3. __sync_fetch... 内置函数已过时且过于昂贵,因为它们构成了一个完整的内存屏障,并且它们在这里被调用的次数超过了必要的次数。 使用built-in functions for memory model aware atomic operations
  4. Bit-fields位顺序取决于平台。该代码假定使用低端位域。
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/21807231

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档