diff options
| -rw-r--r-- | internal/eventloop.go | 24 | ||||
| -rw-r--r-- | internal/types/fastdecode.go | 147 | ||||
| -rw-r--r-- | internal/types/fastdecode_test.go | 127 |
3 files changed, 286 insertions, 12 deletions
diff --git a/internal/eventloop.go b/internal/eventloop.go index a917613..562a802 100644 --- a/internal/eventloop.go +++ b/internal/eventloop.go @@ -377,46 +377,46 @@ func (e *eventLoop) initRawHandlers() { } e.rawHandlers[ENTER_OPEN_EVENT] = func(raw []byte, _ chan<- *event.Pair) { - if ev, ok := e.filter.openEvent(NewOpenEvent(raw)); ok { + if ev, ok := e.filter.openEvent(NewOpenEventFast(raw)); ok { e.tracepointEntered(ev) } } e.rawHandlers[EXIT_OPEN_EVENT] = func(raw []byte, ch chan<- *event.Pair) { - e.tracepointExited(NewRetEvent(raw), ch) + e.tracepointExited(NewRetEventFast(raw), ch) } e.rawHandlers[ENTER_FD_EVENT] = func(raw []byte, _ chan<- *event.Pair) { - e.tracepointEntered(NewFdEvent(raw)) + e.tracepointEntered(NewFdEventFast(raw)) } e.rawHandlers[EXIT_FD_EVENT] = func(raw []byte, ch chan<- *event.Pair) { - e.tracepointExited(NewFdEvent(raw), ch) + e.tracepointExited(NewFdEventFast(raw), ch) } e.rawHandlers[ENTER_NULL_EVENT] = func(raw []byte, _ chan<- *event.Pair) { - e.tracepointEntered(NewNullEvent(raw)) + e.tracepointEntered(NewNullEventFast(raw)) } e.rawHandlers[EXIT_NULL_EVENT] = func(raw []byte, ch chan<- *event.Pair) { - e.tracepointExited(NewNullEvent(raw), ch) + e.tracepointExited(NewNullEventFast(raw), ch) } e.rawHandlers[EXIT_RET_EVENT] = func(raw []byte, ch chan<- *event.Pair) { - e.tracepointExited(NewRetEvent(raw), ch) + e.tracepointExited(NewRetEventFast(raw), ch) } e.rawHandlers[ENTER_NAME_EVENT] = func(raw []byte, _ chan<- *event.Pair) { - if ev, ok := e.filter.nameEvent(NewNameEvent(raw)); ok { + if ev, ok := e.filter.nameEvent(NewNameEventFast(raw)); ok { e.tracepointEntered(ev) } } e.rawHandlers[ENTER_PATH_EVENT] = func(raw []byte, _ chan<- *event.Pair) { - if ev, ok := e.filter.pathEvent(NewPathEvent(raw)); ok { + if ev, ok := e.filter.pathEvent(NewPathEventFast(raw)); ok { e.tracepointEntered(ev) } } e.rawHandlers[ENTER_FCNTL_EVENT] = func(raw []byte, _ chan<- *event.Pair) { - e.tracepointEntered(NewFcntlEvent(raw)) + e.tracepointEntered(NewFcntlEventFast(raw)) } e.rawHandlers[ENTER_OPEN_BY_HANDLE_AT_EVENT] = func(raw []byte, _ chan<- *event.Pair) { - e.tracepointEntered(NewOpenByHandleAtEvent(raw)) + e.tracepointEntered(NewOpenByHandleAtEventFast(raw)) } e.rawHandlers[ENTER_DUP3_EVENT] = func(raw []byte, _ chan<- *event.Pair) { - e.tracepointEntered(NewDup3Event(raw)) + e.tracepointEntered(NewDup3EventFast(raw)) } } diff --git a/internal/types/fastdecode.go b/internal/types/fastdecode.go new file mode 100644 index 0000000..92b57c6 --- /dev/null +++ b/internal/types/fastdecode.go @@ -0,0 +1,147 @@ +package types + +import "encoding/binary" + +const ( + openEventSize = 300 + nullEventSize = 24 + fdEventSize = 28 + retEventSize = 36 + nameEventSize = 536 + pathEventSize = 280 + fcntlEventSize = 40 + dup3EventSize = 32 + openByHandleAtEventSize = 28 +) + +func NewOpenEventFast(raw []byte) *OpenEvent { + if len(raw) != openEventSize { + return NewOpenEvent(raw) + } + o := poolOfOpenEvents.Get().(*OpenEvent) + o.EventType = EventType(binary.LittleEndian.Uint32(raw[0:4])) + o.TraceId = TraceId(binary.LittleEndian.Uint32(raw[4:8])) + o.Time = binary.LittleEndian.Uint64(raw[8:16]) + o.Pid = binary.LittleEndian.Uint32(raw[16:20]) + o.Tid = binary.LittleEndian.Uint32(raw[20:24]) + o.Flags = int32(binary.LittleEndian.Uint32(raw[24:28])) + copy(o.Filename[:], raw[28:284]) + copy(o.Comm[:], raw[284:300]) + return o +} + +func NewNullEventFast(raw []byte) *NullEvent { + if len(raw) != nullEventSize { + return NewNullEvent(raw) + } + n := poolOfNullEvents.Get().(*NullEvent) + n.EventType = EventType(binary.LittleEndian.Uint32(raw[0:4])) + n.TraceId = TraceId(binary.LittleEndian.Uint32(raw[4:8])) + n.Time = binary.LittleEndian.Uint64(raw[8:16]) + n.Pid = binary.LittleEndian.Uint32(raw[16:20]) + n.Tid = binary.LittleEndian.Uint32(raw[20:24]) + return n +} + +func NewFdEventFast(raw []byte) *FdEvent { + if len(raw) != fdEventSize { + return NewFdEvent(raw) + } + f := poolOfFdEvents.Get().(*FdEvent) + f.EventType = EventType(binary.LittleEndian.Uint32(raw[0:4])) + f.TraceId = TraceId(binary.LittleEndian.Uint32(raw[4:8])) + f.Time = binary.LittleEndian.Uint64(raw[8:16]) + f.Pid = binary.LittleEndian.Uint32(raw[16:20]) + f.Tid = binary.LittleEndian.Uint32(raw[20:24]) + f.Fd = int32(binary.LittleEndian.Uint32(raw[24:28])) + return f +} + +func NewRetEventFast(raw []byte) *RetEvent { + if len(raw) != retEventSize { + return NewRetEvent(raw) + } + r := poolOfRetEvents.Get().(*RetEvent) + r.EventType = EventType(binary.LittleEndian.Uint32(raw[0:4])) + r.TraceId = TraceId(binary.LittleEndian.Uint32(raw[4:8])) + r.Time = binary.LittleEndian.Uint64(raw[8:16]) + r.Ret = int64(binary.LittleEndian.Uint64(raw[16:24])) + r.Pid = binary.LittleEndian.Uint32(raw[24:28]) + r.Tid = binary.LittleEndian.Uint32(raw[28:32]) + r.RetType = binary.LittleEndian.Uint32(raw[32:36]) + return r +} + +func NewNameEventFast(raw []byte) *NameEvent { + if len(raw) != nameEventSize { + return NewNameEvent(raw) + } + n := poolOfNameEvents.Get().(*NameEvent) + n.EventType = EventType(binary.LittleEndian.Uint32(raw[0:4])) + n.TraceId = TraceId(binary.LittleEndian.Uint32(raw[4:8])) + n.Time = binary.LittleEndian.Uint64(raw[8:16]) + n.Pid = binary.LittleEndian.Uint32(raw[16:20]) + n.Tid = binary.LittleEndian.Uint32(raw[20:24]) + copy(n.Oldname[:], raw[24:280]) + copy(n.Newname[:], raw[280:536]) + return n +} + +func NewPathEventFast(raw []byte) *PathEvent { + if len(raw) != pathEventSize { + return NewPathEvent(raw) + } + p := poolOfPathEvents.Get().(*PathEvent) + p.EventType = EventType(binary.LittleEndian.Uint32(raw[0:4])) + p.TraceId = TraceId(binary.LittleEndian.Uint32(raw[4:8])) + p.Time = binary.LittleEndian.Uint64(raw[8:16]) + p.Pid = binary.LittleEndian.Uint32(raw[16:20]) + p.Tid = binary.LittleEndian.Uint32(raw[20:24]) + copy(p.Pathname[:], raw[24:280]) + return p +} + +func NewFcntlEventFast(raw []byte) *FcntlEvent { + if len(raw) != fcntlEventSize { + return NewFcntlEvent(raw) + } + f := poolOfFcntlEvents.Get().(*FcntlEvent) + f.EventType = EventType(binary.LittleEndian.Uint32(raw[0:4])) + f.TraceId = TraceId(binary.LittleEndian.Uint32(raw[4:8])) + f.Time = binary.LittleEndian.Uint64(raw[8:16]) + f.Pid = binary.LittleEndian.Uint32(raw[16:20]) + f.Tid = binary.LittleEndian.Uint32(raw[20:24]) + f.Fd = binary.LittleEndian.Uint32(raw[24:28]) + f.Cmd = binary.LittleEndian.Uint32(raw[28:32]) + f.Arg = binary.LittleEndian.Uint64(raw[32:40]) + return f +} + +func NewDup3EventFast(raw []byte) *Dup3Event { + if len(raw) != dup3EventSize { + return NewDup3Event(raw) + } + d := poolOfDup3Events.Get().(*Dup3Event) + d.EventType = EventType(binary.LittleEndian.Uint32(raw[0:4])) + d.TraceId = TraceId(binary.LittleEndian.Uint32(raw[4:8])) + d.Time = binary.LittleEndian.Uint64(raw[8:16]) + d.Pid = binary.LittleEndian.Uint32(raw[16:20]) + d.Tid = binary.LittleEndian.Uint32(raw[20:24]) + d.Fd = int32(binary.LittleEndian.Uint32(raw[24:28])) + d.Flags = int32(binary.LittleEndian.Uint32(raw[28:32])) + return d +} + +func NewOpenByHandleAtEventFast(raw []byte) *OpenByHandleAtEvent { + if len(raw) != openByHandleAtEventSize { + return NewOpenByHandleAtEvent(raw) + } + o := poolOfOpenByHandleAtEvents.Get().(*OpenByHandleAtEvent) + o.EventType = EventType(binary.LittleEndian.Uint32(raw[0:4])) + o.TraceId = TraceId(binary.LittleEndian.Uint32(raw[4:8])) + o.Time = binary.LittleEndian.Uint64(raw[8:16]) + o.Pid = binary.LittleEndian.Uint32(raw[16:20]) + o.Tid = binary.LittleEndian.Uint32(raw[20:24]) + o.Flags = int32(binary.LittleEndian.Uint32(raw[24:28])) + return o +} diff --git a/internal/types/fastdecode_test.go b/internal/types/fastdecode_test.go new file mode 100644 index 0000000..3ce5592 --- /dev/null +++ b/internal/types/fastdecode_test.go @@ -0,0 +1,127 @@ +package types + +import "testing" + +func TestFastDecodersMatchGeneratedDecoders(t *testing.T) { + t.Run("OpenEvent", func(t *testing.T) { + ev := &OpenEvent{EventType: ENTER_OPEN_EVENT, TraceId: SYS_ENTER_OPENAT, Time: 1, Pid: 2, Tid: 3, Flags: 4} + copy(ev.Filename[:], "a") + copy(ev.Comm[:], "b") + raw, _ := ev.Bytes() + + slow := NewOpenEvent(raw) + fast := NewOpenEventFast(raw) + defer slow.Recycle() + defer fast.Recycle() + if !slow.Equals(fast) { + t.Fatalf("open decode mismatch") + } + }) + + t.Run("NullEvent", func(t *testing.T) { + ev := &NullEvent{EventType: ENTER_NULL_EVENT, TraceId: SYS_ENTER_SYNC, Time: 1, Pid: 2, Tid: 3} + raw, _ := ev.Bytes() + + slow := NewNullEvent(raw) + fast := NewNullEventFast(raw) + defer slow.Recycle() + defer fast.Recycle() + if !slow.Equals(fast) { + t.Fatalf("null decode mismatch") + } + }) + + t.Run("FdEvent", func(t *testing.T) { + ev := &FdEvent{EventType: ENTER_FD_EVENT, TraceId: SYS_ENTER_READ, Time: 1, Pid: 2, Tid: 3, Fd: 4} + raw, _ := ev.Bytes() + + slow := NewFdEvent(raw) + fast := NewFdEventFast(raw) + defer slow.Recycle() + defer fast.Recycle() + if !slow.Equals(fast) { + t.Fatalf("fd decode mismatch") + } + }) + + t.Run("RetEvent", func(t *testing.T) { + ev := &RetEvent{EventType: EXIT_RET_EVENT, TraceId: SYS_EXIT_READ, Time: 1, Ret: 2, Pid: 3, Tid: 4, RetType: READ_CLASSIFIED} + raw, _ := ev.Bytes() + + slow := NewRetEvent(raw) + fast := NewRetEventFast(raw) + defer slow.Recycle() + defer fast.Recycle() + if !slow.Equals(fast) { + t.Fatalf("ret decode mismatch") + } + }) + + t.Run("NameEvent", func(t *testing.T) { + ev := &NameEvent{EventType: ENTER_NAME_EVENT, TraceId: SYS_ENTER_RENAME, Time: 1, Pid: 2, Tid: 3} + copy(ev.Oldname[:], "old") + copy(ev.Newname[:], "new") + raw, _ := ev.Bytes() + + slow := NewNameEvent(raw) + fast := NewNameEventFast(raw) + defer slow.Recycle() + defer fast.Recycle() + if !slow.Equals(fast) { + t.Fatalf("name decode mismatch") + } + }) + + t.Run("PathEvent", func(t *testing.T) { + ev := &PathEvent{EventType: ENTER_PATH_EVENT, TraceId: SYS_ENTER_MKDIR, Time: 1, Pid: 2, Tid: 3} + copy(ev.Pathname[:], "path") + raw, _ := ev.Bytes() + + slow := NewPathEvent(raw) + fast := NewPathEventFast(raw) + defer slow.Recycle() + defer fast.Recycle() + if !slow.Equals(fast) { + t.Fatalf("path decode mismatch") + } + }) + + t.Run("FcntlEvent", func(t *testing.T) { + ev := &FcntlEvent{EventType: ENTER_FCNTL_EVENT, TraceId: SYS_ENTER_FCNTL, Time: 1, Pid: 2, Tid: 3, Fd: 4, Cmd: 5, Arg: 6} + raw, _ := ev.Bytes() + + slow := NewFcntlEvent(raw) + fast := NewFcntlEventFast(raw) + defer slow.Recycle() + defer fast.Recycle() + if !slow.Equals(fast) { + t.Fatalf("fcntl decode mismatch") + } + }) + + t.Run("Dup3Event", func(t *testing.T) { + ev := &Dup3Event{EventType: ENTER_DUP3_EVENT, TraceId: SYS_ENTER_DUP3, Time: 1, Pid: 2, Tid: 3, Fd: 4, Flags: 5} + raw, _ := ev.Bytes() + + slow := NewDup3Event(raw) + fast := NewDup3EventFast(raw) + defer slow.Recycle() + defer fast.Recycle() + if !slow.Equals(fast) { + t.Fatalf("dup3 decode mismatch") + } + }) + + t.Run("OpenByHandleAtEvent", func(t *testing.T) { + ev := &OpenByHandleAtEvent{EventType: ENTER_OPEN_BY_HANDLE_AT_EVENT, TraceId: SYS_ENTER_OPEN_BY_HANDLE_AT, Time: 1, Pid: 2, Tid: 3, Flags: 4} + raw, _ := ev.Bytes() + + slow := NewOpenByHandleAtEvent(raw) + fast := NewOpenByHandleAtEventFast(raw) + defer slow.Recycle() + defer fast.Recycle() + if !slow.Equals(fast) { + t.Fatalf("open_by_handle_at decode mismatch") + } + }) +} |
