繁体   English   中英

在 XV6 中双重获得自旋锁

[英]Double Acquire a Spinlock in XV6

正如我们所知,xv6 不允许两次获取自旋锁(即使是进程本身)。

我正在尝试添加此功能,该功能允许进程多次获取锁。 为了达到这个目的,我在struct spinlock中添加了一个名为lock_holder_pid的属性,该属性应该保存已获得此锁的进程的 pid。

我更改的唯一文件是spinlock.c

这是我的新acquire() function:

// Acquire the lock.
// Loops (spins) until the lock is acquired.
// Holding a lock for a long time may cause
// other CPUs to waste time spinning to acquire it.
void
acquire(struct spinlock *lk)
{
  pushcli(); // disable interrupts to avoid deadlock.

  
  uint cur_proc_pid = myproc()->pid; //Added by me
  
  
  if (holding(lk) && lk->lock_holder_pid == cur_proc_pid) //Added by me
  {
      popcli();
      return;
  }

  if(holding(lk) && lk->lock_holder_pid != cur_proc_pid) //Added by me
    panic("acquire");
  

  /* Commented by me
  if(holding(lk)) 
    panic("acquire");
  */


  // The xchg is atomic.
  while(xchg(&lk->locked, 1) != 0)
    ;

  
  lk-> lock_holder_pid = cur_proc_pid; //Added by me
  

  // Tell the C compiler and the processor to not move loads or stores
  // past this point, to ensure that the critical section's memory
  // references happen after the lock is acquired.
  __sync_synchronize();

  // Record info about lock acquisition for debugging.
  lk->cpu = mycpu();
  getcallerpcs(&lk, lk->pcs);
}

我还将initlock() function 更改为:

void
initlock(struct spinlock *lk, char *name)
{
  lk->name = name;
  lk->locked = 0;
  lk->cpu = 0;
  lk->lock_holder_pid = -1; //Added by me
}

我最后修改的function是:

void
release(struct spinlock *lk)
{
  if(!holding(lk))
    panic("release");

  lk->pcs[0] = 0;
  lk->cpu = 0;
  lk->lock_holder_pid = -1; //Added by me



...

问题是 xv6 终端在启动时卡住了以下消息:

Booting from Hard Disk...

据我了解,导致问题的行是:

uint cur_proc_pid = myproc()->pid;

当我评论这一行并且只将 lock_holder_pid 设置为一个常数时,它会成功启动。

谁能帮我解决这个问题?

代码中标有“我添加”的部分是我添加的部分。

这仅仅是因为您试图访问 null 结构 ( myproc()->pid ) 的字段。

您可能知道, myproc()返回一个在当前处理器上运行的进程。 如果您查看main.c ,您可能会注意到引导处理器开始在那里运行。 因此,如果我们在设置第一个进程之前找到一个调用acquire() function的function,问题就解决了。

仔细看kinit1 function,可以发现里面调用了acquire function。 因此,我们发现了一个 function,它使用了acquire function,甚至在初始化ptable结构之前。 因此,当您尝试访问myproc()值时,它尚未初始化。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM