{
MSpan *next; // in a span linked list
MSpan *prev; // in a span linked list
- MSpan *allnext; // in the list of all spans
PageID start; // starting page number
uintptr npages; // number of pages in span
MLink *freelist; // list of free objects
Lock;
MSpan free[MaxMHeapList]; // free lists of given length
MSpan large; // free lists length >= MaxMHeapList
- MSpan *allspans;
+ MSpan **allspans;
+ uint32 nspan;
+ uint32 nspancap;
// span lookup
MSpan *map[1<<MHeapMap_Bits];
Note alldone;
Lock markgate;
Lock sweepgate;
- MSpan *spans;
+ uint32 spanidx;
Lock;
byte *chunk;
static void
sweep(void)
{
- MSpan *s;
+ MSpan *s, **allspans;
int64 now;
+ uint32 spanidx, nspan;
now = runtime·nanotime();
+ nspan = runtime·mheap.nspan;
+ allspans = runtime·mheap.allspans;
for(;;) {
- s = work.spans;
- if(s == nil)
+ spanidx = runtime·xadd(&work.spanidx, 1) - 1;
+ if(spanidx >= nspan)
break;
- if(!runtime·casp(&work.spans, s, s->allnext))
- continue;
+ s = allspans[spanidx];
// Stamp newly unused spans. The scavenger will use that
// info to potentially give back some pages to the OS.
mark(debug_scanblock);
t1 = runtime·nanotime();
- work.spans = runtime·mheap.allspans;
+ work.spanidx = 0;
runtime·unlock(&work.sweepgate); // let the helpers in
sweep();
if(work.nproc > 1)
{
MHeap *h;
MSpan *s;
+ MSpan **all;
+ uint32 cap;
h = vh;
s = (MSpan*)p;
- s->allnext = h->allspans;
- h->allspans = s;
+ if(h->nspan >= h->nspancap) {
+ cap = 64*1024/sizeof(all[0]);
+ if(cap < h->nspancap*3/2)
+ cap = h->nspancap*3/2;
+ all = (MSpan**)runtime·SysAlloc(cap*sizeof(all[0]));
+ if(h->allspans) {
+ runtime·memmove(all, h->allspans, h->nspancap*sizeof(all[0]));
+ runtime·SysFree(h->allspans, h->nspancap*sizeof(all[0]));
+ }
+ h->allspans = all;
+ h->nspancap = cap;
+ }
+ h->allspans[h->nspan++] = s;
}
// Initialize the heap; fetch memory using alloc.