1// Copyright 2014 The Go Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style 3// license that can be found in the LICENSE file. 4 5package runtime 6 7import "unsafe" 8 9type mOS struct { 10 unused byte 11} 12 13//go:noescape 14//extern umtx_sleep 15func sys_umtx_sleep(addr *uint32, val, timeout int32) int32 16 17//go:noescape 18//extern umtx_wakeup 19func sys_umtx_wakeup(addr *uint32, val int32) int32 20 21//go:nosplit 22func futexsleep(addr *uint32, val uint32, ns int64) { 23 systemstack(func() { 24 futexsleep1(addr, val, ns) 25 }) 26} 27 28func futexsleep1(addr *uint32, val uint32, ns int64) { 29 var timeout int32 30 if ns >= 0 { 31 // The timeout is specified in microseconds - ensure that we 32 // do not end up dividing to zero, which would put us to sleep 33 // indefinitely... 34 timeout = timediv(ns, 1000, nil) 35 if timeout == 0 { 36 timeout = 1 37 } 38 } 39 40 // sys_umtx_sleep will return EWOULDBLOCK (EAGAIN) when the timeout 41 // expires or EBUSY if the mutex value does not match. 42 ret := sys_umtx_sleep(addr, int32(val), timeout) 43 if ret >= 0 || ret == -_EINTR || ret == -_EAGAIN || ret == -_EBUSY { 44 return 45 } 46 47 print("umtx_sleep addr=", addr, " val=", val, " ret=", ret, "\n") 48 *(*int32)(unsafe.Pointer(uintptr(0x1005))) = 0x1005 49} 50 51//go:nosplit 52func futexwakeup(addr *uint32, cnt uint32) { 53 ret := sys_umtx_wakeup(addr, int32(cnt)) 54 if ret >= 0 { 55 return 56 } 57 58 systemstack(func() { 59 print("umtx_wake_addr=", addr, " ret=", ret, "\n") 60 *(*int32)(unsafe.Pointer(uintptr(0x1006))) = 0x1006 61 }) 62} 63