summaryrefslogtreecommitdiff
path: root/vendor/github.com/bytedance/sonic/loader/stubs.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/bytedance/sonic/loader/stubs.go')
-rw-r--r--vendor/github.com/bytedance/sonic/loader/stubs.go34
1 files changed, 27 insertions, 7 deletions
diff --git a/vendor/github.com/bytedance/sonic/loader/stubs.go b/vendor/github.com/bytedance/sonic/loader/stubs.go
index 8377649b7..80f8de836 100644
--- a/vendor/github.com/bytedance/sonic/loader/stubs.go
+++ b/vendor/github.com/bytedance/sonic/loader/stubs.go
@@ -17,7 +17,8 @@
package loader
import (
- `sync`
+ "sync/atomic"
+ "unsafe"
_ `unsafe`
)
@@ -25,16 +26,35 @@ import (
//goland:noinspection GoUnusedGlobalVariable
var lastmoduledatap *moduledata
-var moduledataMux sync.Mutex
-
func registerModule(mod *moduledata) {
- moduledataMux.Lock()
- lastmoduledatap.next = mod
- lastmoduledatap = mod
- moduledataMux.Unlock()
+ registerModuleLockFree(&lastmoduledatap, mod)
}
//go:linkname moduledataverify1 runtime.moduledataverify1
func moduledataverify1(_ *moduledata)
+func registerModuleLockFree(tail **moduledata, mod *moduledata) {
+ for {
+ oldTail := loadModule(tail)
+ if casModule(tail, oldTail, mod) {
+ storeModule(&oldTail.next, mod)
+ break
+ }
+ }
+}
+
+func loadModule(p **moduledata) *moduledata {
+ return (*moduledata)(atomic.LoadPointer((*unsafe.Pointer)(unsafe.Pointer(p))))
+}
+func storeModule(p **moduledata, value *moduledata) {
+ atomic.StorePointer((*unsafe.Pointer)(unsafe.Pointer(p)), unsafe.Pointer(value))
+}
+
+func casModule(p **moduledata, oldValue *moduledata, newValue *moduledata) bool {
+ return atomic.CompareAndSwapPointer(
+ (*unsafe.Pointer)(unsafe.Pointer(p)),
+ unsafe.Pointer(oldValue),
+ unsafe.Pointer(newValue),
+ )
+}