carlos / platform Public

Clone
git clone https://amadan.net/carlos/platform

Plain git — no account needed to clone.

Download

Download this file

1//go:build linux
2
3package host
4
5import (
6 "os"
7 "path/filepath"
8 "syscall"
9 "time"
10 "unsafe"
11
12 "github.com/carlosframework/platform/internal/moves"
13)
14
15// measureDiskSize is how much T11's disk measurement writes and reads back.
16const measureDiskSize = 64 << 20
17
18// measureDiskRate times writing and reading measureDiskSize under dir with
19// O_DIRECT, so the page cache neither absorbs the write nor answers the
20// read (F12). A filesystem that refuses O_DIRECT (tmpfs) is measured with a
21// plain write, fsync and read instead.
22func measureDiskRate(dir string, now func() time.Time) (moves.MeasuredRate, error) {
23 path := filepath.Join(dir, "disk")
24 f, err := os.OpenFile(path, os.O_CREATE|os.O_EXCL|os.O_RDWR|syscall.O_DIRECT, 0o600)
25 if err != nil {
26 return measureDiskSynced(dir, now)
27 }
28 defer f.Close()
29 buf := alignedBlock(1 << 20)
30 start := now()
31 for n := 0; n < measureDiskSize; n += len(buf) {
32 if _, err := f.Write(buf); err != nil {
33 return moves.MeasuredRate{}, err
34 }
35 }
36 if err := f.Sync(); err != nil {
37 return moves.MeasuredRate{}, err
38 }
39 if _, err := f.Seek(0, 0); err != nil {
40 return moves.MeasuredRate{}, err
41 }
42 for n := 0; n < measureDiskSize; n += len(buf) {
43 if _, err := f.Read(buf); err != nil {
44 return moves.MeasuredRate{}, err
45 }
46 }
47 return moves.RateOf(2*measureDiskSize, now().Sub(start), now().UTC()), nil
48}
49
50// alignedBlock is a size-byte buffer aligned to 4096 bytes, as O_DIRECT
51// requires.
52func alignedBlock(size int) []byte {
53 const align = 4096
54 b := make([]byte, size+align)
55 off := 0
56 if r := int(uintptr(unsafe.Pointer(&b[0])) & (align - 1)); r != 0 {
57 off = align - r
58 }
59 return b[off : off+size]
60}
61