register.go raw

   1  // +build !bytedance_tango
   2  
   3  /**
   4   * Copyright 2024 ByteDance Inc.
   5   *
   6   * Licensed under the Apache License, Version 2.0 (the "License");
   7   * you may not use this file except in compliance with the License.
   8   * You may obtain a copy of the License at
   9   *
  10   *     https://www.apache.org/licenses/LICENSE-2.0
  11   *
  12   * Unless required by applicable law or agreed to in writing, software
  13   * distributed under the License is distributed on an "AS IS" BASIS,
  14   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  15   * See the License for the specific language governing permissions and
  16   * limitations under the License.
  17   */
  18  
  19  package loader
  20  
  21  import (
  22  	"sync/atomic"
  23  	"unsafe"
  24  )
  25  
  26  func registerModule(mod *moduledata) {
  27      registerModuleLockFree(&lastmoduledatap, mod)
  28  }
  29  
  30  func registerModuleLockFree(tail **moduledata, mod *moduledata) {
  31      for {
  32          oldTail := loadModule(tail)
  33          if casModule(tail, oldTail, mod) {
  34              storeModule(&oldTail.next, mod)
  35              break
  36          }
  37      }
  38  }
  39  
  40  func loadModule(p **moduledata) *moduledata {
  41      return (*moduledata)(atomic.LoadPointer((*unsafe.Pointer)(unsafe.Pointer(p))))
  42  }
  43  
  44  func storeModule(p **moduledata, value *moduledata) {
  45      atomic.StorePointer((*unsafe.Pointer)(unsafe.Pointer(p)), unsafe.Pointer(value))
  46  }
  47  
  48  func casModule(p **moduledata, oldValue *moduledata, newValue *moduledata) bool {
  49      return atomic.CompareAndSwapPointer(
  50          (*unsafe.Pointer)(unsafe.Pointer(p)),
  51          unsafe.Pointer(oldValue),
  52          unsafe.Pointer(newValue),
  53      )
  54  }
  55  
  56