【LittleXi】【MIT6.S081-2020Fall】Lab: locks

news2024/10/6 10:35:24

【MIT6.S081-2020Fall】Lab: locks

  • 【MIT6.S081-2020Fall】Lab: locks
  • 内存分配实验
    • 内存分配实验准备
    • 实验目的
    • 1. 举一个例子说明修改前的**kernel/kalloc.c**中如果没有锁会导致哪些进程间竞争(races)问题
    • 2. 说明修改前的kernel/kalloc.c中锁竞争contention问题及其后果
    • 3. 解释acquire和release中push_off/pop_off的作用
    • 4. 对上页实验内容的实现思路、代码设计、测试结果
      • 实验思路
      • 代码设计
      • 测试结果
    • 同步互斥实验目标
      • Q1:关系分析,请写出题目中存在的互斥和同步的关系
      • Q2:上述关系可以抽象为几个进程? 写出伪代码描述和实现思路
        • 伪代码展示

【MIT6.S081-2020Fall】Lab: locks

内存分配实验

内存分配实验准备

环境配置

  • commit lab0的代码

git commit -am lab0

  • 切换到lock分支

git fetch

git checkout lock

make clean

  • make; make qemu并执行kalloctest观察锁竞争情况

实验目的

1. 为每个CPU维护一个空闲页面链表,每个链表都有自己的锁**

​ → 不同CPU上的分配和释放可以并行执行

2. 当某个CPU的空闲页面用尽时,需要借用另一CPU的空闲页面**

​ → 虽然“借用”时可能引入锁竞争,但这种情况较少发生

​ 完成实验后,需通过kalloctest的3个测试 (测试时间可能较长)

1. 举一个例子说明修改前的kernel/kalloc.c中如果没有锁会导致哪些进程间竞争(races)问题

答:

  1. Double Free问题:如果没有锁来保护释放内存的操作,多个进程可能会同时尝试释放同一块内存。这可能导致内存被释放多次,破坏内存管理的一致性。当后续的内存分配请求发生时,可能会分配到之前已经被释放但未及时回收的内存块,从而导致不可预测的错误和安全问题。
  2. 内存泄漏问题:如果没有锁来保护内存分配的操作,多个进程可能会同时尝试分配内存。这可能导致内存分配失败,因为内存池可能在分配之前已经被其他进程用尽。此时,一些进程可能无法获得所需的内存,导致内存泄漏。
  3. 数据不一致性问题:如果多个进程同时修改内存池的数据结构,没有适当的锁来同步这些操作,就可能导致数据结构的损坏,从而破坏了内存管理的一致性。
  4. 性能问题:没有适当的锁来管理内存池,可能导致竞争条件,降低了系统的性能。竞争条件会导致进程等待或频繁地重试内存分配/释放操作,从而增加了系统的负载和延迟。

2. 说明修改前的kernel/kalloc.c中锁竞争contention问题及其后果

答:

1、修改前的kalloc.c代码中,只有一个内核内存分配器(kmem),这会导致在很多线程想要获取锁,想要CPU 调度分配内存的时候造成拥塞情况,导致大量的线程获取锁失败,使得程序运行效率降低。

3. 解释acquire和release中push_off/pop_off的作用

答:“acquire” 和 “release” 中的 “push_off” 和 “pop_off” 是通常用于实现中断禁用(中断屏蔽)的操作。这些操作通常在多任务操作系统中用于确保获取锁或释放锁的相关代码的原子性执行,以防止并发执行的任务相互干扰。

4. 对上页实验内容的实现思路、代码设计、测试结果

实验思路

1、为每个CPU维护一个空闲页面链表,我们可以通过修改kalloc.c代码中的kmem结构体,修改为长度为NCPU的结构体数组,再init函数中,初始化8个结构体中的锁,进行free操作的时候,注意获取当前CPU的id,然后对对应id的CPU进行释放

实现的核心代码:

struct
{
  struct spinlock lock;
  struct run *freelist;
} kmem[NCPU];

2、当其它CPU空闲的时候,我们怎样借用其它CPU来完成任务呢?我们可以进行一个简单的for循环遍历,当发现这个CPU是空闲的,那么我们就可以借用这个CPU

实现的核心代码

  if (!r)
  {
    for (int j = 0; j < NCPU; j++)
    {
      if (i != j)
      {
        // 尝试获取锁
        acquire(&kmem[j].lock);
        if (kmem[j].freelist)
        {
          // 如果获取到了,那么就分配,并退出
          r = kmem[j].freelist;
          kmem[j].freelist = r->next;
          release(&kmem[j].lock);
          break;
        }
        release(&kmem[j].lock);
      }
    }
  }

代码设计

// Physical memory allocator, for user processes,
// kernel stacks, page-table pages,
// and pipe buffers. Allocates whole 4096-byte pages.

#include "types.h"
#include "param.h"
#include "memlayout.h"
#include "spinlock.h"
#include "riscv.h"
#include "defs.h"

void freerange(void *pa_start, void *pa_end);

extern char end[]; // first address after kernel.
                   // defined by kernel.ld.

struct run
{
  struct run *next;
};

struct
{
  struct spinlock lock;
  struct run *freelist;
} kmem[NCPU];

void kinit()
{
  for (int i = 0; i < 8; i++)
    initlock(&kmem[i].lock, "kmem");
  freerange(end, (void *)PHYSTOP);
}

void freerange(void *pa_start, void *pa_end)
{
  char *p;
  p = (char *)PGROUNDUP((uint64)pa_start);
  for (; p + PGSIZE <= (char *)pa_end; p += PGSIZE)
    kfree(p);
}

// Free the page of physical memory pointed at by pa,
// which normally should have been returned by a
// call to kalloc().  (The exception is when
// initializing the allocator; see kinit above.)
void kfree(void *pa)
{
  struct run *r;

  if (((uint64)pa % PGSIZE) != 0 || (char *)pa < end || (uint64)pa >= PHYSTOP)
    panic("kfree");

  // Fill with junk to catch dangling refs.
  memset(pa, 1, PGSIZE);

  r = (struct run *)pa;

  int i = r_tp();
  push_off();
  acquire(&kmem[i].lock);
  r->next = kmem[i].freelist;
  kmem[i].freelist = r;
  release(&kmem[i].lock);
  pop_off();
}

// Allocate one 4096-byte page of physical memory.
// Returns a pointer that the kernel can use.
// Returns 0 if the memory cannot be allocated.
void *
kalloc(void)
{
  struct run *r;

  push_off();

  int i = r_tp();

  acquire(&kmem[i].lock);
  r = kmem[i].freelist;
  if (r)
    kmem[i].freelist = r->next;
  release(&kmem[i].lock);

  if (!r)
  {
    for (int j = 0; j < NCPU; j++)
    {
      if (i != j)
      {
        // 尝试获取锁
        acquire(&kmem[j].lock);
        if (kmem[j].freelist)
        {
          // 如果获取到了,那么就分配,并退出
          r = kmem[j].freelist;
          kmem[j].freelist = r->next;
          release(&kmem[j].lock);
          break;
        }
        release(&kmem[j].lock);
      }
    }
  }

  pop_off();

  if (r)
    memset((char *)r, 5, PGSIZE); // fill with junk
  return (void *)r;
}

测试结果

请添加图片描述

同步互斥实验目标

Q1:关系分析,请写出题目中存在的互斥和同步的关系

答:同步关系包含互斥关系

1、店面的窗口属于临界区资源,且煎饼果子占用了该窗口后,即将该临界区资源上锁,鸡蛋灌饼不能再占用该临界区资源,反之亦然,此过程既体现了同步关系又体现了互斥关系

2、同学们排队购买早餐,并且根据自己的需求站成了两队,体现出来同步关系,不至于让整个队伍乱掉,有序地进行,去获取窗口上的资源,符合FIFO思想、同学们位于同步阻塞态,但是当8点后,没买到的同学到其它窗口去了,又体现出来非阻塞态

Q2:上述关系可以抽象为几个进程? 写出伪代码描述和实现思路

答:上述几个关系可以抽象为4个进程

实现思路:

1、可以先定义四个wait函数,分别表示煎饼果子等待篮子为空,鸡蛋灌饼等待篮子为空,第一支队伍等待鸡蛋灌饼被添上,第二支队伍等待煎饼果子被添上,然后在主函数中fork四个线程,宏观并行跑这四个函数,知道到达早上8点收摊位置

2、因为题目说每天都会出现从一开始就排队直到 8 点结束,所以我们可以默认;两边排队的人数都足够多,当然实际中我们还可以为队伍人物增加设置一个人数信号量

伪代码展示

请添加图片描述
请添加图片描述
请添加图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1062557.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

使用Jest测试Cesium源码

使用Jest测试Cesium源码 介绍环境Cesium安装Jest安装Jest模块包安装babel安装Jest的VSC插件 测试例子小结 介绍 在使用Cesium时&#xff0c;我们常常需要编写自己的业务代码&#xff0c;其中需要引用Cesium的源码&#xff0c;这样方便调试。此外&#xff0c;目前代码中直接使用…

状态机-状态规划(309. 买卖股票的最佳时机含冷冻期)

class Solution {public int maxProfit(int[] prices) {int n prices.length;if(n 0 || n 1)return 0;int f[][] new int[n][2]; //f[i][0 || 1]表示持有/未持有 第i只股票f[0][0] 0;f[0][1] 0 - prices[0];for(int i 1; i < n;i){f[i][0] Math.max(f[i - 1][0],f[i…

专题一:双指针【优选算法】

双指针应用场景&#xff1a; 数组划分、数组分块 目录 一、移动0 二、复写0 从后向前 三、快乐数 链表带环 四、盛水最多的容器 单调性双指针 五、有效三角形个数 单调性双指针 六、和为s的两个数字 七、三数之和 细节多 需再练 一、移动0 class Solution { public:void move…

前端 | AjaxAxios模块

文章目录 1. Ajax1.1 Ajax介绍1.2 Ajax作用1.3 同步异步1.4 原生Ajax 2. Axios2.1 Axios下载2.2 Axios基本使用2.3 Axios方法 1. Ajax 1.1 Ajax介绍 Ajax: 全称&#xff08;Asynchronous JavaScript And XML&#xff09;&#xff0c;异步的JavaScript和XML。 1.2 Ajax作用 …

SPI 通信协议

1. SPI通信 1. 什么是SPI通信协议 2. SPI的通信过程 在一开始会先把发送缓冲器的数据&#xff08;8位&#xff09;。一次性放到移位寄存器里。 移位寄存器会一位一位发送出去。但是要先放到锁存器里。然后从机来读取。从机的过程也一样。当移位寄存器的数据全部发送完。其实…

【Unity3D编辑器开发】Unity3D编辑器开发基础性框架结构【全面总结】

推荐阅读 CSDN主页GitHub开源地址Unity3D插件分享简书地址我的个人博客 大家好&#xff0c;我是佛系工程师☆恬静的小魔龙☆&#xff0c;不定时更新Unity开发技巧&#xff0c;觉得有用记得一键三连哦。 一、前言 嗨&#xff0c;大家好&#xff0c;我是恬静的小魔龙。 同学们…

open62541学习:文件传输

作为一种通信协议&#xff0c;文件传输是非常重要的。例如传输执行程序&#xff0c;图片&#xff0c;配置文件等等。文件传输的机制和类型在 OPC UA 中已经存在很长时间了。FileType &#xff08;作为ObjectType&#xff09;和ImageType长期以来一直是内置模型的一部分&#xf…

Linux:TCP三握四挥简析

文章目录 1. 前言2. 背景3. TCP连接的建立和断开3.1 TCP协议状态机3.2 TCP的三握四挥3.2.1 TCP 连接建立的三次握手过程分析3.2.1.1 服务端和客户端套接字的创建3.2.1.2 服务端进入 LISTEN 状态3.2.1.3 服务端在 LISTEN 状态等待客户端的 SYN 请求3.2.1.4 客户端向服务端发送 S…

【云笔记篇】Microsoft OneNote笔记分区数据删除方法

【云笔记篇】Microsoft OneNote笔记分区数据删除方法 Microsoft OneNote删除分区数据需要在网页端操作才能彻底删除—【蘇小沐】 1、实验 系统版本Windows 11 专业工作站版22H2&#xff08;22621.1485&#xff09;&#xff1b;OneNoteOneNote 2016(版本 2303 Build 16.0.162…

香橙派Zero3安装miniconda3(问题多多,已全部解决)

文章目录 前言一、miniconda3版本二、使用步骤1.安装2.添加环境变量3.更新源4.创建新环境 总结另外 前言 你会遇到很多问题&#xff0c;按照我说的基本没问题。 香橙派是zero3。 一、miniconda3版本 Miniconda3-py37_4.9.2-Linux-aarch64.sh这个版本是测试没问题的&#xff0…

HDLbits : Module addsub

module top_module(input [31:0] a,input [31:0] b,input sub,output [31:0] sum );wire w1;add16 add16_1(a[15:0],b[15:0]^{16{sub}},sub,sum[15:0],w1);add16 add16_2(a[31:16],b[31:16]^{16{sub}},w1,sum[31:16],);endmodule 注意&#xff1a;sub位扩展

latex方程组编写,一种可以保证方程编号自适应的方法

问题描述&#xff1a; 在利用latex编写方程组时&#xff0c;可以有很多种方法&#xff0c;但不总是编辑好的公式能够显示出编号&#xff0c;故提出一种有效的方程组编写方法 方法&#xff1a; \begin{equation}X_{ t1}\left \{ \begin{matrix}\frac{x_{i}}{a} \quad\quad 0&l…

数学建模预测模型MATLAB代码大合集及皮尔逊相关性分析(无需调试、开源)

已知2010-2020数据&#xff0c;预测2021-2060数据 一、Logistic预测人口 %%logistic预测2021-2060年结果 clear;clc; X[7869.34, 8022.99, 8119.81, 8192.44, 8281.09, 8315.11, 8381.47, 8423.50, 8446.19, 8469.09, 8477.26]; nlength(X)-1; for t1:nZ(t)(X(t1)-X(t))/X(t1…

redis高可用(主从复制,哨兵,集群)

目录 一、主从复制&#xff1a; 1.主从复制介绍&#xff1a; 2.主从复制的作用&#xff1a; 3.主从复制流程&#xff1a; 4.搭建Redis 主从复制&#xff1a; 4.1 环境准备&#xff1a; 4.2 安装redis&#xff1a; 4.3 master节点修改 Redis 配置文件&#xff1a; 4.4 slave节点…

判断三条边是否构成三角形(Python实现)

组成三角形的三条边a,b,c需满足条件: ab>c ac>b bc>a 已知&#xff1a;三角形任意三条边的长度之和大于第三条边。 解题&#xff1a;定义3个变量a、b、c&#xff0c;让用户输入任意三个数字赋值给三个变量。判断三个变量中是否任意两个之和大于第三个数值。 判断条件之…

Docker快速搭建漏洞靶场指南

user: admin passwrod&#xff1a;password 查看容器是否已开启&#xff1a; 最常见漏洞&#xff1a; 防护级别提高后&#xff1a; 更改防护级别&#xff1a; 复现vulhub漏洞靶场&#xff1a; 开启&#xff1a; 一个是漏洞类型一个是真实的漏洞靶场。

VS的调式技巧你真的掌握了吗?

目录 什么是bug? 调式是什么&#xff1f;有多重要&#xff1f; 调试是什么&#xff1f; 调试的基本步骤 debug和release的介绍 windows环境调试介绍 1.调试环境的准备 2.学会快捷键 F11 VS F10 F9 & F5 3.调试时查看程序当前信息 查看临时变量的值 查看内存信…

LLMs: 近端策略优化PPO Proximal policy optimization

Dr. Ehsan Kamalinejad&#xff0c;通常简称为EK&#xff0c;是一位机器学习应用科学家。他目前是亚马逊NLP开发中的精英科学家。以前&#xff0c;他共同创办了Visual One&#xff0c;一家Y Combinator计算机视觉初创公司。在此之前&#xff0c;他曾担任苹果的首席机器学习工程…

WPS/word 表格跨行如何续表、和表的名称

1&#xff1a;具体操作&#xff1a; 将光标定位在跨页部分的第一行任意位置&#xff0c;按下快捷键ctrlshiftenter&#xff0c;就可以在跨页的表格上方插入空行&#xff08;在空行可以写&#xff0c;表1-3 xxxx&#xff08;续&#xff09;&#xff09; 在空行中输入…

NUWA论文阅读

论文链接&#xff1a;NUWA: Visual Synthesis Pre-training for Neural visUal World creAtion 文章目录 摘要引言相关工作视觉自回归模型视觉稀疏自注意 方法3D数据表征3D Nearby Self-Attention3D编码器-解码器训练目标 实验实现细节与SOTA比较T2I微调T2V微调V2V微调Sketch-t…