From e6b2d2aef5fddaeda48e4d8e8a6eabfe4f3efb96 Mon Sep 17 00:00:00 2001 From: Nuno Cruces Date: Mon, 24 Nov 2025 13:42:12 +0000 Subject: [PATCH] Bulk copies. --- vfs/shm_copy.go | 93 ++++++++++++++++++++++++++++++++++--------------- 1 file changed, 64 insertions(+), 29 deletions(-) diff --git a/vfs/shm_copy.go b/vfs/shm_copy.go index fce6325..540f83b 100644 --- a/vfs/shm_copy.go +++ b/vfs/shm_copy.go @@ -35,38 +35,44 @@ func (s *vfsShm) shmAcquire(errp *error) { if errp != nil && *errp != nil { return } - if len(s.ptrs) == 0 || shmEqual(s.shadow[0][:], s.shared[0][:]) { + if len(s.ptrs) == 0 { return } - // Copies modified words from shared to private memory. - for id, p := range s.ptrs { - shared := shmPage(s.shared[id][:]) - shadow := shmPage(s.shadow[id][:]) - privat := shmPage(util.View(s.mod, p, _WALINDEX_PGSZ)) - for i, shared := range shared { - if shadow[i] != shared { - shadow[i] = shared - privat[i] = shared - } - } + if !shmCopyHeader( + util.View(s.mod, s.ptrs[0], _WALINDEX_HDR_SIZE), + s.shadow[0][:], + s.shared[0][:]) { + return + } + + skip := _WALINDEX_HDR_SIZE + for id := range s.ptrs { + shmCopyTables( + util.View(s.mod, s.ptrs[id], _WALINDEX_PGSZ)[skip:], + s.shadow[id][skip:], + s.shared[id][skip:]) + skip = 0 } } func (s *vfsShm) shmRelease() { - if len(s.ptrs) == 0 || shmEqual(s.shadow[0][:], util.View(s.mod, s.ptrs[0], _WALINDEX_HDR_SIZE)) { + if len(s.ptrs) == 0 { return } - // Copies modified words from private to shared memory. - for id, p := range s.ptrs { - shared := shmPage(s.shared[id][:]) - shadow := shmPage(s.shadow[id][:]) - privat := shmPage(util.View(s.mod, p, _WALINDEX_PGSZ)) - for i, privat := range privat { - if shadow[i] != privat { - shadow[i] = privat - shared[i] = privat - } - } + if !shmCopyHeader( + s.shared[0][:], + s.shadow[0][:], + util.View(s.mod, s.ptrs[0], _WALINDEX_HDR_SIZE)) { + return + } + + skip := _WALINDEX_HDR_SIZE + for id := range s.ptrs { + shmCopyTables( + s.shared[id][skip:], + s.shadow[id][skip:], + util.View(s.mod, s.ptrs[id], _WALINDEX_PGSZ)[skip:]) + skip = 0 } } @@ -77,11 +83,40 @@ func (s *vfsShm) shmBarrier() { s.Unlock() } -func shmPage(s []byte) *[_WALINDEX_PGSZ / 4]uint32 { - p := (*uint32)(unsafe.Pointer(unsafe.SliceData(s))) - return (*[_WALINDEX_PGSZ / 4]uint32)(unsafe.Slice(p, _WALINDEX_PGSZ/4)) +func shmCopyTables(v1, v2, v3 []byte) { + if string(v2) != string(v3) { + copy(v1, v3) + copy(v2, v3) + } } -func shmEqual(v1, v2 []byte) bool { - return *(*[_WALINDEX_HDR_SIZE]byte)(v1[:]) == *(*[_WALINDEX_HDR_SIZE]byte)(v2[:]) +func shmCopyHeader(s1, s2, s3 []byte) (ret bool) { + // First copy of the WAL Index Information. + if string(s2[:48]) != string(s3[:48]) { + copy(s1, s3[:48]) + copy(s2, s3[:48]) + ret = true + } + // Second copy of the WAL Index Information. + if string(s2[48:][:48]) != string(s3[48:][:48]) { + copy(s1[48:], s3[48:][:48]) + copy(s2[48:], s3[48:][:48]) + ret = true + } + // Checkpoint Information and Locks. + i1 := shmCheckpointInfo(s1) + i2 := shmCheckpointInfo(s2) + for i, i3 := range shmCheckpointInfo(s3) { + if i2[i] != i3 { + i1[i] = i3 + i2[i] = i3 + ret = true + } + } + return +} + +func shmCheckpointInfo(s []byte) *[10]uint32 { + p := (*uint32)(unsafe.Pointer(&s[96])) + return (*[10]uint32)(unsafe.Slice(p, 10)) }