// Copyright 2025 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package trace

import (
	
	
	
	
	
	
	_ 
)

var tracing traceMultiplexer

type traceMultiplexer struct {
	sync.Mutex
	enabled     atomic.Bool
	subscribers int

	subscribersMu    sync.Mutex
	traceStartWriter io.Writer
	flightRecorder   *recorder
}

func ( *traceMultiplexer) ( *recorder) error {
	.Lock()
	defer .Unlock()

	.subscribersMu.Lock()
	if .flightRecorder != nil {
		.subscribersMu.Unlock()
		return fmt.Errorf("flight recorder already enabled")
	}
	.flightRecorder = 
	.subscribersMu.Unlock()

	if  := .addedSubscriber();  != nil {
		.subscribersMu.Lock()
		.flightRecorder = nil
		.subscribersMu.Unlock()
		return 
	}
	return nil
}

func ( *traceMultiplexer) () error {
	.Lock()
	defer .Unlock()

	.removingSubscriber()

	.subscribersMu.Lock()
	if .flightRecorder == nil {
		.subscribersMu.Unlock()
		return fmt.Errorf("attempt to unsubscribe missing flight recorder")
	}
	.flightRecorder = nil
	.subscribersMu.Unlock()

	.removedSubscriber()
	return nil
}

func ( *traceMultiplexer) ( io.Writer) error {
	.Lock()
	defer .Unlock()

	.subscribersMu.Lock()
	if .traceStartWriter != nil {
		.subscribersMu.Unlock()
		return fmt.Errorf("execution tracer already enabled")
	}
	.traceStartWriter = 
	.subscribersMu.Unlock()

	if  := .addedSubscriber();  != nil {
		.subscribersMu.Lock()
		.traceStartWriter = nil
		.subscribersMu.Unlock()
		return 
	}
	return nil
}

func ( *traceMultiplexer) () {
	.Lock()
	defer .Unlock()

	.removingSubscriber()

	.subscribersMu.Lock()
	if .traceStartWriter == nil {
		.subscribersMu.Unlock()
		return
	}
	.traceStartWriter = nil
	.subscribersMu.Unlock()

	.removedSubscriber()
	return
}

func ( *traceMultiplexer) () error {
	if .enabled.Load() {
		// This is necessary for the trace reader goroutine to pick up on the new subscriber.
		runtime_traceAdvance(false)
	} else {
		if  := .startLocked();  != nil {
			return 
		}
	}
	.subscribers++
	return nil
}

func ( *traceMultiplexer) () {
	if .subscribers == 0 {
		return
	}
	.subscribers--
	if .subscribers == 0 {
		runtime.StopTrace()
		.enabled.Store(false)
	} else {
		// This is necessary to avoid missing trace data when the system is under high load.
		runtime_traceAdvance(false)
	}
}

func ( *traceMultiplexer) () {
	if .subscribers > 0 {
		// This is necessary for the trace reader goroutine to pick up on the new subscriber.
		runtime_traceAdvance(false)
	}
}

func ( *traceMultiplexer) () error {
	if  := runtime.StartTrace();  != nil {
		return 
	}

	// Grab the trace reader goroutine's subscribers.
	//
	// We only update our subscribers if we see an end-of-generation
	// signal from the runtime after this, so any new subscriptions
	// or unsubscriptions must call traceAdvance to ensure the reader
	// goroutine sees an end-of-generation signal.
	.subscribersMu.Lock()
	 := .flightRecorder
	 := .traceStartWriter
	.subscribersMu.Unlock()

	go func() {
		 := runtime_readTrace()
		if  != nil {
			.Write()
		}
		if  != nil {
			.Write()
		}

		for {
			 := runtime_readTrace()
			if  == nil {
				break
			}
			if len() == 1 && tracev2.EventType([0]) == tracev2.EvEndOfGeneration {
				if  != nil {
					.endGeneration()
				}

				// Pick up any changes.
				.subscribersMu.Lock()
				 :=  != .flightRecorder && .flightRecorder != nil
				 :=  != .traceStartWriter && .traceStartWriter != nil
				 = .flightRecorder
				 = .traceStartWriter
				.subscribersMu.Unlock()

				if  {
					.Write()
				}
				if  {
					.Write()
				}
			} else {
				if  != nil {
					.Write()
				}
				if  != nil {
					.Write()
				}
			}
		}
	}()
	.enabled.Store(true)
	return nil
}

//go:linkname runtime_readTrace
func runtime_readTrace() ( []byte)