diff --git a/usr/rsc/mem/Makefile b/usr/rsc/mem/Makefile index 8f2eace2483..0bfb89b512b 100644 --- a/usr/rsc/mem/Makefile +++ b/usr/rsc/mem/Makefile @@ -31,3 +31,7 @@ test%: test%.$O $(OFILES) clean: rm -f *.$O $(TARG) + +runtime: allocator.$O malloc.$O pagemap.$O triv.$O stack.$O + 6ar grc $(GOROOT)/lib/lib_$(GOARCH)_$(GOOS).a $^ + diff --git a/usr/rsc/mem/allocator.go b/usr/rsc/mem/allocator.go index da624fcd5c5..a0d95e77c81 100644 --- a/usr/rsc/mem/allocator.go +++ b/usr/rsc/mem/allocator.go @@ -10,3 +10,4 @@ export func memset(*byte, int, int) export var footprint int64 export var frozen bool export func testsizetoclass() +export var allocated int64 diff --git a/usr/rsc/mem/malloc.c b/usr/rsc/mem/malloc.c index f5461cddf71..02fe40bd3dd 100644 --- a/usr/rsc/mem/malloc.c +++ b/usr/rsc/mem/malloc.c @@ -107,13 +107,7 @@ allocspan(int32 npage) if(s->length >= npage) { *l = s->next; s->next = nil; -if(s->length > npage) { -prints("Chop span"); -sys·printint(s->length); -prints(" for "); -sys·printint(npage); -prints("\n"); -} +//if(s->length > npage) printf("Chop span %D for %d\n", s->length, npage); goto havespan; } } @@ -125,11 +119,7 @@ prints("\n"); if(allocnpage < (1<<20>>PageShift)) // TODO: Tune allocnpage = (1<<20>>PageShift); s->length = allocnpage; -prints("New span "); -sys·printint(allocnpage); -prints(" for "); -sys·printint(npage); -prints("\n"); +//printf("New span %d for %d\n", allocnpage, npage); s->base = trivalloc(allocnpage<>PageShift); -prints("New Class "); -sys·printint(cl); -prints("\n"); +//printf("New class %d\n", cl); s->state = SpanInUse; s->cl = cl; siz = classtosize[cl]; n = chunk/siz; p = s->base; +//printf("centralgrab cl=%d siz=%d n=%d\n", cl, siz, n); for(i=0; ibase; } // Allocate a small object of size class cl. @@ -305,11 +286,13 @@ allocsmall(int32 cl) if(p == nil) { // otherwise grab some blocks from central cache. lock(¢ral); +//printf("centralgrab for %d\n", cl); p = centralgrab(cl, &n); // TODO: update local counters using n unlock(¢ral); } +//printf("alloc from cl %d\n", cl); // advance linked list. m->freelist[cl] = *p; @@ -327,9 +310,7 @@ alloclarge(int32 np) Span *s; lock(¢ral); -//prints("Alloc span "); -//sys·printint(np); -//prints("\n"); +//printf("Alloc span %d\n", np); s = allocspan(np); unlock(¢ral); s->state = SpanInUse; @@ -346,17 +327,16 @@ alloc(int32 n) if(n < LargeSize) { cl = sizetoclass(n); if(cl < 0 || cl >= SmallFreeClasses) { - sys·printint(n); - prints(" -> "); - sys·printint(cl); - prints("\n"); + printf("%d -> %d\n", n, cl); throw("alloc - logic error"); } - return allocsmall(sizetoclass(n)); + allocator·allocated += classtosize[cl]; + return allocsmall(cl); } // count number of pages; careful about overflow for big n. np = (n>>PageShift) + (((n&PageMask)+PageMask)>>PageShift); + allocator·allocated += (uint64)np<base, s->length << PageShift); -//prints("Free big "); -//sys·printint(s->length); -//prints("\n"); +//printf("Free big %D\n", s->length); + allocator·allocated -= s->length << PageShift; lock(¢ral); freespan(s); unlock(¢ral); @@ -403,9 +382,11 @@ free(void *v) // Zero and add to free list. sys·memclr(v, siz); + allocator·allocated -= siz; p = v; *p = m->freelist[s->cl]; m->freelist[s->cl] = p; +//printf("Free siz %d cl %d\n", siz, s->cl); } void @@ -423,21 +404,3 @@ allocator·memset(byte *v, int32 c, int32 n) v[i] = c; } -// Allocate stack segment. -// Must be done without holding locks, because -// calling any function might trigger another stack segment allocation. -void* -allocstack(int32 n) -{ - // TODO - USED(n); - return nil; -} - -void -freestack(void *v) -{ - // TODO - USED(v); -} - diff --git a/usr/rsc/mem/malloc.h b/usr/rsc/mem/malloc.h index aa3bed2c6b3..dd51e49b24d 100644 --- a/usr/rsc/mem/malloc.h +++ b/usr/rsc/mem/malloc.h @@ -24,9 +24,13 @@ struct PageMap void *level0[PMLevelSize]; }; +extern int64 allocator·allocated; extern int64 allocator·footprint; extern bool allocator·frozen; void* trivalloc(int32); void* pmlookup(PageMap*, uintptr); void* pminsert(PageMap*, uintptr, void*); + +void* alloc(int32); +void free(void*); diff --git a/usr/rsc/mem/stack.c b/usr/rsc/mem/stack.c new file mode 100644 index 00000000000..295e709ffb2 --- /dev/null +++ b/usr/rsc/mem/stack.c @@ -0,0 +1,22 @@ +// Copyright 2009 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +#include "malloc.h" + +void* +stackalloc(uint32 n) +{ + void *v; + + v = alloc(n); +//printf("stackalloc %d = %p\n", n, v); + return v; +} + +void +stackfree(void *v) +{ +//printf("stackfree %p\n", v); + free(v); +} diff --git a/usr/rsc/mem/triv.c b/usr/rsc/mem/triv.c index 631e93a0940..935cb9fc081 100644 --- a/usr/rsc/mem/triv.c +++ b/usr/rsc/mem/triv.c @@ -36,6 +36,7 @@ trivalloc(int32 size) static byte *p; static int32 n; byte *v; + uint64 oldfoot; if(allocator·frozen) throw("allocator frozen"); @@ -44,6 +45,7 @@ trivalloc(int32 size) //sys·printint(size); //prints("\n"); + oldfoot = allocator·footprint; if(size < 4096) { // TODO: Tune constant. size = (size + Round) & ~Round; if(size > n) { @@ -53,12 +55,20 @@ trivalloc(int32 size) } v = p; p += size; - return v; + goto out; } if(size & PageMask) size += (1<>24) != (allocator·footprint>>24)) + printf("memory footprint = %D MB for %D MB\n", allocator·footprint>>20, allocator·allocated>>20); + if(allocator·footprint >= 2LL<<30) { + prints("out of memory\n"); + sys·exit(1); + } return v; }