57
57
gcMallocs uint64 // total number of allocations
58
58
gcFrees uint64 // total number of objects freed
59
59
gcFreedBlocks uint64 // total number of freed blocks
60
+ gcLock task.PMutex // lock to avoid race conditions on multicore systems
60
61
)
61
62
62
63
// zeroSizedAlloc is just a sentinel that gets returned when allocating 0 bytes.
@@ -317,6 +318,10 @@ func alloc(size uintptr, layout unsafe.Pointer) unsafe.Pointer {
317
318
runtimePanicAt (returnAddress (0 ), "heap alloc in interrupt" )
318
319
}
319
320
321
+ // Make sure there are no concurrent allocations. The heap is not currently
322
+ // designed for concurrent alloc/GC.
323
+ gcLock .Lock ()
324
+
320
325
gcTotalAlloc += uint64 (size )
321
326
gcMallocs ++
322
327
@@ -399,6 +404,9 @@ func alloc(size uintptr, layout unsafe.Pointer) unsafe.Pointer {
399
404
i .setState (blockStateTail )
400
405
}
401
406
407
+ // We've claimed this allocation, now we can unlock the heap.
408
+ gcLock .Unlock ()
409
+
402
410
// Return a pointer to this allocation.
403
411
pointer := thisAlloc .pointer ()
404
412
if preciseHeap {
@@ -444,7 +452,9 @@ func free(ptr unsafe.Pointer) {
444
452
445
453
// GC performs a garbage collection cycle.
446
454
func GC () {
455
+ gcLock .Lock ()
447
456
runGC ()
457
+ gcLock .Unlock ()
448
458
}
449
459
450
460
// runGC performs a garbage collection cycle. It is the internal implementation
@@ -713,6 +723,7 @@ func dumpHeap() {
713
723
// The returned memory statistics are up to date as of the
714
724
// call to ReadMemStats. This would not do GC implicitly for you.
715
725
func ReadMemStats (m * MemStats ) {
726
+ gcLock .Lock ()
716
727
m .HeapIdle = 0
717
728
m .HeapInuse = 0
718
729
for block := gcBlock (0 ); block < endBlock ; block ++ {
@@ -732,6 +743,7 @@ func ReadMemStats(m *MemStats) {
732
743
m .Sys = uint64 (heapEnd - heapStart )
733
744
m .HeapAlloc = (gcTotalBlocks - gcFreedBlocks ) * uint64 (bytesPerBlock )
734
745
m .Alloc = m .HeapAlloc
746
+ gcLock .Unlock ()
735
747
}
736
748
737
749
func SetFinalizer (obj interface {}, finalizer interface {}) {
0 commit comments