in tools/go-agent/instrument/runtime/instrument.go [117:314]
func (r *Instrument) WriteExtraFiles(dir string) ([]string, error) {
return tools.WriteMultipleFile(dir, map[string]string{
"skywalking_tls_operator.go": tools.ExecuteTemplate(`package runtime
import (
_ "unsafe"
atomic "{{.InternalAtomicPath}}"
)
var {{.GlobalTracerFieldName}} interface{}
var {{.GlobalLoggerFieldName}} interface{}
var {{.GlobalTracerInitNotifyFieldName}} = make([]func(), 0)
var _metricsRegisterLockerVal int32 = 0
var _metricsRegisterLocker = &_metricsRegisterLockerVal
var {{.MetricsRegisterFieldName}} = make([]interface{}, 0)
var {{.MetricsHookFieldName}} = make([]func(), 0)
//go:linkname {{.TLSGetMethod}} {{.TLSGetMethod}}
var {{.TLSGetMethod}} = _skywalking_tls_get_impl
//go:linkname {{.TLSSetMethod}} {{.TLSSetMethod}}
var {{.TLSSetMethod}} = _skywalking_tls_set_impl
//go:linkname {{.GlobalOperatorSetMethodName}} {{.GlobalOperatorSetMethodName}}
var {{.GlobalOperatorSetMethodName}} = _skywalking_global_operator_set_impl
//go:linkname {{.GlobalOperatorGetMethodName}} {{.GlobalOperatorGetMethodName}}
var {{.GlobalOperatorGetMethodName}} = _skywalking_global_operator_get_impl
//go:linkname {{.GlobalLoggerSetMethodName}} {{.GlobalLoggerSetMethodName}}
var {{.GlobalLoggerSetMethodName}} = _skywalking_global_logger_set_impl
//go:linkname {{.GlobalLoggerGetMethodName}} {{.GlobalLoggerGetMethodName}}
var {{.GlobalLoggerGetMethodName}} = _skywalking_global_logger_get_impl
//go:linkname {{.GoroutineIDGetterMethodName}} {{.GoroutineIDGetterMethodName}}
var {{.GoroutineIDGetterMethodName}} = _skywalking_get_goid_impl
//go:linkname {{.GlobalTracerInitNotifyMethodName}} {{.GlobalTracerInitNotifyMethodName}}
var {{.GlobalTracerInitNotifyMethodName}} = _skywalking_global_tracer_init_notify_impl
//go:linkname {{.GlobalTracerInitNotifyGetMethodName}} {{.GlobalTracerInitNotifyGetMethodName}}
var {{.GlobalTracerInitNotifyGetMethodName}} = _skywalking_global_tracer_init_get_notify_impl
//go:linkname {{.MetricsRegisterAppendMethodName}} {{.MetricsRegisterAppendMethodName}}
var {{.MetricsRegisterAppendMethodName}} = _skywalking_metrics_register_append_impl
//go:linkname {{.MetricsObtainMethodName}} {{.MetricsObtainMethodName}}
var {{.MetricsObtainMethodName}} = _skywalking_metrics_obtain_impl
//go:nosplit
func _skywalking_get_goid_impl() int64 {
return {{.GoroutineIDCaster}}
}
//go:nosplit
func _skywalking_tls_get_impl() interface{} {
return getg().m.curg.{{.TLSFiledName}}
}
//go:nosplit
func _skywalking_tls_set_impl(v interface{}) {
getg().m.curg.{{.TLSFiledName}} = v
}
//go:nosplit
func _skywalking_global_operator_set_impl(v interface{}) {
{{.GlobalTracerFieldName}} = v
}
//go:nosplit
func _skywalking_global_operator_get_impl() interface{} {
return {{.GlobalTracerFieldName}}
}
//go:nosplit
func _skywalking_global_logger_set_impl(v interface{}) {
{{.GlobalLoggerFieldName}} = v
}
//go:nosplit
func _skywalking_global_logger_get_impl() interface{} {
return {{.GlobalLoggerFieldName}}
}
//go:nosplit
func _skywalking_global_tracer_init_notify_impl(fun func()) {
{{.GlobalTracerInitNotifyFieldName}} = append({{.GlobalTracerInitNotifyFieldName}}, fun)
}
//go:nosplit
func _skywalking_global_tracer_init_get_notify_impl() []func() {
return {{.GlobalTracerInitNotifyFieldName}}
}
//go:nosplit
func _skywalking_metrics_register_append_impl(v interface{}) {
for {
tmp := atomic.Loadint32(_metricsRegisterLocker)
if atomic.Casint32(_metricsRegisterLocker, tmp, tmp+1) {
{{.MetricsRegisterFieldName}} = append({{.MetricsRegisterFieldName}}, v)
break
}
}
}
//go:nosplit
func _skywalking_metrics_obtain_impl() ([]interface{}, []func()) {
for {
tmp := atomic.Loadint32(_metricsRegisterLocker)
if tmp == 0 {
return nil, nil
}
if atomic.Casint32(_metricsRegisterLocker, tmp, 0) {
registers := {{.MetricsRegisterFieldName}}
{{.MetricsRegisterFieldName}} = make([]interface{}, 0)
hooks := {{.MetricsHookFieldName}}
{{.MetricsHookFieldName}} = make([]func(), 0)
return registers, hooks
}
}
}
//go:nosplit
func _skywalking_metrics_hook_append_impl(f func()) {
for {
tmp := atomic.Loadint32(_metricsRegisterLocker)
if atomic.Casint32(_metricsRegisterLocker, tmp, tmp+1) {
{{.MetricsHookFieldName}} = append({{.MetricsHookFieldName}}, f)
break
}
}
}
type ContextSnapshoter interface {
TakeSnapShot(val interface{}) interface{}
}
func goroutineChange(tls interface{}) interface{} {
if tls == nil {
return nil
}
if taker, ok := tls.(ContextSnapshoter); ok {
return taker.TakeSnapShot(tls)
}
return tls
}
`, struct {
TLSFiledName string
TLSGetMethod string
TLSSetMethod string
GlobalTracerFieldName string
GlobalTracerSnapshotInterface string
GlobalOperatorSetMethodName string
GlobalOperatorGetMethodName string
GlobalLoggerFieldName string
GlobalLoggerSetMethodName string
GlobalLoggerGetMethodName string
GoroutineIDGetterMethodName string
GoroutineIDCaster string
GlobalTracerInitNotifyFieldName string
GlobalTracerInitNotifyMethodName string
GlobalTracerInitNotifyGetMethodName string
MetricsRegisterFieldName string
MetricsRegisterAppendMethodName string
MetricsObtainMethodName string
MetricsHookFieldName string
MetricsHookAppendMethodName string
InternalAtomicPath string
}{
TLSFiledName: consts.TLSFieldName,
TLSGetMethod: consts.TLSGetMethodName,
TLSSetMethod: consts.TLSSetMethodName,
GlobalTracerFieldName: consts.GlobalTracerFieldName,
GlobalTracerSnapshotInterface: consts.GlobalTracerSnapshotInterface,
GlobalOperatorSetMethodName: consts.GlobalTracerSetMethodName,
GlobalOperatorGetMethodName: consts.GlobalTracerGetMethodName,
GlobalLoggerFieldName: consts.GlobalLoggerFieldName,
GlobalLoggerSetMethodName: consts.GlobalLoggerSetMethodName,
GlobalLoggerGetMethodName: consts.GlobalLoggerGetMethodName,
GoroutineIDGetterMethodName: consts.CurrentGoroutineIDGetMethodName,
GoroutineIDCaster: r.generateCastGoID("getg().m.curg.goid"),
GlobalTracerInitNotifyFieldName: consts.GlobalTracerInitNotifyFieldName,
GlobalTracerInitNotifyMethodName: consts.GlobalTracerInitAppendNotifyMethodName,
GlobalTracerInitNotifyGetMethodName: consts.GlobalTracerInitGetNotifyMethodName,
MetricsRegisterFieldName: consts.MetricsRegisterFieldName,
MetricsRegisterAppendMethodName: consts.MetricsRegisterAppendMethodName,
MetricsObtainMethodName: consts.MetricsObtainMethodName,
MetricsHookFieldName: consts.MetricsHookFieldName,
MetricsHookAppendMethodName: consts.MetricsHookAppendMethodName,
InternalAtomicPath: r.parseInternalAtomicPath(),
}),
})
}