--- /dev/null
+// Copyright 2024 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.
+
+package unix_test
+
+import (
+ "internal/syscall/unix"
+ "testing"
+)
+
+func BenchmarkParallelGetRandom(b *testing.B) {
+ b.SetBytes(4)
+ b.RunParallel(func(pb *testing.PB) {
+ var buf [4]byte
+ for pb.Next() {
+ if _, err := unix.GetRandom(buf[:], 0); err != nil {
+ b.Fatal(err)
+ }
+ }
+ })
+}
package runtime
-import "unsafe"
+import (
+ "internal/cpu"
+ "unsafe"
+)
func vgetrandom1(buf *byte, length uintptr, flags uint32, state uintptr, stateSize uintptr) int
lock(&vgetrandomAlloc.statesLock)
if len(vgetrandomAlloc.states) == 0 {
num := uintptr(ncpu) // Just a reasonable size hint to start.
- allocSize := (num*vgetrandomAlloc.stateSize + physPageSize - 1) &^ (physPageSize - 1)
- num = (physPageSize / vgetrandomAlloc.stateSize) * (allocSize / physPageSize)
+ stateSizeCacheAligned := (vgetrandomAlloc.stateSize + cpu.CacheLineSize - 1) &^ (cpu.CacheLineSize - 1)
+ allocSize := (num*stateSizeCacheAligned + physPageSize - 1) &^ (physPageSize - 1)
+ num = (physPageSize / stateSizeCacheAligned) * (allocSize / physPageSize)
p, err := mmap(nil, allocSize, vgetrandomAlloc.mmapProt, vgetrandomAlloc.mmapFlags, -1, 0)
if err != 0 {
unlock(&vgetrandomAlloc.statesLock)
newBlock = (newBlock + physPageSize - 1) &^ (physPageSize - 1)
}
vgetrandomAlloc.states = append(vgetrandomAlloc.states, newBlock)
- newBlock += vgetrandomAlloc.stateSize
+ newBlock += stateSizeCacheAligned
}
}
state := vgetrandomAlloc.states[len(vgetrandomAlloc.states)-1]