Newer
Older
// Physical memory allocator, intended to allocate
// memory for user processes. Allocates in 4096-byte "pages".
// Free list is kept sorted and combines adjacent pages into
// long runs, to make it easier to allocate big segments.
// One reason the page size is 4k is that the x86 segment size
// granularity is 4k.
#include "param.h"
#include "mmu.h"
#include "proc.h"
struct spinlock kalloc_lock;
struct run {
struct run *next;
int len; // bytes
};
struct run *freelist;
// Initialize free list of physical pages.
// This code cheats by just considering one megabyte of
// pages after _end. Real systems would determine the
// amount of memory available in the system and use it all.
initlock(&kalloc_lock, "kalloc");
start = (char*) &end;
start = (char*) (((uint)start + PAGE) & ~(PAGE-1));
for(rp=&freelist; (r=*rp) != 0 && r <= pend; rp=&r->next){
rend = (struct run*)((char*)r + r->len);
if(r <= p && p < rend)
if(pend == r){ // p next to r: replace r with p
p->len = len + r->len;
p->next = r->next;
*rp = p;
if(rend == p){ // r next to p: replace p with r
r->len += len;
if(r->next && r->next == pend){ // r now next to r->next?
r->len += r->next->len;
r->next = r->next->next;
// Allocate n bytes of physical memory.
// Returns a kernel-segment pointer.
// Returns 0 if the memory cannot be allocated.