diff --git a/go.work.sum b/go.work.sum index d59625879..8ee8d8cc5 100644 --- a/go.work.sum +++ b/go.work.sum @@ -1 +1,2 @@ -github.com/bytedance/sonic/loader v0.2.0/go.mod h1:ncP89zfokxS5LZrJxl5z0UJcsk4M4yY2JpfqGeCtNLU= +golang.org/x/sync v0.0.0-20210220032951-036812b2e83c h1:5KslGYwFpkhGh+Q16bwMP3cOontH8FOep7tGV86Y7SQ= +golang.org/x/sys v0.0.0-20221010170243-090e33056c14 h1:k5II8e6QD8mITdi+okbbmR/cIyEbeXLBhy5Ha4nevyc= diff --git a/loader/register.go b/loader/register.go new file mode 100644 index 000000000..d32f9fa50 --- /dev/null +++ b/loader/register.go @@ -0,0 +1,55 @@ +// +build !bytedance_tango + +/** + * Copyright 2024 ByteDance Inc. + * + * 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 + * + * https://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. + */ + +package loader + +import ( + "sync/atomic" + "unsafe" +) + +func registerModule(mod *moduledata) { + registerModuleLockFree(&lastmoduledatap, mod) +} + +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), + ) +} + diff --git a/loader/register_tango.go b/loader/register_tango.go new file mode 100644 index 000000000..1c1c14fce --- /dev/null +++ b/loader/register_tango.go @@ -0,0 +1,33 @@ +// +build bytedance_tango + +/** + * Copyright 2024 ByteDance Inc. + * + * 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 + * + * https://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. + */ + +package loader + +import ( + "sync" + _ "unsafe" +) + +//go:linkname pluginsMu plugin.pluginsMu +var pluginsMu sync.Mutex + +func registerModule(mod *moduledata) { + pluginsMu.Lock() + defer pluginsMu.Unlock() + lastmoduledatap = mod +} diff --git a/loader/stubs_test.go b/loader/register_test.go similarity index 97% rename from loader/stubs_test.go rename to loader/register_test.go index 45bc6e35b..eb9b964a9 100644 --- a/loader/stubs_test.go +++ b/loader/register_test.go @@ -1,3 +1,5 @@ +// +build !bytedance_tango + /* * Copyright 2023 ByteDance Inc. * diff --git a/loader/stubs.go b/loader/stubs.go index 80f8de836..28aebd60b 100644 --- a/loader/stubs.go +++ b/loader/stubs.go @@ -17,8 +17,6 @@ package loader import ( - "sync/atomic" - "unsafe" _ `unsafe` ) @@ -26,35 +24,5 @@ import ( //goland:noinspection GoUnusedGlobalVariable var lastmoduledatap *moduledata -func registerModule(mod *moduledata) { - 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), - ) -}