From 1adaf1e0b510805a53754c57c9d008d6112b3608 Mon Sep 17 00:00:00 2001 From: "bogdan.balan1" Date: Thu, 12 Jan 2023 14:47:47 +0200 Subject: [PATCH 1/2] Make start/stop safe for concurrent access --- perf_events.go | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/perf_events.go b/perf_events.go index f8967b4..e78a446 100644 --- a/perf_events.go +++ b/perf_events.go @@ -47,6 +47,9 @@ type PerfEvents struct { stopChannel chan struct{} wg sync.WaitGroup + started bool + startStopMtx sync.Mutex + handlers []*perfEventHandler } @@ -135,6 +138,13 @@ func (pe *PerfEvents) StartForAllProcessesAndCPUs(bufferSize int) (<-chan []byte // Stop stops event polling loop func (pe *PerfEvents) Stop() { + pe.startStopMtx.Lock() + defer pe.startStopMtx.Unlock() + + if !pe.started { + return + } + // Stop poller firstly pe.poller.Stop() // Stop poll loop @@ -150,14 +160,13 @@ func (pe *PerfEvents) Stop() { } func (pe *PerfEvents) startLoop() { + pe.startStopMtx.Lock() + defer pe.startStopMtx.Unlock() + pe.stopChannel = make(chan struct{}) pe.updatesChannel = make(chan []byte) pe.wg.Add(1) - go pe.loop() -} - -func (pe *PerfEvents) loop() { // Setup poller to poll all handlers (one handler per CPU) pe.poller = newPerfEventPoller() for _, handler := range pe.handlers { @@ -166,6 +175,11 @@ func (pe *PerfEvents) loop() { // Start poller pollerCh := pe.poller.Start(pe.PollTimeoutMs) + pe.started = true + go pe.loop(pollerCh) +} + +func (pe *PerfEvents) loop(pollerCh <-chan *perfEventHandler) { defer func() { pe.wg.Done() }() From ab020f6f917efaf5905203565b4ba3d5d5587a32 Mon Sep 17 00:00:00 2001 From: "bogdan.balan1" Date: Thu, 12 Jan 2023 20:51:43 +0200 Subject: [PATCH 2/2] Remove mutex --- perf_events.go | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/perf_events.go b/perf_events.go index e78a446..0cccce4 100644 --- a/perf_events.go +++ b/perf_events.go @@ -47,8 +47,7 @@ type PerfEvents struct { stopChannel chan struct{} wg sync.WaitGroup - started bool - startStopMtx sync.Mutex + started bool handlers []*perfEventHandler } @@ -138,9 +137,6 @@ func (pe *PerfEvents) StartForAllProcessesAndCPUs(bufferSize int) (<-chan []byte // Stop stops event polling loop func (pe *PerfEvents) Stop() { - pe.startStopMtx.Lock() - defer pe.startStopMtx.Unlock() - if !pe.started { return } @@ -160,9 +156,6 @@ func (pe *PerfEvents) Stop() { } func (pe *PerfEvents) startLoop() { - pe.startStopMtx.Lock() - defer pe.startStopMtx.Unlock() - pe.stopChannel = make(chan struct{}) pe.updatesChannel = make(chan []byte) pe.wg.Add(1)