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