mirror of
https://github.com/golang/go
synced 2024-11-19 18:44:41 -07:00
c007ce824d
Preparation was in CL 134570043. This CL contains only the effect of 'hg mv src/pkg/* src'. For more about the move, see golang.org/s/go14nopkg.
116 lines
2.5 KiB
C
116 lines
2.5 KiB
C
// 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.
|
|
|
|
// Per-P malloc cache for small objects.
|
|
//
|
|
// See malloc.h for an overview.
|
|
|
|
#include "runtime.h"
|
|
#include "arch_GOARCH.h"
|
|
#include "malloc.h"
|
|
|
|
extern volatile intgo runtime·MemProfileRate;
|
|
|
|
// dummy MSpan that contains no free objects.
|
|
static MSpan emptymspan;
|
|
|
|
MCache*
|
|
runtime·allocmcache(void)
|
|
{
|
|
intgo rate;
|
|
MCache *c;
|
|
int32 i;
|
|
|
|
runtime·lock(&runtime·mheap.lock);
|
|
c = runtime·FixAlloc_Alloc(&runtime·mheap.cachealloc);
|
|
runtime·unlock(&runtime·mheap.lock);
|
|
runtime·memclr((byte*)c, sizeof(*c));
|
|
for(i = 0; i < NumSizeClasses; i++)
|
|
c->alloc[i] = &emptymspan;
|
|
|
|
// Set first allocation sample size.
|
|
rate = runtime·MemProfileRate;
|
|
if(rate > 0x3fffffff) // make 2*rate not overflow
|
|
rate = 0x3fffffff;
|
|
if(rate != 0)
|
|
c->next_sample = runtime·fastrand1() % (2*rate);
|
|
|
|
return c;
|
|
}
|
|
|
|
static void
|
|
freemcache(MCache *c)
|
|
{
|
|
runtime·MCache_ReleaseAll(c);
|
|
runtime·stackcache_clear(c);
|
|
runtime·gcworkbuffree(c->gcworkbuf);
|
|
runtime·lock(&runtime·mheap.lock);
|
|
runtime·purgecachedstats(c);
|
|
runtime·FixAlloc_Free(&runtime·mheap.cachealloc, c);
|
|
runtime·unlock(&runtime·mheap.lock);
|
|
}
|
|
|
|
static void
|
|
freemcache_m(void)
|
|
{
|
|
MCache *c;
|
|
|
|
c = g->m->ptrarg[0];
|
|
g->m->ptrarg[0] = nil;
|
|
freemcache(c);
|
|
}
|
|
|
|
void
|
|
runtime·freemcache(MCache *c)
|
|
{
|
|
void (*fn)(void);
|
|
|
|
g->m->ptrarg[0] = c;
|
|
fn = freemcache_m;
|
|
runtime·onM(&fn);
|
|
}
|
|
|
|
// Gets a span that has a free object in it and assigns it
|
|
// to be the cached span for the given sizeclass. Returns this span.
|
|
MSpan*
|
|
runtime·MCache_Refill(MCache *c, int32 sizeclass)
|
|
{
|
|
MSpan *s;
|
|
|
|
g->m->locks++;
|
|
// Return the current cached span to the central lists.
|
|
s = c->alloc[sizeclass];
|
|
if(s->freelist != nil)
|
|
runtime·throw("refill on a nonempty span");
|
|
if(s != &emptymspan)
|
|
s->incache = false;
|
|
|
|
// Get a new cached span from the central lists.
|
|
s = runtime·MCentral_CacheSpan(&runtime·mheap.central[sizeclass].mcentral);
|
|
if(s == nil)
|
|
runtime·throw("out of memory");
|
|
if(s->freelist == nil) {
|
|
runtime·printf("%d %d\n", s->ref, (int32)((s->npages << PageShift) / s->elemsize));
|
|
runtime·throw("empty span");
|
|
}
|
|
c->alloc[sizeclass] = s;
|
|
g->m->locks--;
|
|
return s;
|
|
}
|
|
|
|
void
|
|
runtime·MCache_ReleaseAll(MCache *c)
|
|
{
|
|
int32 i;
|
|
MSpan *s;
|
|
|
|
for(i=0; i<NumSizeClasses; i++) {
|
|
s = c->alloc[i];
|
|
if(s != &emptymspan) {
|
|
runtime·MCentral_UncacheSpan(&runtime·mheap.central[i].mcentral, s);
|
|
c->alloc[i] = &emptymspan;
|
|
}
|
|
}
|
|
}
|