Skip to content

Commit 7c45999

Browse files
committed
Switch to Append style encoding
Signed-off-by: Alun Evans <[email protected]>
1 parent 676899f commit 7c45999

File tree

1 file changed

+19
-17
lines changed

1 file changed

+19
-17
lines changed

marshalers.go

Lines changed: 19 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import (
55
"errors"
66
"fmt"
77
"reflect"
8+
"slices"
89
"unsafe"
910

1011
"github.com/cilium/ebpf/internal"
@@ -43,33 +44,36 @@ func makeMapSyscallOutput(dst any, length int) sysenc.Buffer {
4344
return sysenc.SyscallOutput(dst, length)
4445
}
4546

46-
// marshalSlice encodes a slice containing one value per
47+
// appendPerCPUSlice encodes a slice containing one value per
4748
// possible CPU into a buffer of bytes.
4849
//
4950
// Values are initialized to zero if the slice has less elements than CPUs.
50-
func marshalSlice(slice any, elemLength, possibleCPUs, alignedElemLength int, buf []byte) error {
51+
func appendPerCPUSlice(buf []byte, slice any, possibleCPUs, elemLength, alignedElemLength int) ([]byte, error) {
5152
sliceType := reflect.TypeOf(slice)
5253
if sliceType.Kind() != reflect.Slice {
53-
return errors.New("per-CPU value requires slice")
54+
return nil, errors.New("per-CPU value requires slice")
5455
}
5556

5657
sliceValue := reflect.ValueOf(slice)
5758
sliceLen := sliceValue.Len()
5859
if sliceLen > possibleCPUs {
59-
return fmt.Errorf("per-CPU value exceeds number of CPUs")
60+
return nil, fmt.Errorf("per-CPU value exceeds number of CPUs")
6061
}
6162

63+
// Grow increases the slice's capacity, _if_necessary_
64+
buf = slices.Grow(buf, alignedElemLength*possibleCPUs)
6265
for i := 0; i < sliceLen; i++ {
6366
elem := sliceValue.Index(i).Interface()
6467
elemBytes, err := sysenc.Marshal(elem, elemLength)
6568
if err != nil {
66-
return err
69+
return nil, err
6770
}
6871

69-
offset := i * alignedElemLength
70-
elemBytes.CopyTo(buf[offset : offset+elemLength])
72+
b := make([]byte, alignedElemLength)
73+
elemBytes.CopyTo(b) // Only copies elemLength
74+
buf = append(buf, b...)
7175
}
72-
return nil
76+
return buf, nil
7377
}
7478

7579
// marshalPerCPUValue encodes a slice containing one value per
@@ -83,8 +87,9 @@ func marshalPerCPUValue(slice any, elemLength int) (sys.Pointer, error) {
8387
}
8488

8589
alignedElemLength := internal.Align(elemLength, 8)
86-
buf := make([]byte, alignedElemLength*possibleCPUs)
87-
if err := marshalSlice(slice, elemLength, possibleCPUs, alignedElemLength, buf); err != nil {
90+
buf := make([]byte, 0, alignedElemLength*possibleCPUs)
91+
buf, err = appendPerCPUSlice(buf, slice, possibleCPUs, elemLength, alignedElemLength)
92+
if err != nil {
8893
return sys.Pointer{}, err
8994
}
9095

@@ -108,18 +113,15 @@ func marshalBatchPerCPUValue(slice any, batchLen, elemLength int) (sys.Pointer,
108113
}
109114

110115
alignedElemLength := internal.Align(elemLength, 8)
111-
stride := alignedElemLength * possibleCPUs
112-
result := make([]byte, batchLen*stride)
113-
buf := result
116+
buf := make([]byte, 0, batchLen*alignedElemLength*possibleCPUs)
114117
for i := 0; i < batchLen; i++ {
115118
batch := sliceValue.Slice(i*possibleCPUs, (i+1)*possibleCPUs).Interface()
116-
if err := marshalSlice(batch, elemLength, possibleCPUs, alignedElemLength, buf[:stride]); err != nil {
119+
buf, err = appendPerCPUSlice(buf, batch, possibleCPUs, elemLength, alignedElemLength)
120+
if err != nil {
117121
return sys.Pointer{}, fmt.Errorf("batch %d: %w", i, err)
118122
}
119-
120-
buf = buf[stride:]
121123
}
122-
return sys.NewSlicePointer(result), nil
124+
return sys.NewSlicePointer(buf), nil
123125
}
124126

125127
// unmarshalPerCPUValue decodes a buffer into a slice containing one value per

0 commit comments

Comments
 (0)