func()

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(),
		}),
	})
}