示例#1
0
// Return span from an MCache.
void
runtime·MCentral_UncacheSpan(MCentral *c, MSpan *s)
{
	MLink *v;
	int32 cap, n;

	runtime·lock(c);

	s->incache = false;

	// Move any explicitly freed items from the freebuf to the freelist.
	while((v = s->freebuf) != nil) {
		s->freebuf = v->next;
		runtime·markfreed(v);
		v->next = s->freelist;
		s->freelist = v;
		s->ref--;
	}

	if(s->ref == 0) {
		// Free back to heap.  Unlikely, but possible.
		MCentral_ReturnToHeap(c, s); // unlocks c
		return;
	}
	
	cap = (s->npages << PageShift) / s->elemsize;
	n = cap - s->ref;
	if(n > 0) {
		c->nfree += n;
		runtime·MSpanList_Remove(s);
		runtime·MSpanList_Insert(&c->nonempty, s);
	}
	runtime·unlock(c);
}
示例#2
0
void 
runtime·free ( void *v ) 
{ 
int32 sizeclass; 
MSpan *s; 
MCache *c; 
uint32 prof; 
uintptr size; 
#line 2161 "C:\Go\src\pkg\runtime\malloc.goc"
if ( v == nil ) 
return; 
#line 2167 "C:\Go\src\pkg\runtime\malloc.goc"
if ( m->mallocing ) 
runtime·throw ( "malloc/free - deadlock" ) ; 
m->mallocing = 1; 
#line 2171 "C:\Go\src\pkg\runtime\malloc.goc"
if ( !runtime·mlookup ( v , nil , nil , &s ) ) { 
runtime·printf ( "free %p: not an allocated block\n" , v ) ; 
runtime·throw ( "free runtime·mlookup" ) ; 
} 
prof = runtime·blockspecial ( v ) ; 
#line 2178 "C:\Go\src\pkg\runtime\malloc.goc"
sizeclass = s->sizeclass; 
c = m->mcache; 
if ( sizeclass == 0 ) { 
#line 2182 "C:\Go\src\pkg\runtime\malloc.goc"
size = s->npages<<PageShift; 
* ( uintptr* ) ( s->start<<PageShift ) = 1; 
#line 2186 "C:\Go\src\pkg\runtime\malloc.goc"
runtime·markfreed ( v , size ) ; 
runtime·unmarkspan ( v , 1<<PageShift ) ; 
runtime·MHeap_Free ( &runtime·mheap , s , 1 ) ; 
} else { 
#line 2191 "C:\Go\src\pkg\runtime\malloc.goc"
size = runtime·class_to_size[sizeclass]; 
if ( size > sizeof ( uintptr ) ) 
( ( uintptr* ) v ) [1] = 1; 
#line 2197 "C:\Go\src\pkg\runtime\malloc.goc"
runtime·markfreed ( v , size ) ; 
c->local_by_size[sizeclass].nfree++; 
runtime·MCache_Free ( c , v , sizeclass , size ) ; 
} 
c->local_alloc -= size; 
if ( prof ) 
runtime·MProf_Free ( v , size ) ; 
m->mallocing = 0; 
} 
示例#3
0
// Helper: free one object back into the central free list.
// Caller must hold lock on c on entry.  Holds lock on exit.
static void
MCentral_Free(MCentral *c, MLink *v)
{
	MSpan *s;

	// Find span for v.
	s = runtime·MHeap_Lookup(&runtime·mheap, v);
	if(s == nil || s->ref == 0)
		runtime·throw("invalid free");
	if(s->sweepgen != runtime·mheap.sweepgen)
		runtime·throw("free into unswept span");
	
	// If the span is currently being used unsynchronized by an MCache,
	// we can't modify the freelist.  Add to the freebuf instead.  The
	// items will get moved to the freelist when the span is returned
	// by the MCache.
	if(s->incache) {
		v->next = s->freebuf;
		s->freebuf = v;
		return;
	}

	// Move span to nonempty if necessary.
	if(s->freelist == nil) {
		runtime·MSpanList_Remove(s);
		runtime·MSpanList_Insert(&c->nonempty, s);
	}

	// Add the object to span's free list.
	runtime·markfreed(v);
	v->next = s->freelist;
	s->freelist = v;
	s->ref--;
	c->nfree++;

	// If s is completely freed, return it to the heap.
	if(s->ref == 0) {
		MCentral_ReturnToHeap(c, s); // unlocks c
		runtime·lock(c);
	}
}