root/kalloc.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. kinit1
  2. kinit2
  3. freerange
  4. kfree
  5. kalloc

   1 // Physical memory allocator, intended to allocate
   2 // memory for user processes, kernel stacks, page table pages,
   3 // and pipe buffers. Allocates 4096-byte pages.
   4 
   5 #include "types.h"
   6 #include "defs.h"
   7 #include "param.h"
   8 #include "memlayout.h"
   9 #include "mmu.h"
  10 #include "spinlock.h"
  11 
  12 void freerange(void *vstart, void *vend);
  13 extern char end[]; // first address after kernel loaded from ELF file
  14 
  15 struct run {
  16   struct run *next;
  17 };
  18 
  19 struct {
  20   struct spinlock lock;
  21   int use_lock;
  22   struct run *freelist;
  23 } kmem;
  24 
  25 // Initialization happens in two phases.
  26 // 1. main() calls kinit1() while still using entrypgdir to place just
  27 // the pages mapped by entrypgdir on free list.
  28 // 2. main() calls kinit2() with the rest of the physical pages
  29 // after installing a full page table that maps them on all cores.
  30 void
  31 kinit1(void *vstart, void *vend)
  32 {
  33   initlock(&kmem.lock, "kmem");
  34   kmem.use_lock = 0;
  35   freerange(vstart, vend);
  36 }
  37 
  38 void
  39 kinit2(void *vstart, void *vend)
  40 {
  41   freerange(vstart, vend);
  42   kmem.use_lock = 1;
  43 }
  44 
  45 void
  46 freerange(void *vstart, void *vend)
  47 {
  48   char *p;
  49   p = (char*)PGROUNDUP((uint)vstart);
  50   for(; p + PGSIZE <= (char*)vend; p += PGSIZE)
  51     kfree(p);
  52 }
  53 
  54 //PAGEBREAK: 21
  55 // Free the page of physical memory pointed at by v,
  56 // which normally should have been returned by a
  57 // call to kalloc().  (The exception is when
  58 // initializing the allocator; see kinit above.)
  59 void
  60 kfree(char *v)
  61 {
  62   struct run *r;
  63 
  64   if((uint)v % PGSIZE || v < end || v2p(v) >= PHYSTOP)
  65     panic("kfree");
  66 
  67   // Fill with junk to catch dangling refs.
  68   memset(v, 1, PGSIZE);
  69 
  70   if(kmem.use_lock)
  71     acquire(&kmem.lock);
  72   r = (struct run*)v;
  73   r->next = kmem.freelist;
  74   kmem.freelist = r;
  75   if(kmem.use_lock)
  76     release(&kmem.lock);
  77 }
  78 
  79 // Allocate one 4096-byte page of physical memory.
  80 // Returns a pointer that the kernel can use.
  81 // Returns 0 if the memory cannot be allocated.
  82 char*
  83 kalloc(void)
  84 {
  85   struct run *r;
  86 
  87   if(kmem.use_lock)
  88     acquire(&kmem.lock);
  89   r = kmem.freelist;
  90   if(r)
  91     kmem.freelist = r->next;
  92   if(kmem.use_lock)
  93     release(&kmem.lock);
  94   return (char*)r;
  95 }
  96 

/* [<][>][^][v][top][bottom][index][help] */