diff options
| author | YDBot <[email protected]> | 2026-06-10 06:27:27 +0000 |
|---|---|---|
| committer | YDBot <[email protected]> | 2026-06-10 06:27:27 +0000 |
| commit | eb8c7d3ee0c13034ecf5d8d35c24cefc40f0bb3f (patch) | |
| tree | a1eba7fec49a258bb24bfa77808233496ac0047f /contrib/go/_std_1.25/src/runtime/os_plan9.go | |
| parent | c4011885693f041c96b035f368aae8a1baac8885 (diff) | |
| parent | 72cfbf8958fa6fa5227e9ad6466abfc635fdeb15 (diff) | |
Diffstat (limited to 'contrib/go/_std_1.25/src/runtime/os_plan9.go')
| -rw-r--r-- | contrib/go/_std_1.25/src/runtime/os_plan9.go | 596 |
1 files changed, 0 insertions, 596 deletions
diff --git a/contrib/go/_std_1.25/src/runtime/os_plan9.go b/contrib/go/_std_1.25/src/runtime/os_plan9.go deleted file mode 100644 index 72a86579854..00000000000 --- a/contrib/go/_std_1.25/src/runtime/os_plan9.go +++ /dev/null @@ -1,596 +0,0 @@ -// Copyright 2010 The Go 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 runtime - -import ( - "internal/abi" - "internal/byteorder" - "internal/runtime/atomic" - "internal/stringslite" - "unsafe" -) - -type mOS struct { - waitsemacount uint32 - notesig *int8 - errstr *byte - ignoreHangup bool -} - -func dupfd(old, new int32) int32 -func closefd(fd int32) int32 - -//go:noescape -func open(name *byte, mode, perm int32) int32 - -//go:noescape -func pread(fd int32, buf unsafe.Pointer, nbytes int32, offset int64) int32 - -//go:noescape -func pwrite(fd int32, buf unsafe.Pointer, nbytes int32, offset int64) int32 - -func seek(fd int32, offset int64, whence int32) int64 - -//go:noescape -func exits(msg *byte) - -//go:noescape -func brk_(addr unsafe.Pointer) int32 - -func sleep(ms int32) int32 - -func rfork(flags int32) int32 - -//go:noescape -func plan9_semacquire(addr *uint32, block int32) int32 - -//go:noescape -func plan9_tsemacquire(addr *uint32, ms int32) int32 - -//go:noescape -func plan9_semrelease(addr *uint32, count int32) int32 - -//go:noescape -func notify(fn unsafe.Pointer) int32 - -func noted(mode int32) int32 - -//go:noescape -func nsec(*int64) int64 - -//go:noescape -func sigtramp(ureg, note unsafe.Pointer) - -func setfpmasks() - -//go:noescape -func tstart_plan9(newm *m) - -func errstr() string - -type _Plink uintptr - -func sigpanic() { - gp := getg() - if !canpanic() { - throw("unexpected signal during runtime execution") - } - - note := gostringnocopy((*byte)(unsafe.Pointer(gp.m.notesig))) - switch gp.sig { - case _SIGRFAULT, _SIGWFAULT: - i := indexNoFloat(note, "addr=") - if i >= 0 { - i += 5 - } else if i = indexNoFloat(note, "va="); i >= 0 { - i += 3 - } else { - panicmem() - } - addr := note[i:] - gp.sigcode1 = uintptr(atolwhex(addr)) - if gp.sigcode1 < 0x1000 { - panicmem() - } - if gp.paniconfault { - panicmemAddr(gp.sigcode1) - } - if inUserArenaChunk(gp.sigcode1) { - // We could check that the arena chunk is explicitly set to fault, - // but the fact that we faulted on accessing it is enough to prove - // that it is. - print("accessed data from freed user arena ", hex(gp.sigcode1), "\n") - } else { - print("unexpected fault address ", hex(gp.sigcode1), "\n") - } - throw("fault") - case _SIGTRAP: - if gp.paniconfault { - panicmem() - } - throw(note) - case _SIGINTDIV: - panicdivide() - case _SIGFLOAT: - panicfloat() - default: - panic(errorString(note)) - } -} - -// indexNoFloat is bytealg.IndexString but safe to use in a note -// handler. -func indexNoFloat(s, t string) int { - if len(t) == 0 { - return 0 - } - for i := 0; i < len(s); i++ { - if s[i] == t[0] && stringslite.HasPrefix(s[i:], t) { - return i - } - } - return -1 -} - -func atolwhex(p string) int64 { - for stringslite.HasPrefix(p, " ") || stringslite.HasPrefix(p, "\t") { - p = p[1:] - } - neg := false - if stringslite.HasPrefix(p, "-") || stringslite.HasPrefix(p, "+") { - neg = p[0] == '-' - p = p[1:] - for stringslite.HasPrefix(p, " ") || stringslite.HasPrefix(p, "\t") { - p = p[1:] - } - } - var n int64 - switch { - case stringslite.HasPrefix(p, "0x"), stringslite.HasPrefix(p, "0X"): - p = p[2:] - for ; len(p) > 0; p = p[1:] { - if '0' <= p[0] && p[0] <= '9' { - n = n*16 + int64(p[0]-'0') - } else if 'a' <= p[0] && p[0] <= 'f' { - n = n*16 + int64(p[0]-'a'+10) - } else if 'A' <= p[0] && p[0] <= 'F' { - n = n*16 + int64(p[0]-'A'+10) - } else { - break - } - } - case stringslite.HasPrefix(p, "0"): - for ; len(p) > 0 && '0' <= p[0] && p[0] <= '7'; p = p[1:] { - n = n*8 + int64(p[0]-'0') - } - default: - for ; len(p) > 0 && '0' <= p[0] && p[0] <= '9'; p = p[1:] { - n = n*10 + int64(p[0]-'0') - } - } - if neg { - n = -n - } - return n -} - -type sigset struct{} - -// Called to initialize a new m (including the bootstrap m). -// Called on the parent thread (main thread in case of bootstrap), can allocate memory. -func mpreinit(mp *m) { - // Initialize stack and goroutine for note handling. - mp.gsignal = malg(32 * 1024) - mp.gsignal.m = mp - mp.notesig = (*int8)(mallocgc(_ERRMAX, nil, true)) - // Initialize stack for handling strings from the - // errstr system call, as used in package syscall. - mp.errstr = (*byte)(mallocgc(_ERRMAX, nil, true)) -} - -func sigsave(p *sigset) { -} - -func msigrestore(sigmask sigset) { -} - -//go:nosplit -//go:nowritebarrierrec -func clearSignalHandlers() { -} - -func sigblock(exiting bool) { -} - -// Called to initialize a new m (including the bootstrap m). -// Called on the new thread, cannot allocate memory. -func minit() { - if atomic.Load(&exiting) != 0 { - exits(&emptystatus[0]) - } - // Mask all SSE floating-point exceptions - // when running on the 64-bit kernel. - setfpmasks() -} - -// Called from dropm to undo the effect of an minit. -func unminit() { -} - -// Called from mexit, but not from dropm, to undo the effect of thread-owned -// resources in minit, semacreate, or elsewhere. Do not take locks after calling this. -// -// This always runs without a P, so //go:nowritebarrierrec is required. -// -//go:nowritebarrierrec -func mdestroy(mp *m) { -} - -var sysstat = []byte("/dev/sysstat\x00") - -func getCPUCount() int32 { - var buf [2048]byte - fd := open(&sysstat[0], _OREAD|_OCEXEC, 0) - if fd < 0 { - return 1 - } - ncpu := int32(0) - for { - n := read(fd, unsafe.Pointer(&buf), int32(len(buf))) - if n <= 0 { - break - } - for i := int32(0); i < n; i++ { - if buf[i] == '\n' { - ncpu++ - } - } - } - closefd(fd) - if ncpu == 0 { - ncpu = 1 - } - return ncpu -} - -var devswap = []byte("/dev/swap\x00") -var pagesize = []byte(" pagesize\n") - -func getPageSize() uintptr { - var buf [2048]byte - var pos int - fd := open(&devswap[0], _OREAD|_OCEXEC, 0) - if fd < 0 { - // There's not much we can do if /dev/swap doesn't - // exist. However, nothing in the memory manager uses - // this on Plan 9, so it also doesn't really matter. - return minPhysPageSize - } - for pos < len(buf) { - n := read(fd, unsafe.Pointer(&buf[pos]), int32(len(buf)-pos)) - if n <= 0 { - break - } - pos += int(n) - } - closefd(fd) - text := buf[:pos] - // Find "<n> pagesize" line. - bol := 0 - for i, c := range text { - if c == '\n' { - bol = i + 1 - } - if bytesHasPrefix(text[i:], pagesize) { - // Parse number at the beginning of this line. - return uintptr(_atoi(text[bol:])) - } - } - // Again, the page size doesn't really matter, so use a fallback. - return minPhysPageSize -} - -func bytesHasPrefix(s, prefix []byte) bool { - if len(s) < len(prefix) { - return false - } - for i, p := range prefix { - if s[i] != p { - return false - } - } - return true -} - -var pid = []byte("#c/pid\x00") - -func getpid() uint64 { - var b [20]byte - fd := open(&pid[0], 0, 0) - if fd >= 0 { - read(fd, unsafe.Pointer(&b), int32(len(b))) - closefd(fd) - } - c := b[:] - for c[0] == ' ' || c[0] == '\t' { - c = c[1:] - } - return uint64(_atoi(c)) -} - -var ( - bintimeFD int32 = -1 - - bintimeDev = []byte("/dev/bintime\x00") - randomDev = []byte("/dev/random\x00") -) - -func osinit() { - physPageSize = getPageSize() - initBloc() - numCPUStartup = getCPUCount() - getg().m.procid = getpid() - - fd := open(&bintimeDev[0], _OREAD|_OCEXEC, 0) - if fd < 0 { - fatal("cannot open /dev/bintime") - } - bintimeFD = fd - - // Move fd high up, to avoid conflicts with smaller ones - // that programs might hard code, and to make exec's job easier. - // Plan 9 allocates chunks of DELTAFD=20 fds in a row, - // so 18 is near the top of what's possible. - if bintimeFD < 18 { - if dupfd(bintimeFD, 18) < 0 { - fatal("cannot dup /dev/bintime onto 18") - } - closefd(bintimeFD) - bintimeFD = 18 - } -} - -//go:nosplit -func crash() { - notify(nil) - *(*int)(nil) = 0 -} - -// Don't read from /dev/random, since this device can only -// return a few hundred bits a second and would slow creation -// of Go processes down significantly. -// -//go:nosplit -func readRandom(r []byte) int { - return 0 -} - -func initsig(preinit bool) { - if !preinit { - notify(unsafe.Pointer(abi.FuncPCABI0(sigtramp))) - } -} - -//go:nosplit -func osyield() { - sleep(0) -} - -//go:nosplit -func osyield_no_g() { - osyield() -} - -//go:nosplit -func usleep(µs uint32) { - ms := int32(µs / 1000) - if ms == 0 { - ms = 1 - } - sleep(ms) -} - -//go:nosplit -func usleep_no_g(usec uint32) { - usleep(usec) -} - -var goexits = []byte("go: exit ") -var emptystatus = []byte("\x00") -var exiting uint32 - -func goexitsall(status *byte) { - var buf [_ERRMAX]byte - if !atomic.Cas(&exiting, 0, 1) { - return - } - getg().m.locks++ - n := copy(buf[:], goexits) - n = copy(buf[n:], gostringnocopy(status)) - pid := getpid() - for mp := (*m)(atomic.Loadp(unsafe.Pointer(&allm))); mp != nil; mp = mp.alllink { - if mp.procid != 0 && mp.procid != pid { - postnote(mp.procid, buf[:]) - } - } - getg().m.locks-- -} - -var procdir = []byte("/proc/") -var notefile = []byte("/note\x00") - -func postnote(pid uint64, msg []byte) int { - var buf [128]byte - var tmp [32]byte - n := copy(buf[:], procdir) - n += copy(buf[n:], itoa(tmp[:], pid)) - copy(buf[n:], notefile) - fd := open(&buf[0], _OWRITE, 0) - if fd < 0 { - return -1 - } - len := findnull(&msg[0]) - if write1(uintptr(fd), unsafe.Pointer(&msg[0]), int32(len)) != int32(len) { - closefd(fd) - return -1 - } - closefd(fd) - return 0 -} - -//go:nosplit -func exit(e int32) { - var status []byte - if e == 0 { - status = emptystatus - } else { - // build error string - var tmp [32]byte - sl := itoa(tmp[:len(tmp)-1], uint64(e)) - // Don't append, rely on the existing data being zero. - status = sl[:len(sl)+1] - } - goexitsall(&status[0]) - exits(&status[0]) -} - -// May run with m.p==nil, so write barriers are not allowed. -// -//go:nowritebarrier -func newosproc(mp *m) { - if false { - print("newosproc mp=", mp, " ostk=", &mp, "\n") - } - pid := rfork(_RFPROC | _RFMEM | _RFNOWAIT) - if pid < 0 { - throw("newosproc: rfork failed") - } - if pid == 0 { - tstart_plan9(mp) - } -} - -func exitThread(wait *atomic.Uint32) { - // We should never reach exitThread on Plan 9 because we let - // the OS clean up threads. - throw("exitThread") -} - -//go:nosplit -func semacreate(mp *m) { -} - -//go:nosplit -func semasleep(ns int64) int { - gp := getg() - if ns >= 0 { - ms := timediv(ns, 1000000, nil) - if ms == 0 { - ms = 1 - } - ret := plan9_tsemacquire(&gp.m.waitsemacount, ms) - if ret == 1 { - return 0 // success - } - return -1 // timeout or interrupted - } - for plan9_semacquire(&gp.m.waitsemacount, 1) < 0 { - // interrupted; try again (c.f. lock_sema.go) - } - return 0 // success -} - -//go:nosplit -func semawakeup(mp *m) { - plan9_semrelease(&mp.waitsemacount, 1) -} - -//go:nosplit -func read(fd int32, buf unsafe.Pointer, n int32) int32 { - return pread(fd, buf, n, -1) -} - -//go:nosplit -func write1(fd uintptr, buf unsafe.Pointer, n int32) int32 { - return pwrite(int32(fd), buf, n, -1) -} - -var _badsignal = []byte("runtime: signal received on thread not created by Go.\n") - -// This runs on a foreign stack, without an m or a g. No stack split. -// -//go:nosplit -func badsignal2() { - pwrite(2, unsafe.Pointer(&_badsignal[0]), int32(len(_badsignal)), -1) - exits(&_badsignal[0]) -} - -func raisebadsignal(sig uint32) { - badsignal2() -} - -func _atoi(b []byte) int { - n := 0 - for len(b) > 0 && '0' <= b[0] && b[0] <= '9' { - n = n*10 + int(b[0]) - '0' - b = b[1:] - } - return n -} - -func signame(sig uint32) string { - if sig >= uint32(len(sigtable)) { - return "" - } - return sigtable[sig].name -} - -const preemptMSupported = false - -func preemptM(mp *m) { - // Not currently supported. - // - // TODO: Use a note like we use signals on POSIX OSes -} - -//go:nosplit -func readtime(t *uint64, min, n int) int { - if bintimeFD < 0 { - fatal("/dev/bintime not opened") - } - const uint64size = 8 - r := pread(bintimeFD, unsafe.Pointer(t), int32(n*uint64size), 0) - if int(r) < min*uint64size { - fatal("cannot read /dev/bintime") - } - return int(r) / uint64size -} - -// timesplit returns u/1e9, u%1e9 -func timesplit(u uint64) (sec int64, nsec int32) - -func frombe(u uint64) uint64 { - b := (*[8]byte)(unsafe.Pointer(&u)) - return byteorder.BEUint64(b[:]) -} - -//go:nosplit -func nanotime1() int64 { - var t [4]uint64 - if readtime(&t[0], 1, 4) == 4 { - // long read indicates new kernel sending monotonic time - // (https://github.com/rsc/plan9/commit/baf076425). - return int64(frombe(t[3])) - } - // fall back to unix time - return int64(frombe(t[0])) -} - -//go:nosplit -func walltime() (sec int64, nsec int32) { - var t [1]uint64 - readtime(&t[0], 1, 1) - return timesplit(frombe(t[0])) -} |
