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;
}
}
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);
insertspan(s);
for(i=0; i<nelem(classtosize); i++) {
for(; n <= classtosize[i]; n++) {
if(sizetoclass(n) != i) {
- prints("sizetoclass ");
- sys·printint(n);
- prints(" = ");
- sys·printint(sizetoclass(n));
- prints(" want ");
- sys·printint(i);
- prints("\n");
+ printf("sizetoclass %d = %d want %d\n", n, sizetoclass(n), i);
throw("testsizetoclass");
}
}
}
if (n != 32768+1) {
- prints("testsizetoclass stopped at ");
- sys·printint(n);
- prints("\n");
+ printf("testsizetoclass stopped at %d\n", n);
throw("testsizetoclass");
}
}
}
chunk = (chunk+PageMask) & ~PageMask;
s = allocspan(chunk>>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; i<n-1; i++) {
*(void**)p = p+siz;
p += siz;
}
*pn = n;
- return p;
+ return s->base;
}
// Allocate a small object of size class 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;
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;
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<<PageShift;
return alloclarge(np);
}
// TODO: For large spans, maybe just return the
// memory to the operating system and let it zero it.
sys·memclr(s->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);
// 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
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);
-}
-
static byte *p;
static int32 n;
byte *v;
+ uint64 oldfoot;
if(allocator·frozen)
throw("allocator frozen");
//sys·printint(size);
//prints("\n");
+ oldfoot = allocator·footprint;
if(size < 4096) { // TODO: Tune constant.
size = (size + Round) & ~Round;
if(size > n) {
}
v = p;
p += size;
- return v;
+ goto out;
}
if(size & PageMask)
size += (1<<PageShift) - (size & PageMask);
v = sys·mmap(nil, size, PROT_READ|PROT_WRITE, MAP_ANON|MAP_PRIVATE, 0, 0);
allocator·footprint += size;
+
+out:
+ if((oldfoot>>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;
}