github.com/MeteorsLiu/simpleMQ@v1.0.3/queue/kill_test.go (about)

     1  //go:build !windows
     2  
     3  package queue
     4  
     5  // the following test is NOT stable.
     6  // DON'T USE
     7  
     8  import (
     9  	"sync"
    10  	"syscall"
    11  	"testing"
    12  	"time"
    13  	"unsafe"
    14  	_ "unsafe"
    15  
    16  	"github.com/MeteorsLiu/getm"
    17  )
    18  
    19  type PID struct {
    20  	pid int
    21  	tid int
    22  	m   uintptr
    23  	g   uintptr
    24  }
    25  
    26  //go:linkname suspendG runtime.suspendG
    27  func suspendG(unsafe.Pointer)
    28  
    29  //go:linkname systemstack runtime.systemstack
    30  func systemstack(f func())
    31  
    32  //go:linkname casGToWaiting runtime.casGToWaiting
    33  func casGToWaiting(gp unsafe.Pointer, old uint32, reason uint8)
    34  
    35  //go:linkname casgstatus runtime.casgstatus
    36  func casgstatus(gp unsafe.Pointer, oldval, newval uint32)
    37  
    38  func TestKill(t *testing.T) {
    39  	var wg sync.WaitGroup
    40  	tgid := make(chan *PID)
    41  	wg.Add(2)
    42  	go func() {
    43  		defer wg.Done()
    44  		tgid <- &PID{
    45  			pid: syscall.Getpid(),
    46  			tid: syscall.Gettid(),
    47  			m:   getm.GetM(),
    48  			g:   getm.GetG(),
    49  		}
    50  
    51  		for {
    52  			i := 0
    53  			i++
    54  		}
    55  
    56  	}()
    57  	go func() {
    58  		defer wg.Done()
    59  		id := <-tgid
    60  
    61  		t.Log(syscall.Getpid(), syscall.Gettid(), id.pid, id.tid)
    62  		time.AfterFunc(10*time.Second, func() {
    63  			systemstack(func() {
    64  				g := unsafe.Pointer(getm.CustomInM[uintptr]("curg"))
    65  				casGToWaiting(g, 2, 7)
    66  				suspendG(unsafe.Pointer(id.g))
    67  				casgstatus(g, 4, 2)
    68  			})
    69  			t.Log("suspend G")
    70  		})
    71  	}()
    72  	wg.Wait()
    73  	t.Log("exit")
    74  	t.Log("main is still running")
    75  	time.Sleep(5 * time.Second)
    76  	t.Log("main exits")
    77  }