xref: /xv6-public/kalloc.c (revision 4587b358)
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 "mmu.h"
9 #include "spinlock.h"
10 
11 struct run {
12   struct run *next;
13 };
14 
15 struct {
16   struct spinlock lock;
17   struct run *freelist;
18 } kmem;
19 
20 extern char end[]; // first address after kernel loaded from ELF file
21 
22 // Initialize free list of physical pages.
23 void
24 kinit(void)
25 {
26   initlock(&kmem.lock, "kmem");
27   char *p = (char*)PGROUNDUP((uint)end);
28   for( ; p + PGSIZE - 1 < (char*) PHYSTOP; p += PGSIZE)
29     kfree(p);
30 }
31 
32 //PAGEBREAK: 21
33 // Free the page of physical memory pointed at by v,
34 // which normally should have been returned by a
35 // call to kalloc().  (The exception is when
36 // initializing the allocator; see kinit above.)
37 void
38 kfree(char *v)
39 {
40   struct run *r;
41 
42   if(((uint) v) % PGSIZE || v < end || (uint)v >= PHYSTOP)
43     panic("kfree");
44 
45   // Fill with junk to catch dangling refs.
46   memset(v, 1, PGSIZE);
47 
48   acquire(&kmem.lock);
49   r = (struct run *) v;
50   r->next = kmem.freelist;
51   kmem.freelist = r;
52   release(&kmem.lock);
53 }
54 
55 // Allocate one 4096-byte page of physical memory.
56 // Returns a pointer that the kernel can use.
57 // Returns 0 if the memory cannot be allocated.
58 char*
59 kalloc()
60 {
61   struct run *r;
62 
63   acquire(&kmem.lock);
64   r = kmem.freelist;
65   if(r)
66     kmem.freelist = r->next;
67   release(&kmem.lock);
68   return (char*) r;
69 }
70 
71