in pkg/profiling/task/offcpu/runner.go [170:225]
func (r *Runner) FlushData() ([]*v3.EBPFProfilingData, error) {
if r.bpf == nil {
return nil, nil
}
var stack ProcessStack
var counter StackCounter
iterate := r.bpf.Counts.Iterate()
stacks := r.bpf.Stacks
result := make([]*v3.EBPFProfilingData, 0)
stackSymbols := make([]uint64, 100)
for iterate.Next(&stack, &counter) {
metadatas := make([]*v3.EBPFProfilingStackMetadata, 0)
// kernel stack
if d := r.base.GenerateProfilingData(r.kernelProfiling, stack.KernelStackID, stacks,
v3.EBPFProfilingStackType_PROCESS_KERNEL_SPACE, stackSymbols); d != nil {
metadatas = append(metadatas, d)
}
// user stack
if d := r.base.GenerateProfilingData(r.processProfiling, stack.UserStackID, stacks,
v3.EBPFProfilingStackType_PROCESS_USER_SPACE, stackSymbols); d != nil {
metadatas = append(metadatas, d)
}
if len(metadatas) == 0 {
continue
}
// update the counters in memory
switchCount := int32(counter.Times)
duration := int64(counter.Deltas)
existCounter := r.previousStacks[stack]
if existCounter.Times > 0 && existCounter.Deltas > 0 {
switchCount -= int32(existCounter.Times)
duration -= int64(existCounter.Deltas)
}
r.previousStacks[stack] = counter
if switchCount <= 0 {
continue
}
result = append(result, &v3.EBPFProfilingData{
Profiling: &v3.EBPFProfilingData_OffCPU{
OffCPU: &v3.EBPFOffCPUProfiling{
Stacks: metadatas,
SwitchCount: switchCount,
Duration: duration,
},
},
})
}
if r.flushDataNotify != nil {
r.flushDataNotify()
}
return result, nil
}