在xv6 中锁对象是 spinlock,spinlock中的locked为1的时候表示被占用,为0的时候锁空闲。

struct spinlock {
uint locked; // Is the lock held?
......
};

  使用 acquire获取锁

void acquire(struct spinlock *lk)
{
........
while(xchg(&lk->locked, ) != );
......
}

  该函数中通过xchg原子性交换locked和1,并返回locked的原来的值。当返回值为1时,说明其他线程占用了该锁,继续循环等待;当返回值为0时,说明其他地方没有占用该锁,同时locked本设置成1了,所以该锁被此处占用。

  

static inline uint xchg(volatile uint *addr, uint newval)
{
uint result; // The + in "+m" denotes a read-modify-write operand.
asm volatile("lock; xchgl %0, %1" :
"+m" (*addr), "=a" (result) :
"" (newval) :
"cc");
/*
//最终汇编类似于
movq *addr, %rdx
movl newval, %eax
lock; xchgl (%rdx), %eax
movl %eax, result */
return result;
}

  xchg通过lock xchg实现原子性的交换,把*addr的老值放入eax中,然后在赋值给result。

  释放锁

void release(struct spinlock *lk)
{
...
// Release the lock, equivalent to lk->locked = 0.
// This code can't use a C assignment, since it might
// not be atomic. A real OS would use C atomics here.
asm volatile("movl $0, %0" : "+m" (lk->locked) : );
...
}

xv6 锁的更多相关文章

  1. XV6锁

    锁 xv6 运行在多处理器上,即计算机上有多个单独执行代码的 CPU.这些 CPU 操作同一片地址空间并分享其中的数据结构:xv6 必须建立一种合作机制防止它们互相干扰.即使是在单个处理器上,xv6 ...

  2. xv6学习笔记(5) : 锁与管道与多cpu

    xv6学习笔记(5) : 锁与管道与多cpu 1. xv6锁结构 1. xv6操作系统要求在内核临界区操作时中断必须关闭. 如果此时中断开启,那么可能会出现以下死锁情况: 进程A在内核态运行并拿下了p ...

  3. XV6操作系统代码阅读心得(四):虚拟内存

    本文将会详细介绍Xv6操作系统中虚拟内存的初始化过程. 基本概念 32位X86体系结构采用二级页表来管理虚拟内存.之所以使用二级页表, 是为了节省页表所占用的内存,因为没有内存映射的二级页表可以不用分 ...

  4. XV6源代码阅读-同步机制

    Exercise1 源代码阅读 锁部分:spinlock.h/spinlock.c以及相关其他文件代码 // Mutual exclusion lock. struct spinlock { uint ...

  5. XV6操作系统代码阅读心得(三):锁

    锁是操作系统中实现进程同步的重要机制. 基本概念 临界区(Critical Section)是指对共享数据进行访问与操作的代码区域.所谓共享数据,就是可能有多个代码执行流并发地执行,并在执行中可能会同 ...

  6. XV6学习(10)锁

    在包括XV6的绝大部分操作系统都是多个任务交错执行的.交错的一个原因是多核硬件:多核计算机的多个CPU核心独立执行计算,如XV6的RISC-V处理器.多个CPU核心共享物理内存,XV6利用这种共享来维 ...

  7. XV6操作系统代码阅读心得(二):进程

    1. 进程的基本概念 从抽象的意义来说,进程是指一个正在运行的程序的实例,而线程是一个CPU指令执行流的最小单位.进程是操作系统资源分配的最小单位,线程是操作系统中调度的最小单位.从实现的角度上讲,X ...

  8. XV6调度

    调度 任何操作系统都可能碰到进程数多于处理器数的情况,这样就需要考虑如何分享处理器资源.理想的做法是让分享机制对进程透明.通常我们对进程造成一个自己独占处理器的假象,然后让操作系统的多路复用机制(mu ...

  9. XV6文件系统

    文件系统 文件系统的目的是组织和存储数据,典型的文件系统支持用户和程序间的数据共享,并提供数据持久化的支持(即重启之后数据仍然可用). xv6 的文件系统中使用了类似 Unix 的文件,文件描述符,目 ...

随机推荐

  1. 查漏补缺之Go的Strings, bytes, runes和字符

    字节遍历,字符遍历 https://play.golang.org/p/DeZcCN9aHXo package main import ( "fmt" "unicode/ ...

  2. python多线程采集图片

    cmd中运行 >python untitled2.py    图片的网站 import requests import threading from bs4 import BeautifulSo ...

  3. Python 数组

    使用之前要先导入函数库  import numpy as np 数组名=np.zeros(数组大小,数据类型)    初始化为0值,这里的数据类型只能是数值类型,字符类型不能用 一.一维数组 impo ...

  4. RabbitMq学习笔记——配置

    1.RabbitMq server官网下载地址:https://www.rabbitmq.com 2.Rabbit MQ 是建立在强大的Erlang OTP平台上,因此安装Rabbit MQ的前提是安 ...

  5. 一道综合渗透题引发的updatexml()注入思考

    MYSQL数据库updatexml报错注入UPDATEXML (XML_document, XPath_string, new_value); 第一个参数:XML_document是String格式, ...

  6. 实时监听input输入的变化(兼容主流浏览器)

    遇到如此需求,首先想到的是change事件,但用过change的都知道只有在input失去焦点时才会触发,并不能满足实时监测的需求,比如监测用户输入字符数. 在经过查阅一番资料后,欣慰的发现firef ...

  7. 如果不想在django 的settings中保存mysql数据库的密码

    如题,你可以编写一个配置文件,用'OPTIONS' 将该配置文件导入进来,这样你发布到git上的源码上就没有你的数据库密码了. 这是django推荐的方法. # settings.py DATABAS ...

  8. LCS(Longest Common Subsequence)最长公共子序列

    最长公共子序列(LCS)是一个在一个序列集合中(通常为两个序列)用来查找所有序列中最长子序列的问题.这与查找最长公共子串的问题不同的地方是:子序列不需要在原序列中占用连续的位置 .最长公共子序列问题是 ...

  9. 部署 Prometheus Operator【转】

    本节在实践时使用的是 Prometheus Operator 版本 v0.14.0.由于项目开发迭代速度很快,部署方法可能会更新,必要时请参考官方文档. 下载最新源码 git clone https: ...

  10. HashMap ConcurrentHashMap解读

    前言: 常见的关于HahsMap与ConcurrentHashMap的问题: 数据结构.线程安全.扩容.jdk1.7 HashMap死循环.jdk1.8 HashMap红黑树.容量必须是2的冥次 Ha ...