@@ -322,6 +322,165 @@ func TestReadAfterClose(t *testing.T) {
322322 }
323323}
324324
325+ func TestReadZeroCopySingle (t * testing.T ) {
326+ testutils .SkipOnOldKernel (t , "5.8" , "BPF ring buffer" )
327+
328+ prog , events := mustOutputSamplesProg (t , sampleMessage {size : 5 })
329+
330+ rd , err := NewReader (events )
331+ qt .Assert (t , qt .IsNil (err ))
332+ defer rd .Close ()
333+
334+ mustRun (t , prog )
335+
336+ var rec Record
337+ err = rd .ReadUnsafe (& rec )
338+ qt .Assert (t , qt .IsNil (err ))
339+ qt .Assert (t , qt .Equals (len (rec .RawSample ), 5 ))
340+ qt .Assert (t , qt .DeepEquals (rec .RawSample , []byte {1 , 2 , 3 , 4 , 4 }))
341+
342+ rd .Commit ()
343+ qt .Assert (t , qt .Equals (rd .AvailableBytes (), 0 ))
344+ }
345+
346+ func TestReadZeroCopyMulti (t * testing.T ) {
347+ testutils .SkipOnOldKernel (t , "5.8" , "BPF ring buffer" )
348+
349+ prog , events := mustOutputSamplesProg (t ,
350+ sampleMessage {size : 5 },
351+ sampleMessage {size : 10 , discard : true },
352+ sampleMessage {size : 15 },
353+ )
354+
355+ rd , err := NewReader (events )
356+ qt .Assert (t , qt .IsNil (err ))
357+ defer rd .Close ()
358+
359+ mustRun (t , prog )
360+
361+ var rec Record
362+
363+ err = rd .ReadUnsafe (& rec )
364+ qt .Assert (t , qt .IsNil (err ))
365+ qt .Assert (t , qt .Equals (len (rec .RawSample ), 5 ))
366+
367+ err = rd .ReadUnsafe (& rec )
368+ qt .Assert (t , qt .IsNil (err ))
369+ qt .Assert (t , qt .Equals (len (rec .RawSample ), 15 ))
370+
371+ rd .Commit ()
372+ qt .Assert (t , qt .Equals (rd .AvailableBytes (), 0 ))
373+ }
374+
375+ func TestReadZeroCopyCommitReleasesSpace (t * testing.T ) {
376+ testutils .SkipOnOldKernel (t , "5.8" , "BPF ring buffer" )
377+
378+ prog , events := mustOutputSamplesProg (t , sampleMessage {size : 5 })
379+
380+ rd , err := NewReader (events )
381+ qt .Assert (t , qt .IsNil (err ))
382+ defer rd .Close ()
383+
384+ mustRun (t , prog )
385+
386+ var rec Record
387+ err = rd .ReadUnsafe (& rec )
388+ qt .Assert (t , qt .IsNil (err ))
389+
390+ qt .Assert (t , qt .Not (qt .Equals (rd .AvailableBytes (), 0 )))
391+
392+ rd .Commit ()
393+ qt .Assert (t , qt .Equals (rd .AvailableBytes (), 0 ))
394+
395+ mustRun (t , prog )
396+ err = rd .ReadUnsafe (& rec )
397+ qt .Assert (t , qt .IsNil (err ))
398+ qt .Assert (t , qt .Equals (len (rec .RawSample ), 5 ))
399+ rd .Commit ()
400+ }
401+
402+ func TestReadZeroCopyDeadline (t * testing.T ) {
403+ testutils .SkipOnOldKernel (t , "5.8" , "BPF ring buffer" )
404+
405+ _ , events := mustOutputSamplesProg (t , sampleMessage {size : 5 })
406+
407+ rd , err := NewReader (events )
408+ qt .Assert (t , qt .IsNil (err ))
409+ defer rd .Close ()
410+
411+ rd .SetDeadline (time .Now ().Add (- time .Second ))
412+
413+ var rec Record
414+ err = rd .ReadUnsafe (& rec )
415+ qt .Assert (t , qt .ErrorIs (err , os .ErrDeadlineExceeded ))
416+ }
417+
418+ func TestReadIntoRejectsUncommittedZeroCopy (t * testing.T ) {
419+ testutils .SkipOnOldKernel (t , "5.8" , "BPF ring buffer" )
420+
421+ prog , events := mustOutputSamplesProg (t , sampleMessage {size : 5 })
422+
423+ rd , err := NewReader (events )
424+ qt .Assert (t , qt .IsNil (err ))
425+ defer rd .Close ()
426+
427+ mustRun (t , prog )
428+
429+ var rec Record
430+ err = rd .ReadUnsafe (& rec )
431+ qt .Assert (t , qt .IsNil (err ))
432+
433+ err = rd .ReadInto (& rec )
434+ qt .Assert (t , qt .ErrorIs (err , ErrNotCommitted ))
435+
436+ _ , err = rd .Read ()
437+ qt .Assert (t , qt .ErrorIs (err , ErrNotCommitted ))
438+
439+ rd .Commit ()
440+
441+ mustRun (t , prog )
442+ err = rd .ReadInto (& rec )
443+ qt .Assert (t , qt .IsNil (err ))
444+ }
445+
446+ func TestCommitNoOp (t * testing.T ) {
447+ testutils .SkipOnOldKernel (t , "5.8" , "BPF ring buffer" )
448+
449+ _ , events := mustOutputSamplesProg (t , sampleMessage {size : 5 })
450+
451+ rd , err := NewReader (events )
452+ qt .Assert (t , qt .IsNil (err ))
453+ defer rd .Close ()
454+
455+ rd .Commit ()
456+ }
457+
458+ func BenchmarkReadZeroCopy (b * testing.B ) {
459+ testutils .SkipOnOldKernel (b , "5.8" , "BPF ring buffer" )
460+
461+ prog , events := mustOutputSamplesProg (b , sampleMessage {size : 80 , flags : 0 })
462+
463+ rd , err := NewReader (events )
464+ if err != nil {
465+ b .Fatal (err )
466+ }
467+ defer rd .Close ()
468+
469+ b .ReportAllocs ()
470+
471+ var rec Record
472+ for b .Loop () {
473+ b .StopTimer ()
474+ mustRun (b , prog )
475+ b .StartTimer ()
476+
477+ if err := rd .ReadUnsafe (& rec ); err != nil {
478+ b .Fatal ("Can't read samples:" , err )
479+ }
480+ rd .Commit ()
481+ }
482+ }
483+
325484func BenchmarkReader (b * testing.B ) {
326485 testutils .SkipOnOldKernel (b , "5.8" , "BPF ring buffer" )
327486
0 commit comments