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-P malloc cache for small objects.
7 // See malloc.h for an overview.
13 extern volatile intgo runtime_MemProfileRate
14 __asm__ (GOSYM_PREFIX
"runtime.MemProfileRate");
16 // dummy MSpan that contains no free objects.
17 static MSpan emptymspan
;
20 runtime_allocmcache(void)
26 runtime_lock(&runtime_mheap
);
27 c
= runtime_FixAlloc_Alloc(&runtime_mheap
.cachealloc
);
28 runtime_unlock(&runtime_mheap
);
29 runtime_memclr((byte
*)c
, sizeof(*c
));
30 for(i
= 0; i
< NumSizeClasses
; i
++)
31 c
->alloc
[i
] = &emptymspan
;
33 // Set first allocation sample size.
34 rate
= runtime_MemProfileRate
;
35 if(rate
> 0x3fffffff) // make 2*rate not overflow
38 c
->next_sample
= runtime_fastrand1() % (2*rate
);
44 runtime_freemcache(MCache
*c
)
46 runtime_MCache_ReleaseAll(c
);
47 runtime_lock(&runtime_mheap
);
48 runtime_purgecachedstats(c
);
49 runtime_FixAlloc_Free(&runtime_mheap
.cachealloc
, c
);
50 runtime_unlock(&runtime_mheap
);
53 // Gets a span that has a free object in it and assigns it
54 // to be the cached span for the given sizeclass. Returns this span.
56 runtime_MCache_Refill(MCache
*c
, int32 sizeclass
)
62 // Return the current cached span to the central lists.
63 s
= c
->alloc
[sizeclass
];
64 if(s
->freelist
!= nil
)
65 runtime_throw("refill on a nonempty span");
67 runtime_MCentral_UncacheSpan(&runtime_mheap
.central
[sizeclass
], s
);
69 // Push any explicitly freed objects to the central lists.
70 // Not required, but it seems like a good time to do it.
71 l
= &c
->free
[sizeclass
];
73 runtime_MCentral_FreeList(&runtime_mheap
.central
[sizeclass
], l
->list
);
78 // Get a new cached span from the central lists.
79 s
= runtime_MCentral_CacheSpan(&runtime_mheap
.central
[sizeclass
]);
81 runtime_throw("out of memory");
82 if(s
->freelist
== nil
) {
83 runtime_printf("%d %d\n", s
->ref
, (int32
)((s
->npages
<< PageShift
) / s
->elemsize
));
84 runtime_throw("empty span");
86 c
->alloc
[sizeclass
] = s
;
92 runtime_MCache_Free(MCache
*c
, MLink
*p
, int32 sizeclass
, uintptr size
)
97 l
= &c
->free
[sizeclass
];
102 // We transfer a span at a time from MCentral to MCache,
103 // so we'll do the same in the other direction.
104 if(l
->nlist
>= (runtime_class_to_allocnpages
[sizeclass
]<<PageShift
)/size
) {
105 runtime_MCentral_FreeList(&runtime_mheap
.central
[sizeclass
], l
->list
);
112 runtime_MCache_ReleaseAll(MCache
*c
)
118 for(i
=0; i
<NumSizeClasses
; i
++) {
120 if(s
!= &emptymspan
) {
121 runtime_MCentral_UncacheSpan(&runtime_mheap
.central
[i
], s
);
122 c
->alloc
[i
] = &emptymspan
;
126 runtime_MCentral_FreeList(&runtime_mheap
.central
[i
], l
->list
);