Skip to content

Commit

Permalink
opt: use unsafe.Add to avoid race panic
Browse files Browse the repository at this point in the history
  • Loading branch information
AsterDY committed Jan 10, 2025
1 parent bfce75f commit a764000
Show file tree
Hide file tree
Showing 11 changed files with 279 additions and 9 deletions.
13 changes: 10 additions & 3 deletions go.mod
Original file line number Diff line number Diff line change
@@ -1,10 +1,17 @@
module github.com/cloudwego/localsession

go 1.16
go 1.17

require (
github.com/bytedance/gopkg v0.0.0-20230728082804-614d0af6619b
github.com/modern-go/gls v0.0.0-20220109145502-612d0167dce5
github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/modern-go/reflect2 v1.0.2
github.com/stretchr/testify v1.7.0
)

require (
github.com/davecgh/go-spew v1.1.0 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
golang.org/x/net v0.0.0-20221014081412-f15817d10f9b // indirect
golang.org/x/text v0.3.7 // indirect
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c // indirect
)
2 changes: 0 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@ github.com/bytedance/gopkg v0.0.0-20230728082804-614d0af6619b h1:R6PWoQtxEMpWJPH
github.com/bytedance/gopkg v0.0.0-20230728082804-614d0af6619b/go.mod h1:FtQG3YbQG9L/91pbKSw787yBQPutC+457AvDW77fgUQ=
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/gls v0.0.0-20220109145502-612d0167dce5 h1:uiS4zKYKJVj5F3ID+5iylfKPsEQmBEOucSD9Vgmn0i0=
github.com/modern-go/gls v0.0.0-20220109145502-612d0167dce5/go.mod h1:I8AX+yW//L8Hshx6+a1m3bYkwXkpsVjA2795vP4f4oQ=
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=
Expand Down
45 changes: 45 additions & 0 deletions internal/goid/goid.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
// Copyright 2023 CloudWeGo Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// Copyright 2016 Huan Du. All rights reserved.
// Use of this source code is governed by a MIT
// license that can be found in the LICENSE file.

package goid

import (
"unsafe"

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

// offset for go1.4
var goidOffset uintptr = 128

func init() {
gType := reflect2.TypeByName("runtime.g").(reflect2.StructType)
if gType == nil {
panic("failed to get runtime.g type")
}
goidField := gType.FieldByName("goid")
goidOffset = goidField.Offset()
}

// GoID returns the goroutine id of current goroutine
func GoID() int64 {
p_goid := (*int64)(unsafe.Add(unsafe.Pointer(getg()), goidOffset))
return *p_goid
}

func getg() uintptr
27 changes: 27 additions & 0 deletions internal/goid/goid_386.s
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// Copyright 2023 CloudWeGo Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// Copyright 2016 Huan Du. All rights reserved.
// Use of this source code is governed by a MIT
// license that can be found in the LICENSE file.

#include "go_asm.h"
#include "go_tls.h"
#include "textflag.h"

TEXT ·getg(SB), NOSPLIT, $0-4
get_tls(CX)
MOVL g(CX), AX
MOVL AX, ret+0(FP)
RET
27 changes: 27 additions & 0 deletions internal/goid/goid_amd64.s
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// Copyright 2023 CloudWeGo Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// Copyright 2016 Huan Du. All rights reserved.
// Use of this source code is governed by a MIT
// license that can be found in the LICENSE file.

#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

19 changes: 19 additions & 0 deletions internal/goid/goid_amd64p32.s
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
// Copyright 2023 CloudWeGo Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// Copyright 2016 Huan Du. All rights reserved.
// Use of this source code is governed by a MIT
// license that can be found in the LICENSE file.

#include "goid_amd64.s"
26 changes: 26 additions & 0 deletions internal/goid/goid_arm.s
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
// Copyright 2023 CloudWeGo Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// Copyright 2016 Huan Du. All rights reserved.
// Use of this source code is governed by a MIT
// license that can be found in the LICENSE file.

#include "go_asm.h"
#include "textflag.h"

TEXT ·getg(SB), NOSPLIT, $0-4
MOVW g, R8
MOVW R8, ret+0(FP)
RET

26 changes: 26 additions & 0 deletions internal/goid/goid_arm64.s
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
//// Copyright 2023 CloudWeGo Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// Copyright 2016 Huan Du. All rights reserved.
// Use of this source code is governed by a MIT
// license that can be found in the LICENSE file.

#include "go_asm.h"
#include "textflag.h"

TEXT ·getg(SB), NOSPLIT, $0-8
MOVD g, R8
MOVD R8, ret+0(FP)
RET

25 changes: 25 additions & 0 deletions internal/goid/goid_riscv64.s
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
//// Copyright 2023 CloudWeGo Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// Copyright 2016 Huan Du. All rights reserved.
// Use of this source code is governed by a MIT
// license that can be found in the LICENSE file.

#include "go_asm.h"
#include "textflag.h"

TEXT ·getg(SB), NOSPLIT, $0-8
MOV g, A0
MOV A0, ret+0(FP)
RET
70 changes: 70 additions & 0 deletions internal/goid/goid_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
// Copyright 2023 CloudWeGo Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// Copyright 2016 Huan Du. All rights reserved.
// Use of this source code is governed by a MIT
// license that can be found in the LICENSE file.

package goid

import (
"fmt"
"runtime"
"strings"
"sync"
"testing"
_ "unsafe"
)

func TestGoID(t *testing.T) {
var wg sync.WaitGroup
for i := 0; i < 5; i++ {
wg.Add(1)
go func() {
testGoID(t)
wg.Done()
}()
}
wg.Wait()
}

func testGoID(t *testing.T) {
id := GoID()
lines := strings.Split(stackTrace(), "\n")
for i, line := range lines {
if !strings.HasPrefix(line, fmt.Sprintf("goroutine %d ", id)) {
continue
}
if i+1 == len(lines) {
break
}
if !strings.Contains(lines[i+1], ".stackTrace") {
t.Errorf("there are goroutine id %d but it is not me: %s", id, lines[i+1])
}
return
}
t.Errorf("there are no goroutine %d", id)
}

func stackTrace() string {
var n int
for n = 4096; n < 16777216; n *= 2 {
buf := make([]byte, n)
ret := runtime.Stack(buf, true)
if ret != n {
return string(buf[:ret])
}
}
panic(n)
}
8 changes: 4 additions & 4 deletions stubs.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,12 @@ import (
"strconv"
_ "unsafe"

"github.com/modern-go/gls"
"github.com/cloudwego/localsession/internal/goid"
)

//go:nocheckptr
func goID() uint64 {
return uint64(gls.GoID())
return uint64(goid.GoID())
}

type labelMap map[string]string
Expand All @@ -49,7 +49,7 @@ func transmitSessionID(id SessionID) {
}
}
}

n[Pprof_Label_Session_ID] = strconv.FormatInt(int64(id), 10)
setPprofLabel(&n)
}
Expand All @@ -73,7 +73,7 @@ func getSessionID() (SessionID, bool) {
func clearSessionID() {
m := getPproLabel()
if m == nil {
return
return
}
if _, ok := (*m)[Pprof_Label_Session_ID]; !ok {
return
Expand Down

0 comments on commit a764000

Please sign in to comment.