summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--internal/eventloop.go24
-rw-r--r--internal/types/fastdecode.go147
-rw-r--r--internal/types/fastdecode_test.go127
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")
+ }
+ })
+}