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