5757	gcMallocs      uint64          // total number of allocations 
5858	gcFrees        uint64          // total number of objects freed 
5959	gcFreedBlocks  uint64          // total number of freed blocks 
60+ 	gcLock         task.PMutex     // lock to avoid race conditions on multicore systems 
6061)
6162
6263// 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 {
317318		runtimePanicAt (returnAddress (0 ), "heap alloc in interrupt" )
318319	}
319320
321+ 	// Make sure there are no concurrent allocations. The heap is not currently 
322+ 	// designed for concurrent alloc/GC. 
323+ 	gcLock .Lock ()
324+ 
320325	gcTotalAlloc  +=  uint64 (size )
321326	gcMallocs ++ 
322327
@@ -399,6 +404,9 @@ func alloc(size uintptr, layout unsafe.Pointer) unsafe.Pointer {
399404				i .setState (blockStateTail )
400405			}
401406
407+ 			// We've claimed this allocation, now we can unlock the heap. 
408+ 			gcLock .Unlock ()
409+ 
402410			// Return a pointer to this allocation. 
403411			pointer  :=  thisAlloc .pointer ()
404412			if  preciseHeap  {
@@ -444,7 +452,9 @@ func free(ptr unsafe.Pointer) {
444452
445453// GC performs a garbage collection cycle. 
446454func  GC () {
455+ 	gcLock .Lock ()
447456	runGC ()
457+ 	gcLock .Unlock ()
448458}
449459
450460// runGC performs a garbage collection cycle. It is the internal implementation 
@@ -713,6 +723,7 @@ func dumpHeap() {
713723// The returned memory statistics are up to date as of the 
714724// call to ReadMemStats. This would not do GC implicitly for you. 
715725func  ReadMemStats (m  * MemStats ) {
726+ 	gcLock .Lock ()
716727	m .HeapIdle  =  0 
717728	m .HeapInuse  =  0 
718729	for  block  :=  gcBlock (0 ); block  <  endBlock ; block ++  {
@@ -732,6 +743,7 @@ func ReadMemStats(m *MemStats) {
732743	m .Sys  =  uint64 (heapEnd  -  heapStart )
733744	m .HeapAlloc  =  (gcTotalBlocks  -  gcFreedBlocks ) *  uint64 (bytesPerBlock )
734745	m .Alloc  =  m .HeapAlloc 
746+ 	gcLock .Unlock ()
735747}
736748
737749func  SetFinalizer (obj  interface {}, finalizer  interface {}) {
0 commit comments