aboutsummaryrefslogtreecommitdiff
path: root/contrib/bug216610/go
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/bug216610/go')
-rw-r--r--contrib/bug216610/go/.gitignore5
-rw-r--r--contrib/bug216610/go/fibber/fib.go32
-rw-r--r--contrib/bug216610/go/fibber/fibs_linux_amd64.s21
-rw-r--r--contrib/bug216610/go/fibber/fibs_linux_arm.s23
-rw-r--r--contrib/bug216610/go/go.mod5
-rw-r--r--contrib/bug216610/go/main.go29
6 files changed, 115 insertions, 0 deletions
diff --git a/contrib/bug216610/go/.gitignore b/contrib/bug216610/go/.gitignore
new file mode 100644
index 0000000..ae14305
--- /dev/null
+++ b/contrib/bug216610/go/.gitignore
@@ -0,0 +1,5 @@
+fib
+*.syso
+main
+go.sum
+linkage.go
diff --git a/contrib/bug216610/go/fibber/fib.go b/contrib/bug216610/go/fibber/fib.go
new file mode 100644
index 0000000..49757cd
--- /dev/null
+++ b/contrib/bug216610/go/fibber/fib.go
@@ -0,0 +1,32 @@
+// Package fibber implements a Fibonacci sequence generator using a C
+// coded compute kernel (a .syso file).
+package fibber
+
+import (
+ "unsafe"
+)
+
+// State is the native Go form of the C.state structure.
+type State struct {
+ B, A uint32
+}
+
+// cPtr converts State into a C pointer suitable as an argument for
+// sysoCaller.
+func (s *State) cPtr() unsafe.Pointer {
+ return unsafe.Pointer(&s.B)
+}
+
+// NewState initializes a Fibonacci Number sequence generator. Upon
+// return s.A=0 and s.B=1 are the first two numbers in the sequence.
+func NewState() *State {
+ s := &State{}
+ syso__fib_init.call(s.cPtr())
+ return s
+}
+
+// Next advances the state to the next number in the sequence. Upon
+// return, s.B is the most recently calculated value.
+func (s *State) Next() {
+ syso__fib_next.call(s.cPtr())
+}
diff --git a/contrib/bug216610/go/fibber/fibs_linux_amd64.s b/contrib/bug216610/go/fibber/fibs_linux_amd64.s
new file mode 100644
index 0000000..5992d09
--- /dev/null
+++ b/contrib/bug216610/go/fibber/fibs_linux_amd64.s
@@ -0,0 +1,21 @@
+// To transition from a Go call to a C function call, we are skating
+// on really thin ice... Ceveat Emptor!
+//
+// Ref:
+// https://gitlab.com/x86-psABIs/x86-64-ABI/-/wikis/home
+//
+// This is not strictly needed, but it makes gdb debugging less
+// confusing because spacer ends up being an alias for the TEXT
+// section start.
+TEXT ·spacer(SB),$0
+ RET
+
+#define RINDEX(n) (8*n)
+
+// Header to this function wrapper is the last time we can voluntarily
+// yield to some other goroutine.
+TEXT ·syso(SB),$0-16
+ MOVQ cFn+RINDEX(0)(FP), SI
+ MOVQ state+RINDEX(1)(FP), DI
+ CALL *SI
+ RET
diff --git a/contrib/bug216610/go/fibber/fibs_linux_arm.s b/contrib/bug216610/go/fibber/fibs_linux_arm.s
new file mode 100644
index 0000000..39640a5
--- /dev/null
+++ b/contrib/bug216610/go/fibber/fibs_linux_arm.s
@@ -0,0 +1,23 @@
+// To transition from a Go call to a C function call, we are skating
+// on really thin ice... Ceveat Emptor!
+//
+// Ref:
+// https://stackoverflow.com/questions/261419/what-registers-to-save-in-the-arm-c-calling-convention
+//
+// This is not strictly needed, but it makes gdb debugging less
+// confusing because spacer ends up being an alias for the TEXT
+// section start.
+TEXT ·spacer(SB),$0
+ RET
+
+#define FINDEX(n) (8*n)
+
+// Header to this function wrapper is the last time we can voluntarily
+// yield to some other goroutine.
+//
+// Conventions: PC == R15, SP == R13, LR == R14, IP (scratch) = R12
+TEXT ·syso(SB),$0-8
+ MOVW cFn+0(FP), R14
+ MOVW state+4(FP), R0
+ BL (R14)
+ RET
diff --git a/contrib/bug216610/go/go.mod b/contrib/bug216610/go/go.mod
new file mode 100644
index 0000000..8531994
--- /dev/null
+++ b/contrib/bug216610/go/go.mod
@@ -0,0 +1,5 @@
+module fib
+
+go 1.18
+
+require kernel.org/pub/linux/libs/security/libcap/psx v1.2.69
diff --git a/contrib/bug216610/go/main.go b/contrib/bug216610/go/main.go
new file mode 100644
index 0000000..65121f6
--- /dev/null
+++ b/contrib/bug216610/go/main.go
@@ -0,0 +1,29 @@
+// Program fib uses the psx package once, and then prints the first
+// ten Fibonacci numbers.
+package main
+
+import (
+ "fmt"
+ "log"
+ "syscall"
+
+ "fib/fibber"
+
+ "kernel.org/pub/linux/libs/security/libcap/psx"
+)
+
+func main() {
+ pid, _, err := psx.Syscall3(syscall.SYS_GETPID, 0, 0, 0)
+ if err != 0 {
+ log.Fatalf("failed to get PID via psx: %v", err)
+ }
+ fmt.Print("psx syscall result: PID=")
+ fmt.Println(pid)
+ s := fibber.NewState()
+ fmt.Print("fib: ", s.A, ", ", s.B)
+ for i := 0; i < 8; i++ {
+ s.Next()
+ fmt.Print(", ", s.B)
+ }
+ fmt.Println(", ...")
+}