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