Skip to content

Commit

Permalink
add runtimex/sched
Browse files Browse the repository at this point in the history
  • Loading branch information
joway committed Sep 6, 2023
1 parent 614d0af commit 92184d0
Show file tree
Hide file tree
Showing 22 changed files with 213 additions and 10 deletions.
2 changes: 1 addition & 1 deletion cloud/circuitbreaker/counter.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import (
"runtime"
"sync/atomic"

"github.com/bytedance/gopkg/internal/runtimex"
"github.com/bytedance/gopkg/lang/runtimex"
)

type Counter interface {
Expand Down
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ module github.com/bytedance/gopkg
go 1.15

require (
github.com/modern-go/reflect2 v1.0.2
github.com/stretchr/testify v1.7.0
golang.org/x/net v0.0.0-20221014081412-f15817d10f9b
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
Expand Down
2 changes: 1 addition & 1 deletion internal/wyhash/digest.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import (
"reflect"
"unsafe"

"github.com/bytedance/gopkg/internal/runtimex"
"github.com/bytedance/gopkg/lang/runtimex"
)

type Digest struct {
Expand Down
2 changes: 1 addition & 1 deletion internal/wyhash/wyhash.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import (
"unsafe"

"github.com/bytedance/gopkg/internal/hack"
"github.com/bytedance/gopkg/internal/runtimex"
"github.com/bytedance/gopkg/lang/runtimex"
)

const (
Expand Down
2 changes: 1 addition & 1 deletion lang/fastrand/fastrand.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import (
"math/bits"
"unsafe"

"github.com/bytedance/gopkg/internal/runtimex"
"github.com/bytedance/gopkg/lang/runtimex"
)

// Uint32 returns a pseudo-random 32-bit value as a uint32.
Expand Down
File renamed without changes.
8 changes: 8 additions & 0 deletions lang/runtimex/g_amd64.s
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#include "textflag.h"
#include "go_tls.h"

TEXT ·getg(SB), NOSPLIT, $0-8
get_tls(CX)
MOVQ g(CX), AX
MOVQ AX, ret+0(FP)
RET
22 changes: 22 additions & 0 deletions lang/runtimex/go_tls.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// Copyright 2014 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

#ifdef GOARCH_arm
#define LR R14
#endif

#ifdef GOARCH_amd64
#define get_tls(r) MOVQ TLS, r
#define g(r) 0(r)(TLS*1)
#endif

#ifdef GOARCH_amd64p32
#define get_tls(r) MOVL TLS, r
#define g(r) 0(r)(TLS*1)
#endif

#ifdef GOARCH_386
#define get_tls(r) MOVL TLS, r
#define g(r) 0(r)(TLS*1)
#endif
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
22 changes: 22 additions & 0 deletions internal/runtimex/runtime.go → lang/runtimex/runtime.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,25 @@ import (

//go:linkname Fastrand runtime.fastrand
func Fastrand() uint32

func getg() uintptr

type puintptr uintptr
type guintptr uintptr
type muintptr uintptr

type _m struct {
g0 uintptr // goroutine with scheduling stack
morebuf uintptr // gobuf arg to morestack
divmod uint32 // div/mod denominator for arm - known to liblink
_ uint32 // align next field to 8 bytes
procid uint64 // for debuggers, but offset not hard-coded
}

type _p struct {
id int32
status uint32 // one of pidle/prunning/...
link puintptr
schedtick uint32 // incremented on every scheduler call
syscalltick uint32 // incremented on every system call
}
69 changes: 69 additions & 0 deletions lang/runtimex/sched.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
package runtimex

import (
"log"
"unsafe"

"github.com/modern-go/reflect2"
)

var (
// types
gType = reflect2.TypeByName("runtime.g").(reflect2.StructType)
mType = reflect2.TypeByName("runtime.m").(reflect2.StructType)
pType = reflect2.TypeByName("runtime.p").(reflect2.StructType)
// fields
mField = gType.FieldByName("m")
pField = mType.FieldByName("p")
gidField = gType.FieldByName("goid")
gpreemptField = gType.FieldByName("preempt")
midField = mType.FieldByName("id")
mpreemptoffField = mType.FieldByName("preemptoff")
ppreemptField = pType.FieldByName("preempt")
prunqheadField = pType.FieldByName("runqhead")
prunqtailField = pType.FieldByName("runqtail")
//prunqField = pType.FieldByName("runq")
)

func MPreemptOff() {
g := getg()
m := *((**_m)(unsafe.Pointer(g + mField.Offset())))
preemptoff := (*string)(unsafe.Pointer((uintptr)(unsafe.Pointer(m)) + mpreemptoffField.Offset()))
if *preemptoff == "" {
*preemptoff = "holding"
}
}

func MPreemptOn() {
g := getg()
m := *((**_m)(unsafe.Pointer(g + mField.Offset())))
preemptoff := (*string)(unsafe.Pointer((uintptr)(unsafe.Pointer(m)) + mpreemptoffField.Offset()))
if *preemptoff != "" {
*preemptoff = ""
}
}

func schedlog() {
g := getg()
m := *((**_m)(unsafe.Pointer(g + mField.Offset())))
p := *((**_p)(unsafe.Pointer(uintptr(unsafe.Pointer(m)) + pField.Offset())))
gid := *((*int64)(unsafe.Pointer(g + gidField.Offset())))
gpreempt := *(*bool)(unsafe.Pointer(g + gpreemptField.Offset()))
mid := *((*int64)(unsafe.Pointer(uintptr(unsafe.Pointer(m)) + midField.Offset())))
mpreemptoff := *(*string)(unsafe.Pointer((uintptr)(unsafe.Pointer(m)) + mpreemptoffField.Offset()))
pid := p.id
pstatus := p.status
ppreempt := *(*bool)(unsafe.Pointer((uintptr)(unsafe.Pointer(p)) + ppreemptField.Offset()))
prunqhead := *(*uint32)(unsafe.Pointer((uintptr)(unsafe.Pointer(p)) + prunqheadField.Offset()))
prunqtail := *(*uint32)(unsafe.Pointer((uintptr)(unsafe.Pointer(p)) + prunqtailField.Offset()))
//prunq := *(*[256]guintptr)(unsafe.Pointer((uintptr)(unsafe.Pointer(p)) + prunqField.Offset()))
qsize := prunqtail - prunqhead
log.Printf(
"[G] gid=%d,gpreempt=%v | "+
"[M] mid=%d,mpreemptoff=%s | "+
"[P] pid=%d,pstatus=%d,ppreempt=%v,qsize=%d",
gid, gpreempt,
mid, mpreemptoff,
pid, pstatus, ppreempt, qsize,
)
}
78 changes: 78 additions & 0 deletions lang/runtimex/sched_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
package runtimex

import (
"runtime"
"sync"
"testing"
"time"
)

//go:noinline
func testStackFunction(n int) int {
var stack [1024 * 4]int64
for i := 0; i < len(stack); i++ {
stack[i] = int64(n + i)
}
return int(stack[len(stack)/2])
}

func TestCPUBondSingleP(t *testing.T) {
runtime.GOMAXPROCS(4)
const (
tasks = 8
interval = 1000000
round = 1000
)
begin := time.Now()
var wg sync.WaitGroup
for t := 0; t < tasks; t++ {
wg.Add(1)
go func(n int) {
defer wg.Done()
if n == 0 {
MPreemptOff()
defer MPreemptOn()
}
for i := 0; i < round*interval; i++ {
if i%interval == 0 {
testStackFunction(i)
}
}
}(t)
}
wg.Wait()
cost := time.Now().Sub(begin)
t.Logf("Cost: %vms", cost.Milliseconds())
}

func TestIOBondSingleP(t *testing.T) {
runtime.GOMAXPROCS(4)
const (
tasks = 8
interval = 1000000
round = 1000
)
begin := time.Now()
var wg sync.WaitGroup
for t := 0; t < tasks; t++ {
wg.Add(1)
go func(n int) {
defer wg.Done()
if n == 0 {
MPreemptOff()
defer MPreemptOn()
}
for i := 0; i < round*interval; i++ {
if i%interval == 0 {
testStackFunction(i)
}
if i%interval == interval/2 {
time.Sleep(time.Millisecond)
}
}
}(t)
}
wg.Wait()
cost := time.Now().Sub(begin)
t.Logf("Cost: %vms", cost.Milliseconds())
}
2 changes: 1 addition & 1 deletion lang/syncx/pool.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ import (
"sync/atomic"
"unsafe"

"github.com/bytedance/gopkg/internal/runtimex"
"github.com/bytedance/gopkg/lang/runtimex"
)

type Pool struct {
Expand Down
2 changes: 1 addition & 1 deletion lang/syncx/rwmutex.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import (
"sync"
"unsafe"

"github.com/bytedance/gopkg/internal/runtimex"
"github.com/bytedance/gopkg/lang/runtimex"

"golang.org/x/sys/cpu"
)
Expand Down
3 changes: 2 additions & 1 deletion util/xxhash3/accum_scalar.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,9 @@
package xxhash3

import (
"github.com/bytedance/gopkg/internal/runtimex"
"unsafe"

"github.com/bytedance/gopkg/lang/runtimex"
)

func accumScalar(xacc *[8]uint64, xinput, xsecret unsafe.Pointer, l uintptr) {
Expand Down
2 changes: 1 addition & 1 deletion util/xxhash3/hash.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import (
"unsafe"

"github.com/bytedance/gopkg/internal/hack"
"github.com/bytedance/gopkg/internal/runtimex"
"github.com/bytedance/gopkg/lang/runtimex"
)

// Hash returns the hash value of the byte slice in 64bits.
Expand Down
2 changes: 1 addition & 1 deletion util/xxhash3/hash128.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import (
"unsafe"

"github.com/bytedance/gopkg/internal/hack"
"github.com/bytedance/gopkg/internal/runtimex"
"github.com/bytedance/gopkg/lang/runtimex"
)

// Hash128 returns the hash value of the byte slice in 128bits.
Expand Down
2 changes: 1 addition & 1 deletion util/xxhash3/internal/xxh3_raw/xxh3_raw.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import (
"math/bits"
"unsafe"

"github.com/bytedance/gopkg/internal/runtimex"
"github.com/bytedance/gopkg/lang/runtimex"
)

const (
Expand Down

0 comments on commit 92184d0

Please sign in to comment.