root/kalloc.c

/* [previous][next][first][last][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                    // defined by the kernel linker script in kernel.ld
  15 
  16 struct run {
  17   struct run *next;
  18 };
  19 
  20 struct {
  21   struct spinlock lock;
  22   int use_lock;
  23   struct run *freelist;
  24 } kmem;
  25 
  26 // Initialization happens in two phases.
  27 // 1. main() calls kinit1() while still using entrypgdir to place just
  28 // the pages mapped by entrypgdir on free list.
  29 // 2. main() calls kinit2() with the rest of the physical pages
  30 // after installing a full page table that maps them on all cores.
  31 void
  32 kinit1(void *vstart, void *vend)
     /* [previous][next][first][last][top][bottom][index][help]  */
  33 {
  34   initlock(&kmem.lock, "kmem");
  35   kmem.use_lock = 0;
  36   freerange(vstart, vend);
  37 }
  38 
  39 void
  40 kinit2(void *vstart, void *vend)
     /* [previous][next][first][last][top][bottom][index][help]  */
  41 {
  42   freerange(vstart, vend);
  43   kmem.use_lock = 1;
  44 }
  45 
  46 void
  47 freerange(void *vstart, void *vend)
     /* [previous][next][first][last][top][bottom][index][help]  */
  48 {
  49   char *p;
  50   p = (char*)PGROUNDUP((uint)vstart);
  51   for(; p + PGSIZE <= (char*)vend; p += PGSIZE)
  52     kfree(p);
  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)
     /* [previous][next][first][last][top][bottom][index][help]  */
  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)
     /* [previous][next][first][last][top][bottom][index][help]  */
  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 

/* [previous][next][first][last][top][bottom][index][help]  */