@@ -48,6 +48,10 @@ type Record struct {
4848 // The number of samples which could not be output, since
4949 // the ring buffer was full.
5050 LostSamples uint64
51+
52+ // The minimum number of bytes remaining in the per-CPU buffer after this Record has been read.
53+ // Negative for overwritable buffers.
54+ Remaining int
5155}
5256
5357// Read a record from a reader and tag it as being from the given CPU.
@@ -158,6 +162,8 @@ type Reader struct {
158162
159163 paused bool
160164 overwritable bool
165+
166+ bufferSize int
161167}
162168
163169// ReaderOptions control the behaviour of the user
@@ -216,6 +222,7 @@ func NewReaderWithOptions(array *ebpf.Map, perCPUBuffer int, opts ReaderOptions)
216222 // bpf_perf_event_output checks which CPU an event is enabled on,
217223 // but doesn't allow using a wildcard like -1 to specify "all CPUs".
218224 // Hence we have to create a ring for each CPU.
225+ bufferSize := 0
219226 for i := 0 ; i < nCPU ; i ++ {
220227 ring , err := newPerfEventRing (i , perCPUBuffer , opts .Watermark , opts .Overwritable )
221228 if errors .Is (err , unix .ENODEV ) {
@@ -224,6 +231,7 @@ func NewReaderWithOptions(array *ebpf.Map, perCPUBuffer int, opts ReaderOptions)
224231 pauseFds = append (pauseFds , - 1 )
225232 continue
226233 }
234+ bufferSize = ring .size ()
227235
228236 if err != nil {
229237 return nil , fmt .Errorf ("failed to create perf ring for CPU %d: %v" , i , err )
@@ -251,6 +259,7 @@ func NewReaderWithOptions(array *ebpf.Map, perCPUBuffer int, opts ReaderOptions)
251259 eventHeader : make ([]byte , perfEventHeaderSize ),
252260 pauseFds : pauseFds ,
253261 overwritable : opts .Overwritable ,
262+ bufferSize : bufferSize ,
254263 }
255264 if err = pr .Resume (); err != nil {
256265 return nil , err
@@ -430,6 +439,11 @@ func (pr *Reader) Resume() error {
430439 return nil
431440}
432441
442+ // BufferSize is the size in bytes of each per-CPU buffer
443+ func (pr * Reader ) BufferSize () int {
444+ return pr .bufferSize
445+ }
446+
433447// NB: Has to be preceded by a call to ring.loadHead.
434448func (pr * Reader ) readRecordFromRing (rec * Record , ring * perfEventRing ) error {
435449 defer ring .writeTail ()
@@ -439,6 +453,7 @@ func (pr *Reader) readRecordFromRing(rec *Record, ring *perfEventRing) error {
439453 if pr .overwritable && (errors .Is (err , io .EOF ) || errors .Is (err , io .ErrUnexpectedEOF )) {
440454 return errEOR
441455 }
456+ rec .Remaining = ring .remaining ()
442457 return err
443458}
444459
0 commit comments