- Add Bugzilla PRs to ChangeLog reverting AIX long double size.
[official-gcc.git] / libgo / runtime / mcache.c
blobce65757587d3fa83ef2517e659fa88d816c65942
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.
5 // Per-thread (in Go, per-M) malloc cache for small objects.
6 //
7 // See malloc.h for an overview.
9 #include "runtime.h"
10 #include "malloc.h"
12 void*
13 runtime_MCache_Alloc(MCache *c, int32 sizeclass, uintptr size, int32 zeroed)
15 MCacheList *l;
16 MLink *first, *v;
17 int32 n;
19 // Allocate from list.
20 l = &c->list[sizeclass];
21 if(l->list == nil) {
22 // Replenish using central lists.
23 n = runtime_MCentral_AllocList(&runtime_mheap.central[sizeclass],
24 runtime_class_to_transfercount[sizeclass], &first);
25 l->list = first;
26 l->nlist = n;
27 c->size += n*size;
29 v = l->list;
30 l->list = v->next;
31 l->nlist--;
32 if(l->nlist < l->nlistmin)
33 l->nlistmin = l->nlist;
34 c->size -= size;
36 // v is zeroed except for the link pointer
37 // that we used above; zero that.
38 v->next = nil;
39 if(zeroed) {
40 // block is zeroed iff second word is zero ...
41 if(size > sizeof(uintptr) && ((uintptr*)v)[1] != 0)
42 runtime_memclr((byte*)v, size);
43 else {
44 // ... except for the link pointer
45 // that we used above; zero that.
46 v->next = nil;
49 c->local_alloc += size;
50 c->local_objects++;
51 return v;
54 // Take n elements off l and return them to the central free list.
55 static void
56 ReleaseN(MCache *c, MCacheList *l, int32 n, int32 sizeclass)
58 MLink *first, **lp;
59 int32 i;
61 // Cut off first n elements.
62 first = l->list;
63 lp = &l->list;
64 for(i=0; i<n; i++)
65 lp = &(*lp)->next;
66 l->list = *lp;
67 *lp = nil;
68 l->nlist -= n;
69 if(l->nlist < l->nlistmin)
70 l->nlistmin = l->nlist;
71 c->size -= n*runtime_class_to_size[sizeclass];
73 // Return them to central free list.
74 runtime_MCentral_FreeList(&runtime_mheap.central[sizeclass], n, first);
77 void
78 runtime_MCache_Free(MCache *c, void *v, int32 sizeclass, uintptr size)
80 int32 i, n;
81 MCacheList *l;
82 MLink *p;
84 // Put back on list.
85 l = &c->list[sizeclass];
86 p = v;
87 p->next = l->list;
88 l->list = p;
89 l->nlist++;
90 c->size += size;
91 c->local_alloc -= size;
92 c->local_objects--;
94 if(l->nlist >= MaxMCacheListLen) {
95 // Release a chunk back.
96 ReleaseN(c, l, runtime_class_to_transfercount[sizeclass], sizeclass);
99 if(c->size >= MaxMCacheSize) {
100 // Scavenge.
101 for(i=0; i<NumSizeClasses; i++) {
102 l = &c->list[i];
103 n = l->nlistmin;
105 // n is the minimum number of elements we've seen on
106 // the list since the last scavenge. If n > 0, it means that
107 // we could have gotten by with n fewer elements
108 // without needing to consult the central free list.
109 // Move toward that situation by releasing n/2 of them.
110 if(n > 0) {
111 if(n > 1)
112 n /= 2;
113 ReleaseN(c, l, n, i);
115 l->nlistmin = l->nlist;
120 void
121 runtime_MCache_ReleaseAll(MCache *c)
123 int32 i;
124 MCacheList *l;
126 for(i=0; i<NumSizeClasses; i++) {
127 l = &c->list[i];
128 ReleaseN(c, l, l->nlist, i);
129 l->nlistmin = 0;