diff options
author | rtm <rtm> | 2006-07-12 01:48:35 +0000 |
---|---|---|
committer | rtm <rtm> | 2006-07-12 01:48:35 +0000 |
commit | 4e8f237be819424f922399f8d121d9867b675541 (patch) | |
tree | 53459cfde9630b3ae0d2d46d0ce3d4c1ac423944 /kalloc.c | |
parent | b41b38d0da0854f3fa92967b70180ea1156154d4 (diff) | |
download | xv6-labs-4e8f237be819424f922399f8d121d9867b675541.tar.gz xv6-labs-4e8f237be819424f922399f8d121d9867b675541.tar.bz2 xv6-labs-4e8f237be819424f922399f8d121d9867b675541.zip |
no more big kernel lock
succeeds at usertests.c pipe test
Diffstat (limited to 'kalloc.c')
-rw-r--r-- | kalloc.c | 19 |
1 files changed, 16 insertions, 3 deletions
@@ -10,6 +10,9 @@ #include "param.h" #include "types.h" #include "defs.h" +#include "spinlock.h" + +struct spinlock kalloc_lock; struct run { struct run *next; @@ -54,6 +57,8 @@ kfree(char *cp, int len) for(i = 0; i < len; i++) cp[i] = 1; + acquire(&kalloc_lock); + rr = &freelist; while(*rr){ struct run *rend = (struct run *) ((char *)(*rr) + (*rr)->len); @@ -63,13 +68,13 @@ kfree(char *cp, int len) p->len = len + (*rr)->len; p->next = (*rr)->next; *rr = p; - return; + goto out; } if(pend < *rr){ p->len = len; p->next = *rr; *rr = p; - return; + goto out; } if(p == rend){ (*rr)->len += len; @@ -77,13 +82,16 @@ kfree(char *cp, int len) (*rr)->len += (*rr)->next->len; (*rr)->next = (*rr)->next->next; } - return; + goto out; } rr = &((*rr)->next); } p->len = len; p->next = 0; *rr = p; + + out: + release(&kalloc_lock); } /* @@ -99,20 +107,25 @@ kalloc(int n) if(n % PAGE) panic("kalloc"); + acquire(&kalloc_lock); + rr = &freelist; while(*rr){ struct run *r = *rr; if(r->len == n){ *rr = r->next; + release(&kalloc_lock); return (char *) r; } if(r->len > n){ char *p = (char *)r + (r->len - n); r->len -= n; + release(&kalloc_lock); return p; } rr = &(*rr)->next; } + release(&kalloc_lock); return 0; } |