From 86a55e2c0abd419d888ab42d2db8165d8514aa1e Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Wed, 31 Jan 2024 19:04:33 +0530 Subject: [PATCH] Use an aligned slice for file reads --- kittens/pager/file_input.go | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/kittens/pager/file_input.go b/kittens/pager/file_input.go index f438452aa..23e8cd15b 100644 --- a/kittens/pager/file_input.go +++ b/kittens/pager/file_input.go @@ -10,6 +10,7 @@ import ( "os" "strings" "time" + "unsafe" "golang.org/x/sys/unix" ) @@ -31,9 +32,19 @@ func wait_for_file_to_grow(file_name string, limit int64) (err error) { return } +func aligned_slice(b []byte, alignment uintptr) []byte { + addr := uintptr(unsafe.Pointer(&b)) + extra := addr & (alignment - 1) + if extra > 0 { + return b[alignment-extra:] + } + return b +} + func read_input(input_file *os.File, input_file_name string, input_channel chan<- input_line_struct, follow bool, count_carriage_returns bool) { const buf_capacity = 8192 - var buf_array [buf_capacity]byte + var buf_storage [buf_capacity + 128]byte // ensure we have an 64 byte aligned slice with at least 64 bytes after it + buf := aligned_slice(buf_storage[:], 64)[:buf_capacity] output_buf := strings.Builder{} output_buf.Grow(buf_capacity) var err error @@ -92,10 +103,10 @@ func read_input(input_file *os.File, input_file_name string, input_channel chan< for { for err != nil { - n, err = input_file.Read(buf_array[:]) + n, err = input_file.Read(buf) if n > 0 { total_read += int64(n) - process_chunk(buf_array[:n]) + process_chunk(buf) } if err == unix.EAGAIN || err == unix.EINTR { err = nil