github.com/sbinet/go@v0.0.0-20160827155028-54d7de7dd62b/src/runtime/export_test.go (about)

     1  // Copyright 2010 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  // Export guts for testing.
     6  
     7  package runtime
     8  
     9  import (
    10  	"runtime/internal/atomic"
    11  	"runtime/internal/sys"
    12  	"unsafe"
    13  )
    14  
    15  var Fadd64 = fadd64
    16  var Fsub64 = fsub64
    17  var Fmul64 = fmul64
    18  var Fdiv64 = fdiv64
    19  var F64to32 = f64to32
    20  var F32to64 = f32to64
    21  var Fcmp64 = fcmp64
    22  var Fintto64 = fintto64
    23  var F64toint = f64toint
    24  var Sqrt = sqrt
    25  
    26  var Entersyscall = entersyscall
    27  var Exitsyscall = exitsyscall
    28  var LockedOSThread = lockedOSThread
    29  var Xadduintptr = atomic.Xadduintptr
    30  
    31  var FuncPC = funcPC
    32  
    33  var Fastlog2 = fastlog2
    34  
    35  type LFNode struct {
    36  	Next    uint64
    37  	Pushcnt uintptr
    38  }
    39  
    40  func LFStackPush(head *uint64, node *LFNode) {
    41  	lfstackpush(head, (*lfnode)(unsafe.Pointer(node)))
    42  }
    43  
    44  func LFStackPop(head *uint64) *LFNode {
    45  	return (*LFNode)(unsafe.Pointer(lfstackpop(head)))
    46  }
    47  
    48  func GCMask(x interface{}) (ret []byte) {
    49  	systemstack(func() {
    50  		ret = getgcmask(x)
    51  	})
    52  	return
    53  }
    54  
    55  func RunSchedLocalQueueTest() {
    56  	_p_ := new(p)
    57  	gs := make([]g, len(_p_.runq))
    58  	for i := 0; i < len(_p_.runq); i++ {
    59  		if g, _ := runqget(_p_); g != nil {
    60  			throw("runq is not empty initially")
    61  		}
    62  		for j := 0; j < i; j++ {
    63  			runqput(_p_, &gs[i], false)
    64  		}
    65  		for j := 0; j < i; j++ {
    66  			if g, _ := runqget(_p_); g != &gs[i] {
    67  				print("bad element at iter ", i, "/", j, "\n")
    68  				throw("bad element")
    69  			}
    70  		}
    71  		if g, _ := runqget(_p_); g != nil {
    72  			throw("runq is not empty afterwards")
    73  		}
    74  	}
    75  }
    76  
    77  func RunSchedLocalQueueStealTest() {
    78  	p1 := new(p)
    79  	p2 := new(p)
    80  	gs := make([]g, len(p1.runq))
    81  	for i := 0; i < len(p1.runq); i++ {
    82  		for j := 0; j < i; j++ {
    83  			gs[j].sig = 0
    84  			runqput(p1, &gs[j], false)
    85  		}
    86  		gp := runqsteal(p2, p1, true)
    87  		s := 0
    88  		if gp != nil {
    89  			s++
    90  			gp.sig++
    91  		}
    92  		for {
    93  			gp, _ = runqget(p2)
    94  			if gp == nil {
    95  				break
    96  			}
    97  			s++
    98  			gp.sig++
    99  		}
   100  		for {
   101  			gp, _ = runqget(p1)
   102  			if gp == nil {
   103  				break
   104  			}
   105  			gp.sig++
   106  		}
   107  		for j := 0; j < i; j++ {
   108  			if gs[j].sig != 1 {
   109  				print("bad element ", j, "(", gs[j].sig, ") at iter ", i, "\n")
   110  				throw("bad element")
   111  			}
   112  		}
   113  		if s != i/2 && s != i/2+1 {
   114  			print("bad steal ", s, ", want ", i/2, " or ", i/2+1, ", iter ", i, "\n")
   115  			throw("bad steal")
   116  		}
   117  	}
   118  }
   119  
   120  func RunSchedLocalQueueEmptyTest(iters int) {
   121  	// Test that runq is not spuriously reported as empty.
   122  	// Runq emptiness affects scheduling decisions and spurious emptiness
   123  	// can lead to underutilization (both runnable Gs and idle Ps coexist
   124  	// for arbitrary long time).
   125  	done := make(chan bool, 1)
   126  	p := new(p)
   127  	gs := make([]g, 2)
   128  	ready := new(uint32)
   129  	for i := 0; i < iters; i++ {
   130  		*ready = 0
   131  		next0 := (i & 1) == 0
   132  		next1 := (i & 2) == 0
   133  		runqput(p, &gs[0], next0)
   134  		go func() {
   135  			for atomic.Xadd(ready, 1); atomic.Load(ready) != 2; {
   136  			}
   137  			if runqempty(p) {
   138  				println("next:", next0, next1)
   139  				throw("queue is empty")
   140  			}
   141  			done <- true
   142  		}()
   143  		for atomic.Xadd(ready, 1); atomic.Load(ready) != 2; {
   144  		}
   145  		runqput(p, &gs[1], next1)
   146  		runqget(p)
   147  		<-done
   148  		runqget(p)
   149  	}
   150  }
   151  
   152  var StringHash = stringHash
   153  var BytesHash = bytesHash
   154  var Int32Hash = int32Hash
   155  var Int64Hash = int64Hash
   156  var EfaceHash = efaceHash
   157  var IfaceHash = ifaceHash
   158  var MemclrBytes = memclrBytes
   159  
   160  var HashLoad = &hashLoad
   161  
   162  // entry point for testing
   163  func GostringW(w []uint16) (s string) {
   164  	systemstack(func() {
   165  		s = gostringw(&w[0])
   166  	})
   167  	return
   168  }
   169  
   170  var Gostringnocopy = gostringnocopy
   171  var Maxstring = &maxstring
   172  
   173  type Uintreg sys.Uintreg
   174  
   175  var Open = open
   176  var Close = closefd
   177  var Read = read
   178  var Write = write
   179  
   180  func Envs() []string     { return envs }
   181  func SetEnvs(e []string) { envs = e }
   182  
   183  var BigEndian = sys.BigEndian
   184  
   185  // For benchmarking.
   186  
   187  func BenchSetType(n int, x interface{}) {
   188  	e := *efaceOf(&x)
   189  	t := e._type
   190  	var size uintptr
   191  	var p unsafe.Pointer
   192  	switch t.kind & kindMask {
   193  	case kindPtr:
   194  		t = (*ptrtype)(unsafe.Pointer(t)).elem
   195  		size = t.size
   196  		p = e.data
   197  	case kindSlice:
   198  		slice := *(*struct {
   199  			ptr      unsafe.Pointer
   200  			len, cap uintptr
   201  		})(e.data)
   202  		t = (*slicetype)(unsafe.Pointer(t)).elem
   203  		size = t.size * slice.len
   204  		p = slice.ptr
   205  	}
   206  	allocSize := roundupsize(size)
   207  	systemstack(func() {
   208  		for i := 0; i < n; i++ {
   209  			heapBitsSetType(uintptr(p), allocSize, size, t)
   210  		}
   211  	})
   212  }
   213  
   214  const PtrSize = sys.PtrSize
   215  
   216  var TestingAssertE2I2GC = &testingAssertE2I2GC
   217  var TestingAssertE2T2GC = &testingAssertE2T2GC
   218  
   219  var ForceGCPeriod = &forcegcperiod
   220  
   221  // SetTracebackEnv is like runtime/debug.SetTraceback, but it raises
   222  // the "environment" traceback level, so later calls to
   223  // debug.SetTraceback (e.g., from testing timeouts) can't lower it.
   224  func SetTracebackEnv(level string) {
   225  	setTraceback(level)
   226  	traceback_env = traceback_cache
   227  }
   228  
   229  var ReadUnaligned32 = readUnaligned32
   230  var ReadUnaligned64 = readUnaligned64
   231  
   232  func CountPagesInUse() (pagesInUse, counted uintptr) {
   233  	stopTheWorld("CountPagesInUse")
   234  
   235  	pagesInUse = uintptr(mheap_.pagesInUse)
   236  
   237  	for _, s := range h_allspans {
   238  		if s.state == mSpanInUse {
   239  			counted += s.npages
   240  		}
   241  	}
   242  
   243  	startTheWorld()
   244  
   245  	return
   246  }