root/kernel/kalloc.c

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

DEFINITIONS

This source file includes following definitions.
  1. kinit
  2. freerange
  3. kfree
  4. kalloc

   1 // Physical memory allocator, for user processes,
   2 // kernel stacks, page-table pages,
   3 // and pipe buffers. Allocates whole 4096-byte pages.
   4 
   5 #include "types.h"
   6 #include "param.h"
   7 #include "memlayout.h"
   8 #include "spinlock.h"
   9 #include "riscv.h"
  10 #include "defs.h"
  11 
  12 void freerange(void *pa_start, void *pa_end);
  13 
  14 extern char end[]; // first address after kernel.
  15                    // defined by kernel.ld.
  16 
  17 struct run {
  18   struct run *next;
  19 };
  20 
  21 struct {
  22   struct spinlock lock;
  23   struct run *freelist;
  24 } kmem;
  25 
  26 void
  27 kinit()
  28 {
  29   initlock(&kmem.lock, "kmem");
  30   freerange(end, (void*)PHYSTOP);
  31 }
  32 
  33 void
  34 freerange(void *pa_start, void *pa_end)
  35 {
  36   char *p;
  37   p = (char*)PGROUNDUP((uint64)pa_start);
  38   for(; p + PGSIZE <= (char*)pa_end; p += PGSIZE)
  39     kfree(p);
  40 }
  41 
  42 // Free the page of physical memory pointed at by pa,
  43 // which normally should have been returned by a
  44 // call to kalloc().  (The exception is when
  45 // initializing the allocator; see kinit above.)
  46 void
  47 kfree(void *pa)
  48 {
  49   struct run *r;
  50 
  51   if(((uint64)pa % PGSIZE) != 0 || (char*)pa < end || (uint64)pa >= PHYSTOP)
  52     panic("kfree");
  53 
  54   // Fill with junk to catch dangling refs.
  55   memset(pa, 1, PGSIZE);
  56 
  57   r = (struct run*)pa;
  58 
  59   acquire(&kmem.lock);
  60   r->next = kmem.freelist;
  61   kmem.freelist = r;
  62   release(&kmem.lock);
  63 }
  64 
  65 // Allocate one 4096-byte page of physical memory.
  66 // Returns a pointer that the kernel can use.
  67 // Returns 0 if the memory cannot be allocated.
  68 void *
  69 kalloc(void)
  70 {
  71   struct run *r;
  72 
  73   acquire(&kmem.lock);
  74   r = kmem.freelist;
  75   if(r)
  76     kmem.freelist = r->next;
  77   release(&kmem.lock);
  78 
  79   if(r)
  80     memset((char*)r, 5, PGSIZE); // fill with junk
  81   return (void*)r;
  82 }

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