00001
00002
00003
00004
00005
00006
00007
00008 #include "types.h"
00009 #include "defs.h"
00010 #include "param.h"
00011 #include "spinlock.h"
00012
00013 struct run {
00014 struct run *next;
00015 int len;
00016 };
00017
00018 struct {
00019 struct spinlock lock;
00020 struct run *freelist;
00021 } kmem;
00022
00023
00024
00025
00026
00027 void
00028 kinit(void)
00029 {
00030 extern char end[];
00031 uint len;
00032 char *p;
00033
00034 initlock(&kmem.lock, "kmem");
00035 p = (char*)(((uint)end + PAGE) & ~(PAGE-1));
00036 len = 256*PAGE;
00037 cprintf("mem = %d\n", len);
00038 kfree(p, len);
00039 }
00040
00041
00042
00043
00044
00045 void
00046 kfree(char *v, int len)
00047 {
00048 struct run *r, *rend, **rp, *p, *pend;
00049
00050 if(len <= 0 || len % PAGE)
00051 panic("kfree");
00052
00053
00054 memset(v, 1, len);
00055
00056 acquire(&kmem.lock);
00057 p = (struct run*)v;
00058 pend = (struct run*)(v + len);
00059 for(rp=&kmem.freelist; (r=*rp) != 0 && r <= pend; rp=&r->next){
00060 rend = (struct run*)((char*)r + r->len);
00061 if(r <= p && p < rend)
00062 panic("freeing free page");
00063 if(rend == p){
00064 r->len += len;
00065 if(r->next && r->next == pend){
00066 r->len += r->next->len;
00067 r->next = r->next->next;
00068 }
00069 goto out;
00070 }
00071 if(pend == r){
00072 p->len = len + r->len;
00073 p->next = r->next;
00074 *rp = p;
00075 goto out;
00076 }
00077 }
00078
00079 p->len = len;
00080 p->next = r;
00081 *rp = p;
00082
00083 out:
00084 release(&kmem.lock);
00085 }
00086
00087
00088
00089
00090 char*
00091 kalloc(int n)
00092 {
00093 char *p;
00094 struct run *r, **rp;
00095
00096 if(n % PAGE || n <= 0)
00097 panic("kalloc");
00098
00099 acquire(&kmem.lock);
00100 for(rp=&kmem.freelist; (r=*rp) != 0; rp=&r->next){
00101 if(r->len >= n){
00102 r->len -= n;
00103 p = (char*)r + r->len;
00104 if(r->len == 0)
00105 *rp = r->next;
00106 release(&kmem.lock);
00107 return p;
00108 }
00109 }
00110 release(&kmem.lock);
00111
00112 cprintf("kalloc: out of memory\n");
00113 return 0;
00114 }