Skip to content

Commit

Permalink
internal/race,s2: add some race instrumentation (#903)
Browse files Browse the repository at this point in the history
  • Loading branch information
egonelbre authored Dec 19, 2023
1 parent 0619f9a commit 93a6c80
Show file tree
Hide file tree
Showing 6 changed files with 69 additions and 0 deletions.
13 changes: 13 additions & 0 deletions internal/race/norace.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// Copyright 2015 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

//go:build !race

package race

func ReadSlice[T any](s []T) {

Check failure on line 9 in internal/race/norace.go

View workflow job for this annotation

GitHub Actions / build-special

type parameter requires go1.18 or later (-lang was set to go1.16; check go.mod)

Check failure on line 9 in internal/race/norace.go

View workflow job for this annotation

GitHub Actions / build-special

predeclared any requires go1.18 or later (-lang was set to go1.16; check go.mod)
}

func WriteSlice[T any](s []T) {

Check failure on line 12 in internal/race/norace.go

View workflow job for this annotation

GitHub Actions / build-special

type parameter requires go1.18 or later (-lang was set to go1.16; check go.mod)

Check failure on line 12 in internal/race/norace.go

View workflow job for this annotation

GitHub Actions / build-special

predeclared any requires go1.18 or later (-lang was set to go1.16; check go.mod)
}
26 changes: 26 additions & 0 deletions internal/race/race.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
// Copyright 2015 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

//go:build race

package race

import (
"runtime"
"unsafe"
)

func ReadSlice[T any](s []T) {
if len(s) == 0 {
return
}
runtime.RaceReadRange(unsafe.Pointer(&s[0]), len(s)*int(unsafe.Sizeof(s[0])))
}

func WriteSlice[T any](s []T) {
if len(s) == 0 {
return
}
runtime.RaceWriteRange(unsafe.Pointer(&s[0]), len(s)*int(unsafe.Sizeof(s[0])))
}
6 changes: 6 additions & 0 deletions s2/decode.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ import (
"errors"
"fmt"
"strconv"

"github.com/klauspost/compress/internal/race"
)

var (
Expand Down Expand Up @@ -63,6 +65,10 @@ func Decode(dst, src []byte) ([]byte, error) {
} else {
dst = make([]byte, dLen)
}

race.WriteSlice(dst)
race.ReadSlice(src[s:])

if s2Decode(dst, src[s:]) != 0 {
return nil, ErrCorrupt
}
Expand Down
14 changes: 14 additions & 0 deletions s2/encode_amd64.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@

package s2

import "github.com/klauspost/compress/internal/race"

const hasAmd64Asm = true

// encodeBlock encodes a non-empty src to a guaranteed-large-enough dst. It
Expand All @@ -14,6 +16,9 @@ const hasAmd64Asm = true
// len(dst) >= MaxEncodedLen(len(src)) &&
// minNonLiteralBlockSize <= len(src) && len(src) <= maxBlockSize
func encodeBlock(dst, src []byte) (d int) {
race.ReadSlice(src)
race.WriteSlice(dst)

const (
// Use 12 bit table when less than...
limit12B = 16 << 10
Expand Down Expand Up @@ -50,6 +55,9 @@ func encodeBlock(dst, src []byte) (d int) {
// len(dst) >= MaxEncodedLen(len(src)) &&
// minNonLiteralBlockSize <= len(src) && len(src) <= maxBlockSize
func encodeBlockBetter(dst, src []byte) (d int) {
race.ReadSlice(src)
race.WriteSlice(dst)

const (
// Use 12 bit table when less than...
limit12B = 16 << 10
Expand Down Expand Up @@ -86,6 +94,9 @@ func encodeBlockBetter(dst, src []byte) (d int) {
// len(dst) >= MaxEncodedLen(len(src)) &&
// minNonLiteralBlockSize <= len(src) && len(src) <= maxBlockSize
func encodeBlockSnappy(dst, src []byte) (d int) {
race.ReadSlice(src)
race.WriteSlice(dst)

const (
// Use 12 bit table when less than...
limit12B = 16 << 10
Expand Down Expand Up @@ -121,6 +132,9 @@ func encodeBlockSnappy(dst, src []byte) (d int) {
// len(dst) >= MaxEncodedLen(len(src)) &&
// minNonLiteralBlockSize <= len(src) && len(src) <= maxBlockSize
func encodeBlockBetterSnappy(dst, src []byte) (d int) {
race.ReadSlice(src)
race.WriteSlice(dst)

const (
// Use 12 bit table when less than...
limit12B = 16 << 10
Expand Down
4 changes: 4 additions & 0 deletions s2/s2.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ package s2
import (
"bytes"
"hash/crc32"

"github.com/klauspost/compress/internal/race"
)

/*
Expand Down Expand Up @@ -112,6 +114,8 @@ var crcTable = crc32.MakeTable(crc32.Castagnoli)
// crc implements the checksum specified in section 3 of
// https://github.com/google/snappy/blob/master/framing_format.txt
func crc(b []byte) uint32 {
race.ReadSlice(b)

c := crc32.Update(0, crcTable, b)
return c>>15 | c<<17 + 0xa282ead8
}
Expand Down
6 changes: 6 additions & 0 deletions s2/writer.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ import (
"io"
"runtime"
"sync"

"github.com/klauspost/compress/internal/race"
)

const (
Expand Down Expand Up @@ -385,6 +387,8 @@ func (w *Writer) EncodeBuffer(buf []byte) (err error) {
buf = buf[len(uncompressed):]
// Get an output buffer.
obuf := w.buffers.Get().([]byte)[:len(uncompressed)+obufHeaderLen]
race.WriteSlice(obuf)

output := make(chan result)
// Queue output now, so we keep order.
w.output <- output
Expand All @@ -393,6 +397,8 @@ func (w *Writer) EncodeBuffer(buf []byte) (err error) {
}
w.uncompWritten += int64(len(uncompressed))
go func() {
race.ReadSlice(uncompressed)

checksum := crc(uncompressed)

// Set to uncompressed.
Expand Down

0 comments on commit 93a6c80

Please sign in to comment.