summaryrefslogtreecommitdiff
path: root/src/pkg/runtime/mcentral.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/pkg/runtime/mcentral.c')
-rw-r--r--src/pkg/runtime/mcentral.c61
1 files changed, 19 insertions, 42 deletions
diff --git a/src/pkg/runtime/mcentral.c b/src/pkg/runtime/mcentral.c
index ec2a91ad5..735a7e6a9 100644
--- a/src/pkg/runtime/mcentral.c
+++ b/src/pkg/runtime/mcentral.c
@@ -30,16 +30,15 @@ runtime·MCentral_Init(MCentral *c, int32 sizeclass)
runtime·MSpanList_Init(&c->empty);
}
-// Allocate up to n objects from the central free list.
+// Allocate a list of objects from the central free list.
// Return the number of objects allocated.
// The objects are linked together by their first words.
-// On return, *pstart points at the first object.
+// On return, *pfirst points at the first object.
int32
-runtime·MCentral_AllocList(MCentral *c, int32 n, MLink **pfirst)
+runtime·MCentral_AllocList(MCentral *c, MLink **pfirst)
{
MSpan *s;
- MLink *first, *last;
- int32 cap, avail, i;
+ int32 cap, n;
runtime·lock(c);
// Replenish central list if empty.
@@ -52,49 +51,27 @@ runtime·MCentral_AllocList(MCentral *c, int32 n, MLink **pfirst)
}
s = c->nonempty.next;
cap = (s->npages << PageShift) / s->elemsize;
- avail = cap - s->ref;
- if(avail < n)
- n = avail;
-
- // First one is guaranteed to work, because we just grew the list.
- first = s->freelist;
- last = first;
- for(i=1; i<n; i++) {
- last = last->next;
- }
- s->freelist = last->next;
- last->next = nil;
+ n = cap - s->ref;
+ *pfirst = s->freelist;
+ s->freelist = nil;
s->ref += n;
c->nfree -= n;
-
- if(n == avail) {
- if(s->freelist != nil || s->ref != cap) {
- runtime·throw("invalid freelist");
- }
- runtime·MSpanList_Remove(s);
- runtime·MSpanList_Insert(&c->empty, s);
- }
-
+ runtime·MSpanList_Remove(s);
+ runtime·MSpanList_Insert(&c->empty, s);
runtime·unlock(c);
- *pfirst = first;
return n;
}
-// Free n objects back into the central free list.
+// Free the list of objects back into the central free list.
void
-runtime·MCentral_FreeList(MCentral *c, int32 n, MLink *start)
+runtime·MCentral_FreeList(MCentral *c, MLink *start)
{
- MLink *v, *next;
-
- // Assume next == nil marks end of list.
- // n and end would be useful if we implemented
- // the transfer cache optimization in the TODO above.
- USED(n);
+ MLink *next;
runtime·lock(c);
- for(v=start; v; v=next) {
- next = v->next;
- MCentral_Free(c, v);
+ for(; start != nil; start = next) {
+ next = start->next;
+ MCentral_Free(c, start);
}
runtime·unlock(c);
}
@@ -108,7 +85,7 @@ MCentral_Free(MCentral *c, void *v)
int32 size;
// Find span for v.
- s = runtime·MHeap_Lookup(runtime·mheap, v);
+ s = runtime·MHeap_Lookup(&runtime·mheap, v);
if(s == nil || s->ref == 0)
runtime·throw("invalid free");
@@ -133,7 +110,7 @@ MCentral_Free(MCentral *c, void *v)
s->freelist = nil;
c->nfree -= (s->npages << PageShift) / size;
runtime·unlock(c);
- runtime·MHeap_Free(runtime·mheap, s, 0);
+ runtime·MHeap_Free(&runtime·mheap, s, 0);
runtime·lock(c);
}
}
@@ -168,7 +145,7 @@ runtime·MCentral_FreeSpan(MCentral *c, MSpan *s, int32 n, MLink *start, MLink *
c->nfree -= (s->npages << PageShift) / size;
runtime·unlock(c);
runtime·unmarkspan((byte*)(s->start<<PageShift), s->npages<<PageShift);
- runtime·MHeap_Free(runtime·mheap, s, 0);
+ runtime·MHeap_Free(&runtime·mheap, s, 0);
} else {
runtime·unlock(c);
}
@@ -200,7 +177,7 @@ MCentral_Grow(MCentral *c)
runtime·unlock(c);
runtime·MGetSizeClassInfo(c->sizeclass, &size, &npages, &n);
- s = runtime·MHeap_Alloc(runtime·mheap, npages, c->sizeclass, 0, 1);
+ s = runtime·MHeap_Alloc(&runtime·mheap, npages, c->sizeclass, 0, 1);
if(s == nil) {
// TODO(rsc): Log out of memory
runtime·lock(c);