diff options
author | Russ Cox <rsc@golang.org> | 2014-11-11 17:05:02 -0500 |
---|---|---|
committer | Russ Cox <rsc@golang.org> | 2014-11-11 17:05:02 -0500 |
commit | 6344d561aa5585607815558be8471fe7a02ad410 (patch) | |
tree | b8766c223fd1b6bf971040246f04299ec9cbf625 /src/runtime/mcache.go | |
parent | bb9ee976541b2f008a1d1ded4bab7d823b313a53 (diff) | |
download | go-6344d561aa5585607815558be8471fe7a02ad410.tar.gz |
[dev.cc] runtime: convert memory allocator and garbage collector to Go
The conversion was done with an automated tool and then
modified only as necessary to make it compile and run.
[This CL is part of the removal of C code from package runtime.
See golang.org/s/dev.cc for an overview.]
LGTM=r
R=r
CC=austin, dvyukov, golang-codereviews, iant, khr
https://codereview.appspot.com/167540043
Diffstat (limited to 'src/runtime/mcache.go')
-rw-r--r-- | src/runtime/mcache.go | 86 |
1 files changed, 86 insertions, 0 deletions
diff --git a/src/runtime/mcache.go b/src/runtime/mcache.go new file mode 100644 index 000000000..7482bc047 --- /dev/null +++ b/src/runtime/mcache.go @@ -0,0 +1,86 @@ +// 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. + +package runtime + +import "unsafe" + +// dummy MSpan that contains no free objects. +var emptymspan mspan + +func allocmcache() *mcache { + lock(&mheap_.lock) + c := (*mcache)(fixAlloc_Alloc(&mheap_.cachealloc)) + unlock(&mheap_.lock) + memclr(unsafe.Pointer(c), unsafe.Sizeof(*c)) + for i := 0; i < _NumSizeClasses; i++ { + c.alloc[i] = &emptymspan + } + + // Set first allocation sample size. + rate := MemProfileRate + if rate > 0x3fffffff { // make 2*rate not overflow + rate = 0x3fffffff + } + if rate != 0 { + c.next_sample = int32(int(fastrand1()) % (2 * rate)) + } + + return c +} + +func freemcache(c *mcache) { + onM(func() { + mCache_ReleaseAll(c) + stackcache_clear(c) + gcworkbuffree(c.gcworkbuf) + lock(&mheap_.lock) + purgecachedstats(c) + fixAlloc_Free(&mheap_.cachealloc, unsafe.Pointer(c)) + unlock(&mheap_.lock) + }) +} + +// 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. +func mCache_Refill(c *mcache, sizeclass int32) *mspan { + _g_ := getg() + + _g_.m.locks++ + // Return the current cached span to the central lists. + s := c.alloc[sizeclass] + if s.freelist != nil { + gothrow("refill on a nonempty span") + } + if s != &emptymspan { + s.incache = false + } + + // Get a new cached span from the central lists. + s = mCentral_CacheSpan(&mheap_.central[sizeclass].mcentral) + if s == nil { + gothrow("out of memory") + } + if s.freelist == nil { + println(s.ref, (s.npages<<_PageShift)/s.elemsize) + gothrow("empty span") + } + c.alloc[sizeclass] = s + _g_.m.locks-- + return s +} + +func mCache_ReleaseAll(c *mcache) { + for i := 0; i < _NumSizeClasses; i++ { + s := c.alloc[i] + if s != &emptymspan { + mCentral_UncacheSpan(&mheap_.central[i].mcentral, s) + c.alloc[i] = &emptymspan + } + } +} |