why the buf size of the member mspancache in P is 128, just only use half in allocMSpanLocked()

120 views
Skip to first unread message

Wojoin Wu

unread,
Oct 21, 2021, 12:48:15 PM10/21/21
to golang-nuts
// allocMSpanLocked allocates an mspan object.
//
// h.lock must be held.
//
// allocMSpanLocked must be called on the system stack because
// its caller holds the heap lock. See mheap for details.
// Running on the system stack also ensures that we won't
// switch Ps during this function. See tryAllocMSpan for details.
//go:systemstack
func (h *mheap) allocMSpanLocked() *mspan {
assertLockHeld(&h.lock)

pp := getg().m.p.ptr()
if pp == nil {
// We don't have a p so just do the normal thing.
return (*mspan)(h.spanalloc.alloc())
}
// Refill the cache if necessary.
if pp.mspancache.len == 0 {
const refillCount = len(pp.mspancache.buf) / 2
for i := 0; i < refillCount; i++ {
pp.mspancache.buf[i] = (*mspan)(h.spanalloc.alloc())
}
pp.mspancache.len = refillCount
}
// Pull off the last entry in the cache.
s := pp.mspancache.buf[pp.mspancache.len-1]
pp.mspancache.len--
return s
}

Why the value of refillCount just only has half of p.mspancache.buf ?

Thanks.

Ian Lance Taylor

unread,
Oct 21, 2021, 4:25:26 PM10/21/21
to Wojoin Wu, golang-nuts
On Thu, Oct 21, 2021 at 9:48 AM Wojoin Wu <wojo...@gmail.com> wrote:
>
> Why the value of refillCount just only has half of p.mspancache.buf ?

Because the freeMSpanLocked method will add the MSpan being freed to
the cache if possible. If the cache is full, then freeMSpanLocked has
to release it to the general pool, for some future call to
allocMSpanLocked. It's better for the cache to be neither entirely
full nor entirely empty. Setting it to half full is a compromise.

Ian
Reply all
Reply to author
Forward
0 new messages