summaryrefslogtreecommitdiff
path: root/vendor/github.com/ncruces/go-sqlite3/vfs/shm_copy.go
diff options
context:
space:
mode:
authorLibravatar kim <89579420+NyaaaWhatsUpDoc@users.noreply.github.com>2024-11-07 00:16:28 +0000
committerLibravatar GitHub <noreply@github.com>2024-11-07 00:16:28 +0000
commit45e1609377631070765065ffb35ed7d29e8e81f1 (patch)
tree51d170ff0d5fab1ab0f8b1b79c9dd8c31d4ce5b9 /vendor/github.com/ncruces/go-sqlite3/vfs/shm_copy.go
parent[chore] update go ffmpreg to v0.6.0 (#3515) (diff)
downloadgotosocial-45e1609377631070765065ffb35ed7d29e8e81f1.tar.xz
bump ncruces/go-sqlite3 to v0.20.2 (#3524)
Diffstat (limited to 'vendor/github.com/ncruces/go-sqlite3/vfs/shm_copy.go')
-rw-r--r--vendor/github.com/ncruces/go-sqlite3/vfs/shm_copy.go84
1 files changed, 84 insertions, 0 deletions
diff --git a/vendor/github.com/ncruces/go-sqlite3/vfs/shm_copy.go b/vendor/github.com/ncruces/go-sqlite3/vfs/shm_copy.go
new file mode 100644
index 000000000..7a250523e
--- /dev/null
+++ b/vendor/github.com/ncruces/go-sqlite3/vfs/shm_copy.go
@@ -0,0 +1,84 @@
+//go:build (windows && (386 || arm || amd64 || arm64 || riscv64 || ppc64le) && !sqlite3_nosys) || sqlite3_dotlk
+
+package vfs
+
+import (
+ "unsafe"
+
+ "github.com/ncruces/go-sqlite3/internal/util"
+)
+
+const (
+ _WALINDEX_HDR_SIZE = 136
+ _WALINDEX_PGSZ = 32768
+)
+
+// This looks like a safe way of keeping the WAL-index in sync.
+//
+// The WAL-index file starts with a header,
+// and the index doesn't meaningfully change if the header doesn't change.
+//
+// The header starts with two 48 byte, checksummed, copies of the same information,
+// which are accessed independently between memory barriers.
+// The checkpoint information that follows uses 4 byte aligned words.
+//
+// Finally, we have the WAL-index hash tables,
+// which are only modified holding the exclusive WAL_WRITE_LOCK.
+//
+// Since all the data is either redundant+checksummed,
+// 4 byte aligned, or modified under an exclusive lock,
+// the copies below should correctly keep copies in sync.
+//
+// https://sqlite.org/walformat.html#the_wal_index_file_format
+
+func (s *vfsShm) shmAcquire() {
+ if len(s.ptrs) == 0 || shmUnmodified(s.shadow[0][:], s.shared[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
+ }
+ }
+ }
+}
+
+func (s *vfsShm) shmRelease() {
+ if len(s.ptrs) == 0 || shmUnmodified(s.shadow[0][:], util.View(s.mod, s.ptrs[0], _WALINDEX_HDR_SIZE)) {
+ 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
+ }
+ }
+ }
+}
+
+func (s *vfsShm) shmBarrier() {
+ s.Lock()
+ s.shmAcquire()
+ s.shmRelease()
+ 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 shmUnmodified(v1, v2 []byte) bool {
+ return *(*[_WALINDEX_HDR_SIZE]byte)(v1[:]) == *(*[_WALINDEX_HDR_SIZE]byte)(v2[:])
+}