Copyright 2009 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 

type mOS struct {
	initialized bool
	mutex       pthreadmutex
	cond        pthreadcond
	count       int
}

func ( string) {
	println(, "not implemented")
	*(*int)(unsafe.Pointer(uintptr(1231))) = 1231
}
go:nosplit
func ( *m) {
	if .initialized {
		return
	}
	.initialized = true
	if  := pthread_mutex_init(&.mutex, nil);  != 0 {
		throw("pthread_mutex_init")
	}
	if  := pthread_cond_init(&.cond, nil);  != 0 {
		throw("pthread_cond_init")
	}
}
go:nosplit
func ( int64) int32 {
	var  int64
	if  >= 0 {
		 = nanotime()
	}
	 := getg().m
	pthread_mutex_lock(&.mutex)
	for {
		if .count > 0 {
			.count--
			pthread_mutex_unlock(&.mutex)
			return 0
		}
		if  >= 0 {
			 := nanotime() - 
			if  >=  {
				pthread_mutex_unlock(&.mutex)
				return -1
			}
			var  timespec
			.setNsec( - )
			 := pthread_cond_timedwait_relative_np(&.cond, &.mutex, &)
			if  == _ETIMEDOUT {
				pthread_mutex_unlock(&.mutex)
				return -1
			}
		} else {
			pthread_cond_wait(&.cond, &.mutex)
		}
	}
}
go:nosplit
The read and write file descriptors used by the sigNote functions.
sigNoteSetup initializes an async-signal-safe note. The current implementation of notes on Darwin is not async-signal-safe, because the functions pthread_mutex_lock, pthread_cond_signal, and pthread_mutex_unlock, called by semawakeup, are not async-signal-safe. There is only one case where we need to wake up a note from a signal handler: the sigsend function. The signal handler code does not require all the features of notes: it does not need to do a timed wait. This is a separate implementation of notes, based on a pipe, that does not support timed waits but is async-signal-safe.
func (*note) {
	if sigNoteRead != 0 || sigNoteWrite != 0 {
		throw("duplicate sigNoteSetup")
	}
	var  int32
	sigNoteRead, sigNoteWrite,  = pipe()
	if  != 0 {
		throw("pipe failed")
	}
	closeonexec(sigNoteRead)
	closeonexec(sigNoteWrite)
Make the write end of the pipe non-blocking, so that if the pipe buffer is somehow full we will not block in the signal handler. Leave the read end of the pipe blocking so that we will block in sigNoteSleep.
sigNoteWakeup wakes up a thread sleeping on a note created by sigNoteSetup.
sigNoteSleep waits for a note created by sigNoteSetup to be woken.
BSD interface for threading.
pthread_create delayed until end of goenvs so that we can look at the environment first.

	ncpu = getncpu()
	physPageSize = getPageSize()
}

func ( []byte) (int32, int32) {
	 := int32(0)
	 := unsafe.Sizeof()
	 := sysctlbyname(&[0], (*byte)(unsafe.Pointer(&)), &, nil, 0)
	return , 
}
go:linkname internal_cpu_getsysctlbyname internal/cpu.getsysctlbyname
func ( []byte) (int32, int32) {
	return sysctlbynameInt32()
}

const (
	_CTL_HW      = 6
	_HW_NCPU     = 3
	_HW_PAGESIZE = 7
)

Use sysctl to fetch hw.ncpu.
	 := [2]uint32{_CTL_HW, _HW_NCPU}
	 := uint32(0)
	 := unsafe.Sizeof()
	 := sysctl(&[0], 2, (*byte)(unsafe.Pointer(&)), &, nil, 0)
	if  >= 0 && int32() > 0 {
		return int32()
	}
	return 1
}

Use sysctl to fetch hw.pagesize.
	 := [2]uint32{_CTL_HW, _HW_PAGESIZE}
	 := uint32(0)
	 := unsafe.Sizeof()
	 := sysctl(&[0], 2, (*byte)(unsafe.Pointer(&)), &, nil, 0)
	if  >= 0 && int32() > 0 {
		return uintptr()
	}
	return 0
}

var urandom_dev = []byte("/dev/urandom\x00")
go:nosplit
func ( []byte) {
	 := open(&urandom_dev[0], 0 /* O_RDONLY */, 0)
	 := read(, unsafe.Pointer(&[0]), int32(len()))
	closefd()
	extendRandom(, int())
}

func () {
	goenvs_unix()
}
May run with m.p==nil, so write barriers are not allowed.go:nowritebarrierrec
func ( *m) {
	 := unsafe.Pointer(.g0.stack.hi)
	if false {
		print("newosproc stk=", , " m=", , " g=", .g0, " id=", .id, " ostk=", &, "\n")
	}
Initialize an attribute object.
	var  pthreadattr
	var  int32
	 = pthread_attr_init(&)
	if  != 0 {
		write(2, unsafe.Pointer(&failthreadcreate[0]), int32(len(failthreadcreate)))
		exit(1)
	}
Find out OS stack size for our own stack guard.
	var  uintptr
	if pthread_attr_getstacksize(&, &) != 0 {
		write(2, unsafe.Pointer(&failthreadcreate[0]), int32(len(failthreadcreate)))
		exit(1)
	}
	.g0.stack.hi =  // for mstart
Tell the pthread library we won't join with this thread.
Finally, create the thread. It starts at mstart_stub, which does some low-level setup and then calls mstart.
glue code to call mstart from pthread_create.
func ()
newosproc0 is a version of newosproc that can be called before the runtime is initialized. This function is not safe to use after initialization as it does not pass an M as fnarg.go:nosplit
Initialize an attribute object.
	var  pthreadattr
	var  int32
	 = pthread_attr_init(&)
	if  != 0 {
		write(2, unsafe.Pointer(&failthreadcreate[0]), int32(len(failthreadcreate)))
		exit(1)
	}
The caller passes in a suggested stack size, from when we allocated the stack and thread ourselves, without libpthread. Now that we're using libpthread, we use the OS default stack size instead of the suggestion. Find out that stack size for our own stack guard.
	if pthread_attr_getstacksize(&, &) != 0 {
		write(2, unsafe.Pointer(&failthreadcreate[0]), int32(len(failthreadcreate)))
		exit(1)
	}
	g0.stack.hi =  // for mstart
	memstats.stacks_sys.add(int64())
Tell the pthread library we won't join with this thread.
Finally, create the thread. It starts at mstart_stub, which does some low-level setup and then calls mstart.
	var  sigset
	sigprocmask(_SIG_SETMASK, &sigset_all, &)
	 = pthread_create(&, , nil)
	sigprocmask(_SIG_SETMASK, &, nil)
	if  != 0 {
		write(2, unsafe.Pointer(&failthreadcreate[0]), int32(len(failthreadcreate)))
		exit(1)
	}
}

var failallocatestack = []byte("runtime: failed to allocate stack for the new OS thread\n")
var failthreadcreate = []byte("runtime: failed to create new OS thread\n")
Called to do synchronous initialization of Go code built with -buildmode=c-archive or -buildmode=c-shared. None of the Go runtime is initialized.go:nosplitgo:nowritebarrierrec
func () {
	initsig(true)
}
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 ( *m) {
	.gsignal = malg(32 * 1024) // OS X wants >= 8K
	.gsignal.m = 
mlock the signal stack to work around a kernel bug where it may SIGILL when the signal stack is not faulted in while a signal arrives. See issue 42774.
Called to initialize a new m (including the bootstrap m). Called on the new thread, cannot allocate memory.
iOS does not support alternate signal stack. The signal handler handles it directly.
	if !(GOOS == "ios" && GOARCH == "arm64") {
		minitSignalStack()
	}
	minitSignalMask()
	getg().m.procid = uint64(pthread_self())
}
Called from dropm to undo the effect of an minit.go:nosplit
iOS does not support alternate signal stack. See minit.
	if !(GOOS == "ios" && GOARCH == "arm64") {
		unminitSignals()
	}
}
Called from exitm, but not from drop, to undo the effect of thread-owned resources in minit, semacreate, or elsewhere. Do not take locks after calling this.
func ( *m) {
}
go:nosplit
func () {
	usleep(1)
}

const (
	_NSIG        = 32
	_SI_USER     = 0 /* empirically true, but not what headers say */
	_SIG_BLOCK   = 1
	_SIG_UNBLOCK = 2
	_SIG_SETMASK = 3
	_SS_DISABLE  = 4
)
extern SigTabTT runtimeĀ·sigtab[];

type sigset uint32

var sigset_all = ^sigset(0)
go:nosplitgo:nowritebarrierrec
func ( uint32,  uintptr) {
	var  usigactiont
	.sa_flags = _SA_SIGINFO | _SA_ONSTACK | _SA_RESTART
	.sa_mask = ^uint32(0)
	if  == funcPC(sighandler) {
		if iscgo {
			 = funcPC(cgoSigtramp)
		} else {
			 = funcPC(sigtramp)
		}
	}
	*(*uintptr)(unsafe.Pointer(&.__sigaction_u)) = 
	sigaction(, &, nil)
}
sigtramp is the callback from libc when a signal is received. It is called with the C calling convention.
func ()
func ()
go:nosplitgo:nowritebarrierrec
func ( uint32) {
	var  usigactiont
	sigaction(, nil, &)
	 := *(*uintptr)(unsafe.Pointer(&.__sigaction_u))
	if .sa_flags&_SA_ONSTACK != 0 {
		return
	}
	var  usigactiont
	*(*uintptr)(unsafe.Pointer(&.__sigaction_u)) = 
	.sa_mask = .sa_mask
	.sa_flags = .sa_flags | _SA_ONSTACK
	sigaction(, &, nil)
}
go:nosplitgo:nowritebarrierrec
func ( uint32) uintptr {
	var  usigactiont
	sigaction(, nil, &)
	return *(*uintptr)(unsafe.Pointer(&.__sigaction_u))
}
setSignaltstackSP sets the ss_sp field of a stackt.go:nosplit
func ( *stackt,  uintptr) {
	*(*uintptr)(unsafe.Pointer(&.ss_sp)) = 
}
go:nosplitgo:nowritebarrierrec
func ( *sigset,  int) {
	* |= 1 << (uint32() - 1)
}

func ( *sigset,  int) {
	* &^= 1 << (uint32() - 1)
}
go:linkname executablePath os.executablePath
skip over argv, envv and the first string will be the path
	 :=  + 1
	for argv_index(, ) != nil {
		++
	}
	executablePath = gostringnocopy(argv_index(, +1))
strip "executable_path=" prefix if available, it's added after OS X 10.11.
	const  = "executable_path="
	if len(executablePath) > len() && executablePath[:len()] ==  {
		executablePath = executablePath[len():]
	}
}

func ( *m,  int) {
	pthread_kill(pthread(.procid), uint32())