github.com/timandy/routine@v1.1.4-0.20240507073150-e4a3e1fe2ba5/goid_test.go (about)

     1  package routine
     2  
     3  import (
     4  	"reflect"
     5  	"runtime"
     6  	"testing"
     7  	"unsafe"
     8  
     9  	"github.com/stretchr/testify/assert"
    10  )
    11  
    12  func TestG_Goid(t *testing.T) {
    13  	runTest(t, func() {
    14  		gp := getg()
    15  		runtime.GC()
    16  		assert.Equal(t, curGoroutineID(), gp.goid)
    17  	})
    18  }
    19  
    20  func TestG_Paniconfault(t *testing.T) {
    21  	runTest(t, func() {
    22  		gp := getg()
    23  		runtime.GC()
    24  		//read-1
    25  		assert.False(t, setPanicOnFault(false))
    26  		assert.False(t, gp.getPanicOnFault())
    27  		//read-2
    28  		setPanicOnFault(true)
    29  		assert.True(t, gp.getPanicOnFault())
    30  		//write-1
    31  		gp.setPanicOnFault(false)
    32  		assert.False(t, setPanicOnFault(false))
    33  		//write-2
    34  		gp.setPanicOnFault(true)
    35  		assert.True(t, setPanicOnFault(true))
    36  		//write-read-1
    37  		gp.setPanicOnFault(false)
    38  		assert.False(t, gp.getPanicOnFault())
    39  		//write-read-2
    40  		gp.setPanicOnFault(true)
    41  		assert.True(t, gp.getPanicOnFault())
    42  		//restore
    43  		gp.setPanicOnFault(false)
    44  	})
    45  }
    46  
    47  func TestG_Gopc(t *testing.T) {
    48  	runTest(t, func() {
    49  		gp := getg()
    50  		runtime.GC()
    51  		assert.Greater(t, int64(*gp.gopc), int64(0))
    52  	})
    53  }
    54  
    55  func TestG_ProfLabel(t *testing.T) {
    56  	runTest(t, func() {
    57  		ptr := unsafe.Pointer(&struct{}{})
    58  		null := unsafe.Pointer(nil)
    59  		assert.NotEqual(t, ptr, null)
    60  		//
    61  		gp := getg()
    62  		runtime.GC()
    63  		//read-1
    64  		assert.Equal(t, null, getProfLabel())
    65  		assert.Equal(t, null, gp.getLabels())
    66  		//read-2
    67  		setProfLabel(ptr)
    68  		assert.Equal(t, ptr, gp.getLabels())
    69  		//write-1
    70  		gp.setLabels(nil)
    71  		assert.Equal(t, null, getProfLabel())
    72  		//write-2
    73  		gp.setLabels(ptr)
    74  		assert.Equal(t, ptr, getProfLabel())
    75  		//write-read-1
    76  		gp.setLabels(nil)
    77  		assert.Equal(t, null, gp.getLabels())
    78  		//write-read-2
    79  		gp.setLabels(ptr)
    80  		assert.Equal(t, ptr, gp.getLabels())
    81  		//restore
    82  		gp.setLabels(null)
    83  	})
    84  }
    85  
    86  func TestOffset(t *testing.T) {
    87  	runTest(t, func() {
    88  		assert.Panics(t, func() {
    89  			gt := reflect.TypeOf(0)
    90  			offset(gt, "hello")
    91  		})
    92  		assert.PanicsWithValue(t, "No such field 'hello' of struct 'runtime.g'.", func() {
    93  			gt := getgt()
    94  			offset(gt, "hello")
    95  		})
    96  	})
    97  }
    98  
    99  // curGoroutineID parse the current g's goid from caller stack.
   100  //
   101  //go:linkname curGoroutineID net/http.http2curGoroutineID
   102  func curGoroutineID() int64
   103  
   104  // setPanicOnFault controls the runtime's behavior when a program faults at an unexpected (non-nil) address.
   105  //
   106  //go:linkname setPanicOnFault runtime/debug.setPanicOnFault
   107  func setPanicOnFault(new bool) (old bool)
   108  
   109  // getProfLabel get current g's labels which will be inherited by new goroutine.
   110  //
   111  //go:linkname getProfLabel runtime/pprof.runtime_getProfLabel
   112  func getProfLabel() unsafe.Pointer
   113  
   114  // setProfLabel set current g's labels which will be inherited by new goroutine.
   115  //
   116  //go:linkname setProfLabel runtime/pprof.runtime_setProfLabel
   117  func setProfLabel(labels unsafe.Pointer)
   118  
   119  //===
   120  
   121  // BenchmarkGohack-8                               258425366                4.808 ns/op           0 B/op          0 allocs/op
   122  func BenchmarkGohack(b *testing.B) {
   123  	_ = getg()
   124  	b.ReportAllocs()
   125  	b.ResetTimer()
   126  	for i := 0; i < b.N; i++ {
   127  		gp := getg()
   128  		_ = gp.goid
   129  		_ = gp.gopc
   130  		_ = gp.getLabels()
   131  		_ = gp.getPanicOnFault()
   132  		gp.setLabels(nil)
   133  		gp.setPanicOnFault(false)
   134  	}
   135  }