github.com/golang-haiku/go-1.4.3@v0.0.0-20190609233734-1f5ae41cc308/src/runtime/mgc0.go (about)

     1  // Copyright 2012 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.
     4  
     5  package runtime
     6  
     7  import "unsafe"
     8  
     9  // Called from C. Returns the Go type *m.
    10  func gc_m_ptr(ret *interface{}) {
    11  	*ret = (*m)(nil)
    12  }
    13  
    14  // Called from C. Returns the Go type *g.
    15  func gc_g_ptr(ret *interface{}) {
    16  	*ret = (*g)(nil)
    17  }
    18  
    19  // Called from C. Returns the Go type *itab.
    20  func gc_itab_ptr(ret *interface{}) {
    21  	*ret = (*itab)(nil)
    22  }
    23  
    24  func gc_unixnanotime(now *int64) {
    25  	sec, nsec := timenow()
    26  	*now = sec*1e9 + int64(nsec)
    27  }
    28  
    29  func freeOSMemory() {
    30  	gogc(2) // force GC and do eager sweep
    31  	onM(scavenge_m)
    32  }
    33  
    34  var poolcleanup func()
    35  
    36  func registerPoolCleanup(f func()) {
    37  	poolcleanup = f
    38  }
    39  
    40  func clearpools() {
    41  	// clear sync.Pools
    42  	if poolcleanup != nil {
    43  		poolcleanup()
    44  	}
    45  
    46  	for _, p := range &allp {
    47  		if p == nil {
    48  			break
    49  		}
    50  		// clear tinyalloc pool
    51  		if c := p.mcache; c != nil {
    52  			c.tiny = nil
    53  			c.tinysize = 0
    54  
    55  			// disconnect cached list before dropping it on the floor,
    56  			// so that a dangling ref to one entry does not pin all of them.
    57  			var sg, sgnext *sudog
    58  			for sg = c.sudogcache; sg != nil; sg = sgnext {
    59  				sgnext = sg.next
    60  				sg.next = nil
    61  			}
    62  			c.sudogcache = nil
    63  		}
    64  
    65  		// clear defer pools
    66  		for i := range p.deferpool {
    67  			// disconnect cached list before dropping it on the floor,
    68  			// so that a dangling ref to one entry does not pin all of them.
    69  			var d, dlink *_defer
    70  			for d = p.deferpool[i]; d != nil; d = dlink {
    71  				dlink = d.link
    72  				d.link = nil
    73  			}
    74  			p.deferpool[i] = nil
    75  		}
    76  	}
    77  }
    78  
    79  func gosweepone() uintptr
    80  func gosweepdone() bool
    81  
    82  func bgsweep() {
    83  	getg().issystem = true
    84  	for {
    85  		for gosweepone() != ^uintptr(0) {
    86  			sweep.nbgsweep++
    87  			Gosched()
    88  		}
    89  		lock(&gclock)
    90  		if !gosweepdone() {
    91  			// This can happen if a GC runs between
    92  			// gosweepone returning ^0 above
    93  			// and the lock being acquired.
    94  			unlock(&gclock)
    95  			continue
    96  		}
    97  		sweep.parked = true
    98  		goparkunlock(&gclock, "GC sweep wait")
    99  	}
   100  }
   101  
   102  // NOTE: Really dst *unsafe.Pointer, src unsafe.Pointer,
   103  // but if we do that, Go inserts a write barrier on *dst = src.
   104  //go:nosplit
   105  func writebarrierptr(dst *uintptr, src uintptr) {
   106  	*dst = src
   107  }
   108  
   109  //go:nosplit
   110  func writebarrierstring(dst *[2]uintptr, src [2]uintptr) {
   111  	dst[0] = src[0]
   112  	dst[1] = src[1]
   113  }
   114  
   115  //go:nosplit
   116  func writebarrierslice(dst *[3]uintptr, src [3]uintptr) {
   117  	dst[0] = src[0]
   118  	dst[1] = src[1]
   119  	dst[2] = src[2]
   120  }
   121  
   122  //go:nosplit
   123  func writebarrieriface(dst *[2]uintptr, src [2]uintptr) {
   124  	dst[0] = src[0]
   125  	dst[1] = src[1]
   126  }
   127  
   128  //go:nosplit
   129  func writebarrierfat2(dst *[2]uintptr, _ *byte, src [2]uintptr) {
   130  	dst[0] = src[0]
   131  	dst[1] = src[1]
   132  }
   133  
   134  //go:nosplit
   135  func writebarrierfat3(dst *[3]uintptr, _ *byte, src [3]uintptr) {
   136  	dst[0] = src[0]
   137  	dst[1] = src[1]
   138  	dst[2] = src[2]
   139  }
   140  
   141  //go:nosplit
   142  func writebarrierfat4(dst *[4]uintptr, _ *byte, src [4]uintptr) {
   143  	dst[0] = src[0]
   144  	dst[1] = src[1]
   145  	dst[2] = src[2]
   146  	dst[3] = src[3]
   147  }
   148  
   149  //go:nosplit
   150  func writebarrierfat(typ *_type, dst, src unsafe.Pointer) {
   151  	memmove(dst, src, typ.size)
   152  }