微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

在 XV6 中双重获取自旋锁

如何解决在 XV6 中双重获取自旋锁

我们知道,xv6 不允许一个自旋锁被获取两次(即使是一个进程本身)。

我正在尝试添加功能,该功能可让进程多次获取锁。 为了实现这一点,我向 lock_holder_pid 添加一个名为 struct spinlock属性,该属性应该保存已获取此锁的进程的 pid。

我更改的唯一文件spinlock.c

这是我的新 acquire() 函数

// 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() 函数更改为:

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

修改的最后一个函数是:

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 设置为一个常数时,它会成功启动。

有人可以帮我解决这个问题吗?

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

解决方法

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

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

如果仔细观察kinit1函数,就会发现其中调用了acquire函数。因此,我们发现了一个使用 acquire 函数的函数,甚至在初始化 ptable 结构之前。因此,当您尝试访问 myproc() 值时,它尚未初始化。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?