lock的实验一 链接到标题

全局变量的修改和增加 链接到标题

这里的str必须是全局变量,搞成局部变量会导致lock的name指令指向一个虚无位置

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

char str[NCPU][6];

kinit的修改 链接到标题

这里lab里说,要让每个CPU去初始化一下
hint里又说,先让一个CPU有全部的内存块

void
kinit()
{
  for(int i = 0; i < NCPU;++i){
    memmove(str[i],"kmem",5);
    str[i][4] = i+'0';
    str[i][5] = 0;
    initlock(&kmem[i].lock, str[i]);
    kmem[i].freelist = 0;
  }
  freerange(end, (void*)PHYSTOP);
  struct run * t = kmem[0].freelist;
  kmem[0].freelist = 0;
  int i = 0;
  while(t){
    struct run * r = t;
    t = t->next;
    r->next = kmem[i].freelist;
    kmem[i].freelist = r;
    i++;
    i %=NCPU;
  }
}

kfree的修改 链接到标题

这里可能有问题,现在通不过test3

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;
 
  push_off();
  int cpu_id = cpuid();
	//int cpu_id = (uint64)r % NCPU;
  acquire(&kmem[cpu_id].lock);
  r->next = kmem[cpu_id].freelist;
  kmem[cpu_id].freelist = r;
  release(&kmem[cpu_id].lock);
  pop_off();
}

kalloc的修改 链接到标题

这里可能有问题,test3通不过

void *
kalloc(void)
{
  push_off();
  int cpu_id = cpuid();
  struct run *r = 0;

  // 1. 尝试本地分配(必须加锁!)
  acquire(&kmem[cpu_id].lock);
  r = kmem[cpu_id].freelist;
  if(r){
    kmem[cpu_id].freelist = r->next;
  }

  // 2. 本地失败,尝试窃取
  if(!r){
    struct run * s_head = 0;
    int i = cpu_id + 1;
    i %= NCPU;
    while(1){
      if(i == cpu_id) break;
      acquire(&kmem[i].lock);
      //一次偷多个
      if(kmem[i].freelist){
        s_head = kmem[i].freelist;
        struct run * tmp = kmem[i].freelist;
        while( kmem[i].freelist && kmem[i].freelist->next){
          kmem[i].freelist = kmem[i].freelist->next->next;
          tmp = tmp->next;
        }
        if (tmp){
          kmem[i].freelist = tmp->next;
          tmp->next = 0;
        }else {
          kmem[i].freelist = 0;
        }
        release(&kmem[i].lock);
        break;
      }
      release(&kmem[i].lock);
      i++;
      i%=NCPU;
    }
    if (s_head) {
      kmem[cpu_id].freelist = s_head;
      r = kmem[cpu_id].freelist;
      kmem[cpu_id].freelist = r->next;
    }
  }
  release(&kmem[cpu_id].lock);
  if (r) {
    memset((char*)r, 5, PGSIZE);
  }

  pop_off();
  return (void*)r;
}

已有优化 链接到标题

  • 每个CPU在开始时均分内存
  • kfree时看进程看自己在那个CPU上就将内存放在哪里
  • kalloc在有时,只从自己身上拿,没有时窃取

问题 链接到标题

  • kalloc可能写错了逻辑, 导致3号以后的CPU压根没有内存用
  • kfree总是要和kalloc里的steal来来竞争,看怎么降一点