about summary refs log tree commit diff
path: root/vendor/modernc.org/libc/watch.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/modernc.org/libc/watch.go')
-rw-r--r--vendor/modernc.org/libc/watch.go240
1 files changed, 240 insertions, 0 deletions
diff --git a/vendor/modernc.org/libc/watch.go b/vendor/modernc.org/libc/watch.go
new file mode 100644
index 0000000..043957c
--- /dev/null
+++ b/vendor/modernc.org/libc/watch.go
@@ -0,0 +1,240 @@
+// Copyright 2021 The Libc 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 libc // import "modernc.org/libc"
+
+import (
+	"fmt"
+	"math"
+	"os"
+	"sync"
+	"unsafe"
+)
+
+var (
+	watches   = map[uintptr]watch{}
+	watchesMu sync.Mutex
+)
+
+type watch interface {
+	msg() string
+}
+
+type watcher string
+
+func (w watcher) msg() string {
+	if w == "" {
+		return ""
+	}
+
+	return fmt.Sprintf(": %s", w)
+}
+
+type watchInt8 struct {
+	val int8
+	watcher
+}
+
+func WatchInt8(p uintptr, msg string) {
+	watchesMu.Lock()
+	watches[p] = &watchInt8{*(*int8)(unsafe.Pointer(p)), watcher(msg)}
+	watchesMu.Unlock()
+}
+
+type watchUint8 struct {
+	val uint8
+	watcher
+}
+
+func WatchUint8(p uintptr, msg string) {
+	watchesMu.Lock()
+	watches[p] = &watchUint8{*(*uint8)(unsafe.Pointer(p)), watcher(msg)}
+	watchesMu.Unlock()
+}
+
+type watchInt16 struct {
+	val int16
+	watcher
+}
+
+func WatchInt16(p uintptr, msg string) {
+	watchesMu.Lock()
+	watches[p] = &watchInt16{*(*int16)(unsafe.Pointer(p)), watcher(msg)}
+	watchesMu.Unlock()
+}
+
+type watchUint16 struct {
+	val uint16
+	watcher
+}
+
+func WatchUint16(p uintptr, msg string) {
+	watchesMu.Lock()
+	watches[p] = &watchUint16{*(*uint16)(unsafe.Pointer(p)), watcher(msg)}
+	watchesMu.Unlock()
+}
+
+type watchInt32 struct {
+	val int32
+	watcher
+}
+
+func WatchInt32(p uintptr, msg string) {
+	watchesMu.Lock()
+	watches[p] = &watchInt32{*(*int32)(unsafe.Pointer(p)), watcher(msg)}
+	watchesMu.Unlock()
+}
+
+type watchUint32 struct {
+	val uint32
+	watcher
+}
+
+func WatchUint32(p uintptr, msg string) {
+	watchesMu.Lock()
+	watches[p] = &watchUint32{*(*uint32)(unsafe.Pointer(p)), watcher(msg)}
+	watchesMu.Unlock()
+}
+
+type watchInt64 struct {
+	val int64
+	watcher
+}
+
+func WatchInt64(p uintptr, msg string) {
+	watchesMu.Lock()
+	watches[p] = &watchInt64{*(*int64)(unsafe.Pointer(p)), watcher(msg)}
+	watchesMu.Unlock()
+}
+
+type watchUint64 struct {
+	val uint64
+	watcher
+}
+
+func WatchUint64(p uintptr, msg string) {
+	watchesMu.Lock()
+	watches[p] = &watchUint64{*(*uint64)(unsafe.Pointer(p)), watcher(msg)}
+	watchesMu.Unlock()
+}
+
+type watchFloat32 struct {
+	val float32
+	watcher
+}
+
+func WatchFloat32(p uintptr, msg string) {
+	watchesMu.Lock()
+	watches[p] = &watchFloat32{*(*float32)(unsafe.Pointer(p)), watcher(msg)}
+	watchesMu.Unlock()
+}
+
+type watchFloat64 struct {
+	val float64
+	watcher
+}
+
+func WatchFloat64(p uintptr, msg string) {
+	watchesMu.Lock()
+	watches[p] = &watchFloat64{*(*float64)(unsafe.Pointer(p)), watcher(msg)}
+	watchesMu.Unlock()
+}
+
+type watchPtr struct {
+	val uintptr
+	watcher
+}
+
+func WatchPtr(p uintptr, msg string) {
+	watchesMu.Lock()
+	watches[p] = &watchPtr{*(*uintptr)(unsafe.Pointer(p)), watcher(msg)}
+	watchesMu.Unlock()
+}
+
+func Watch() {
+	watchesMu.Lock()
+	flush := false
+	for p, v := range watches {
+		switch x := v.(type) {
+		case *watchInt8:
+			if val := *(*int8)(unsafe.Pointer(p)); val != x.val {
+				flush = true
+				fmt.Fprintf(os.Stderr, "%v: int8@%#x was %d, new %d%s\n", origin(2), p, x.val, val, x.msg())
+				x.val = val
+			}
+		case *watchUint8:
+			if val := *(*uint8)(unsafe.Pointer(p)); val != x.val {
+				flush = true
+				fmt.Fprintf(os.Stderr, "%v: uint8@%#x was %d, new %d%s\n", origin(2), p, x.val, val, x.msg())
+				x.val = val
+			}
+		case *watchInt16:
+			if val := *(*int16)(unsafe.Pointer(p)); val != x.val {
+				flush = true
+				fmt.Fprintf(os.Stderr, "%v: int16@%#x was %d, new %d%s\n", origin(2), p, x.val, val, x.msg())
+				x.val = val
+			}
+		case *watchUint16:
+			if val := *(*uint16)(unsafe.Pointer(p)); val != x.val {
+				flush = true
+				fmt.Fprintf(os.Stderr, "%v: uint16@%#x was %d, new %d%s\n", origin(2), p, x.val, val, x.msg())
+				x.val = val
+			}
+		case *watchInt32:
+			if val := *(*int32)(unsafe.Pointer(p)); val != x.val {
+				flush = true
+				fmt.Fprintf(os.Stderr, "%v: int32@%#x was %d, new %d%s\n", origin(2), p, x.val, val, x.msg())
+				x.val = val
+			}
+		case *watchUint32:
+			if val := *(*uint32)(unsafe.Pointer(p)); val != x.val {
+				flush = true
+				fmt.Fprintf(os.Stderr, "%v: uint32@%#x was %d, new %d%s\n", origin(2), p, x.val, val, x.msg())
+				x.val = val
+			}
+		case *watchInt64:
+			if val := *(*int64)(unsafe.Pointer(p)); val != x.val {
+				flush = true
+				fmt.Fprintf(os.Stderr, "%v: int64@%#x was %d, new %d%s\n", origin(2), p, x.val, val, x.msg())
+				x.val = val
+			}
+		case *watchUint64:
+			if val := *(*uint64)(unsafe.Pointer(p)); val != x.val {
+				flush = true
+				fmt.Fprintf(os.Stderr, "%v: uint64@%#x was %d, new %d%s\n", origin(2), p, x.val, val, x.msg())
+				x.val = val
+			}
+		case *watchFloat32:
+			if val := *(*float32)(unsafe.Pointer(p)); math.Float32bits(val) != math.Float32bits(x.val) {
+				flush = true
+				fmt.Fprintf(os.Stderr, "%v: float32@%#x was %v(%#x), new %v(%#x)%s\n", origin(2), p, x.val, math.Float32bits(x.val), val, math.Float32bits(val), x.msg())
+				x.val = val
+			}
+		case *watchFloat64:
+			if val := *(*float64)(unsafe.Pointer(p)); math.Float64bits(val) != math.Float64bits(x.val) {
+				flush = true
+				fmt.Fprintf(os.Stderr, "%v: float64@%#x was %v(%#x), new %v(%#x)%s\n", origin(2), p, x.val, math.Float64bits(x.val), val, math.Float64bits(val), x.msg())
+				x.val = val
+			}
+		case *watchPtr:
+			if val := *(*uintptr)(unsafe.Pointer(p)); val != x.val {
+				flush = true
+				fmt.Fprintf(os.Stderr, "%v: ptr@%#x was %#x, new %#x%s\n", origin(2), p, x.val, val, x.msg())
+				x.val = val
+			}
+		default:
+			panic(todo("%T", x))
+		}
+	}
+	if flush {
+		os.Stderr.Sync()
+	}
+	watchesMu.Unlock()
+}
+
+func WatchDelete(p uintptr) {
+	watchesMu.Lock()
+	delete(watches, p)
+	watchesMu.Unlock()
+}