github.com/razvanm/vanadium-go-1.3@v0.0.0-20160721203343-4a65068e5915/src/runtime/mcache.c (about)

     1  // Copyright 2009 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  // Per-P malloc cache for small objects.
     6  //
     7  // See malloc.h for an overview.
     8  
     9  #include "runtime.h"
    10  #include "arch_GOARCH.h"
    11  #include "malloc.h"
    12  
    13  extern volatile intgo runtime·MemProfileRate;
    14  
    15  // dummy MSpan that contains no free objects.
    16  MSpan runtime·emptymspan;
    17  
    18  MCache*
    19  runtime·allocmcache(void)
    20  {
    21  	intgo rate;
    22  	MCache *c;
    23  	int32 i;
    24  
    25  	runtime·lock(&runtime·mheap.lock);
    26  	c = runtime·FixAlloc_Alloc(&runtime·mheap.cachealloc);
    27  	runtime·unlock(&runtime·mheap.lock);
    28  	runtime·memclr((byte*)c, sizeof(*c));
    29  	for(i = 0; i < NumSizeClasses; i++)
    30  		c->alloc[i] = &runtime·emptymspan;
    31  
    32  	// Set first allocation sample size.
    33  	rate = runtime·MemProfileRate;
    34  	if(rate > 0x3fffffff)	// make 2*rate not overflow
    35  		rate = 0x3fffffff;
    36  	if(rate != 0)
    37  		c->next_sample = runtime·fastrand1() % (2*rate);
    38  
    39  	return c;
    40  }
    41  
    42  static void
    43  freemcache(MCache *c)
    44  {
    45  	runtime·MCache_ReleaseAll(c);
    46  	runtime·stackcache_clear(c);
    47  	runtime·gcworkbuffree(c->gcworkbuf);
    48  	runtime·lock(&runtime·mheap.lock);
    49  	runtime·purgecachedstats(c);
    50  	runtime·FixAlloc_Free(&runtime·mheap.cachealloc, c);
    51  	runtime·unlock(&runtime·mheap.lock);
    52  }
    53  
    54  static void
    55  freemcache_m(void)
    56  {
    57  	MCache *c;
    58  
    59  	c = g->m->ptrarg[0];
    60  	g->m->ptrarg[0] = nil;
    61  	freemcache(c);
    62  }
    63  
    64  void
    65  runtime·freemcache(MCache *c)
    66  {
    67  	void (*fn)(void);
    68  
    69  	g->m->ptrarg[0] = c;
    70  	fn = freemcache_m;
    71  	runtime·onM(&fn);
    72  }
    73  
    74  // Gets a span that has a free object in it and assigns it
    75  // to be the cached span for the given sizeclass.  Returns this span.
    76  MSpan*
    77  runtime·MCache_Refill(MCache *c, int32 sizeclass)
    78  {
    79  	MSpan *s;
    80  
    81  	g->m->locks++;
    82  	// Return the current cached span to the central lists.
    83  	s = c->alloc[sizeclass];
    84  	if(s->freelist != nil)
    85  		runtime·throw("refill on a nonempty span");
    86  	if(s != &runtime·emptymspan)
    87  		s->incache = false;
    88  
    89  	// Get a new cached span from the central lists.
    90  	s = runtime·MCentral_CacheSpan(&runtime·mheap.central[sizeclass].mcentral);
    91  	if(s == nil)
    92  		runtime·throw("out of memory");
    93  	if(s->freelist == nil) {
    94  		runtime·printf("%d %d\n", s->ref, (int32)((s->npages << PageShift) / s->elemsize));
    95  		runtime·throw("empty span");
    96  	}
    97  	c->alloc[sizeclass] = s;
    98  	g->m->locks--;
    99  	return s;
   100  }
   101  
   102  void
   103  runtime·MCache_ReleaseAll(MCache *c)
   104  {
   105  	int32 i;
   106  	MSpan *s;
   107  
   108  	for(i=0; i<NumSizeClasses; i++) {
   109  		s = c->alloc[i];
   110  		if(s != &runtime·emptymspan) {
   111  			runtime·MCentral_UncacheSpan(&runtime·mheap.central[i].mcentral, s);
   112  			c->alloc[i] = &runtime·emptymspan;
   113  		}
   114  	}
   115  }