Source file src/runtime/os3_solaris.go

     1  // Copyright 2011 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  
     5  package runtime
     6  
     7  import (
     8  	"internal/abi"
     9  	"internal/goarch"
    10  	"internal/runtime/atomic"
    11  	"unsafe"
    12  )
    13  
    14  //go:cgo_export_dynamic runtime.end _end
    15  //go:cgo_export_dynamic runtime.etext _etext
    16  //go:cgo_export_dynamic runtime.edata _edata
    17  
    18  //go:cgo_import_dynamic libc____errno ___errno "libc.so"
    19  //go:cgo_import_dynamic libc_clock_gettime clock_gettime "libc.so"
    20  //go:cgo_import_dynamic libc_exit _exit "libc.so"
    21  //go:cgo_import_dynamic libc_getcontext getcontext "libc.so"
    22  //go:cgo_import_dynamic libc_kill kill "libc.so"
    23  //go:cgo_import_dynamic libc_madvise madvise "libc.so"
    24  //go:cgo_import_dynamic libc_malloc malloc "libc.so"
    25  //go:cgo_import_dynamic libc_mmap mmap "libc.so"
    26  //go:cgo_import_dynamic libc_munmap munmap "libc.so"
    27  //go:cgo_import_dynamic libc_open open "libc.so"
    28  //go:cgo_import_dynamic libc_pthread_attr_destroy pthread_attr_destroy "libc.so"
    29  //go:cgo_import_dynamic libc_pthread_attr_getstack pthread_attr_getstack "libc.so"
    30  //go:cgo_import_dynamic libc_pthread_attr_init pthread_attr_init "libc.so"
    31  //go:cgo_import_dynamic libc_pthread_attr_setdetachstate pthread_attr_setdetachstate "libc.so"
    32  //go:cgo_import_dynamic libc_pthread_attr_setstack pthread_attr_setstack "libc.so"
    33  //go:cgo_import_dynamic libc_pthread_create pthread_create "libc.so"
    34  //go:cgo_import_dynamic libc_pthread_self pthread_self "libc.so"
    35  //go:cgo_import_dynamic libc_pthread_kill pthread_kill "libc.so"
    36  //go:cgo_import_dynamic libc_raise raise "libc.so"
    37  //go:cgo_import_dynamic libc_read read "libc.so"
    38  //go:cgo_import_dynamic libc_select select "libc.so"
    39  //go:cgo_import_dynamic libc_sched_yield sched_yield "libc.so"
    40  //go:cgo_import_dynamic libc_sem_init sem_init "libc.so"
    41  //go:cgo_import_dynamic libc_sem_post sem_post "libc.so"
    42  //go:cgo_import_dynamic libc_sem_reltimedwait_np sem_reltimedwait_np "libc.so"
    43  //go:cgo_import_dynamic libc_sem_wait sem_wait "libc.so"
    44  //go:cgo_import_dynamic libc_setitimer setitimer "libc.so"
    45  //go:cgo_import_dynamic libc_sigaction sigaction "libc.so"
    46  //go:cgo_import_dynamic libc_sigaltstack sigaltstack "libc.so"
    47  //go:cgo_import_dynamic libc_sigprocmask sigprocmask "libc.so"
    48  //go:cgo_import_dynamic libc_sysconf sysconf "libc.so"
    49  //go:cgo_import_dynamic libc_usleep usleep "libc.so"
    50  //go:cgo_import_dynamic libc_write write "libc.so"
    51  //go:cgo_import_dynamic libc_pipe2 pipe2 "libc.so"
    52  
    53  //go:linkname libc____errno libc____errno
    54  //go:linkname libc_clock_gettime libc_clock_gettime
    55  //go:linkname libc_exit libc_exit
    56  //go:linkname libc_getcontext libc_getcontext
    57  //go:linkname libc_kill libc_kill
    58  //go:linkname libc_madvise libc_madvise
    59  //go:linkname libc_malloc libc_malloc
    60  //go:linkname libc_mmap libc_mmap
    61  //go:linkname libc_munmap libc_munmap
    62  //go:linkname libc_open libc_open
    63  //go:linkname libc_pthread_attr_destroy libc_pthread_attr_destroy
    64  //go:linkname libc_pthread_attr_getstack libc_pthread_attr_getstack
    65  //go:linkname libc_pthread_attr_init libc_pthread_attr_init
    66  //go:linkname libc_pthread_attr_setdetachstate libc_pthread_attr_setdetachstate
    67  //go:linkname libc_pthread_attr_setstack libc_pthread_attr_setstack
    68  //go:linkname libc_pthread_create libc_pthread_create
    69  //go:linkname libc_pthread_self libc_pthread_self
    70  //go:linkname libc_pthread_kill libc_pthread_kill
    71  //go:linkname libc_raise libc_raise
    72  //go:linkname libc_read libc_read
    73  //go:linkname libc_select libc_select
    74  //go:linkname libc_sched_yield libc_sched_yield
    75  //go:linkname libc_sem_init libc_sem_init
    76  //go:linkname libc_sem_post libc_sem_post
    77  //go:linkname libc_sem_reltimedwait_np libc_sem_reltimedwait_np
    78  //go:linkname libc_sem_wait libc_sem_wait
    79  //go:linkname libc_setitimer libc_setitimer
    80  //go:linkname libc_sigaction libc_sigaction
    81  //go:linkname libc_sigaltstack libc_sigaltstack
    82  //go:linkname libc_sigprocmask libc_sigprocmask
    83  //go:linkname libc_sysconf libc_sysconf
    84  //go:linkname libc_usleep libc_usleep
    85  //go:linkname libc_write libc_write
    86  //go:linkname libc_pipe2 libc_pipe2
    87  
    88  var (
    89  	libc____errno,
    90  	libc_clock_gettime,
    91  	libc_exit,
    92  	libc_getcontext,
    93  	libc_kill,
    94  	libc_madvise,
    95  	libc_malloc,
    96  	libc_mmap,
    97  	libc_munmap,
    98  	libc_open,
    99  	libc_pthread_attr_destroy,
   100  	libc_pthread_attr_getstack,
   101  	libc_pthread_attr_init,
   102  	libc_pthread_attr_setdetachstate,
   103  	libc_pthread_attr_setstack,
   104  	libc_pthread_create,
   105  	libc_pthread_self,
   106  	libc_pthread_kill,
   107  	libc_raise,
   108  	libc_read,
   109  	libc_sched_yield,
   110  	libc_select,
   111  	libc_sem_init,
   112  	libc_sem_post,
   113  	libc_sem_reltimedwait_np,
   114  	libc_sem_wait,
   115  	libc_setitimer,
   116  	libc_sigaction,
   117  	libc_sigaltstack,
   118  	libc_sigprocmask,
   119  	libc_sysconf,
   120  	libc_usleep,
   121  	libc_write,
   122  	libc_pipe2 libcFunc
   123  )
   124  
   125  var sigset_all = sigset{[4]uint32{^uint32(0), ^uint32(0), ^uint32(0), ^uint32(0)}}
   126  
   127  func getPageSize() uintptr {
   128  	n := int32(sysconf(__SC_PAGESIZE))
   129  	if n <= 0 {
   130  		return 0
   131  	}
   132  	return uintptr(n)
   133  }
   134  
   135  func osinit() {
   136  	// Call miniterrno so that we can safely make system calls
   137  	// before calling minit on m0.
   138  	asmcgocall(unsafe.Pointer(abi.FuncPCABI0(miniterrno)), unsafe.Pointer(&libc____errno))
   139  
   140  	numCPUStartup = getCPUCount()
   141  	if physPageSize == 0 {
   142  		physPageSize = getPageSize()
   143  	}
   144  }
   145  
   146  func tstart_sysvicall(newm *m) uint32
   147  
   148  // May run with m.p==nil, so write barriers are not allowed.
   149  //
   150  //go:nowritebarrier
   151  func newosproc(mp *m) {
   152  	var (
   153  		attr pthreadattr
   154  		oset sigset
   155  		tid  pthread
   156  		ret  int32
   157  		size uint64
   158  	)
   159  
   160  	if pthread_attr_init(&attr) != 0 {
   161  		throw("pthread_attr_init")
   162  	}
   163  	// Allocate a new 2MB stack.
   164  	if pthread_attr_setstack(&attr, 0, 0x200000) != 0 {
   165  		throw("pthread_attr_setstack")
   166  	}
   167  	// Read back the allocated stack.
   168  	if pthread_attr_getstack(&attr, unsafe.Pointer(&mp.g0.stack.hi), &size) != 0 {
   169  		throw("pthread_attr_getstack")
   170  	}
   171  	mp.g0.stack.lo = mp.g0.stack.hi - uintptr(size)
   172  	if pthread_attr_setdetachstate(&attr, _PTHREAD_CREATE_DETACHED) != 0 {
   173  		throw("pthread_attr_setdetachstate")
   174  	}
   175  
   176  	// Disable signals during create, so that the new thread starts
   177  	// with signals disabled. It will enable them in minit.
   178  	sigprocmask(_SIG_SETMASK, &sigset_all, &oset)
   179  	ret = retryOnEAGAIN(func() int32 {
   180  		return pthread_create(&tid, &attr, abi.FuncPCABI0(tstart_sysvicall), unsafe.Pointer(mp))
   181  	})
   182  	sigprocmask(_SIG_SETMASK, &oset, nil)
   183  	if ret != 0 {
   184  		print("runtime: failed to create new OS thread (have ", mcount(), " already; errno=", ret, ")\n")
   185  		if ret == _EAGAIN {
   186  			println("runtime: may need to increase max user processes (ulimit -u)")
   187  		}
   188  		throw("newosproc")
   189  	}
   190  }
   191  
   192  func exitThread(wait *atomic.Uint32) {
   193  	// We should never reach exitThread on Solaris because we let
   194  	// libc clean up threads.
   195  	throw("exitThread")
   196  }
   197  
   198  var urandom_dev = []byte("/dev/urandom\x00")
   199  
   200  //go:nosplit
   201  func readRandom(r []byte) int {
   202  	fd := open(&urandom_dev[0], 0 /* O_RDONLY */, 0)
   203  	n := read(fd, unsafe.Pointer(&r[0]), int32(len(r)))
   204  	closefd(fd)
   205  	return int(n)
   206  }
   207  
   208  func goenvs() {
   209  	goenvs_unix()
   210  }
   211  
   212  // Called to initialize a new m (including the bootstrap m).
   213  // Called on the parent thread (main thread in case of bootstrap), can allocate memory.
   214  func mpreinit(mp *m) {
   215  	mp.gsignal = malg(32 * 1024)
   216  	mp.gsignal.m = mp
   217  }
   218  
   219  func miniterrno()
   220  
   221  // Called to initialize a new m (including the bootstrap m).
   222  // Called on the new thread, cannot allocate memory.
   223  func minit() {
   224  	asmcgocall(unsafe.Pointer(abi.FuncPCABI0(miniterrno)), unsafe.Pointer(&libc____errno))
   225  
   226  	minitSignals()
   227  
   228  	getg().m.procid = uint64(pthread_self())
   229  }
   230  
   231  // Called from dropm to undo the effect of an minit.
   232  func unminit() {
   233  	unminitSignals()
   234  	getg().m.procid = 0
   235  }
   236  
   237  // Called from mexit, but not from dropm, to undo the effect of thread-owned
   238  // resources in minit, semacreate, or elsewhere. Do not take locks after calling this.
   239  //
   240  // This always runs without a P, so //go:nowritebarrierrec is required.
   241  //
   242  //go:nowritebarrierrec
   243  func mdestroy(mp *m) {
   244  }
   245  
   246  func sigtramp()
   247  
   248  //go:nosplit
   249  //go:nowritebarrierrec
   250  func setsig(i uint32, fn uintptr) {
   251  	var sa sigactiont
   252  
   253  	sa.sa_flags = _SA_SIGINFO | _SA_ONSTACK | _SA_RESTART
   254  	sa.sa_mask = sigset_all
   255  	if fn == abi.FuncPCABIInternal(sighandler) { // abi.FuncPCABIInternal(sighandler) matches the callers in signal_unix.go
   256  		fn = abi.FuncPCABI0(sigtramp)
   257  	}
   258  	*((*uintptr)(unsafe.Pointer(&sa._funcptr))) = fn
   259  	sigaction(i, &sa, nil)
   260  }
   261  
   262  //go:nosplit
   263  //go:nowritebarrierrec
   264  func setsigstack(i uint32) {
   265  	var sa sigactiont
   266  	sigaction(i, nil, &sa)
   267  	if sa.sa_flags&_SA_ONSTACK != 0 {
   268  		return
   269  	}
   270  	sa.sa_flags |= _SA_ONSTACK
   271  	sigaction(i, &sa, nil)
   272  }
   273  
   274  //go:nosplit
   275  //go:nowritebarrierrec
   276  func getsig(i uint32) uintptr {
   277  	var sa sigactiont
   278  	sigaction(i, nil, &sa)
   279  	return *((*uintptr)(unsafe.Pointer(&sa._funcptr)))
   280  }
   281  
   282  // setSignalstackSP sets the ss_sp field of a stackt.
   283  //
   284  //go:nosplit
   285  func setSignalstackSP(s *stackt, sp uintptr) {
   286  	*(*uintptr)(unsafe.Pointer(&s.ss_sp)) = sp
   287  }
   288  
   289  //go:nosplit
   290  //go:nowritebarrierrec
   291  func sigaddset(mask *sigset, i int) {
   292  	mask.__sigbits[(i-1)/32] |= 1 << ((uint32(i) - 1) & 31)
   293  }
   294  
   295  func sigdelset(mask *sigset, i int) {
   296  	mask.__sigbits[(i-1)/32] &^= 1 << ((uint32(i) - 1) & 31)
   297  }
   298  
   299  //go:nosplit
   300  func (c *sigctxt) fixsigcode(sig uint32) {
   301  }
   302  
   303  func setProcessCPUProfiler(hz int32) {
   304  	setProcessCPUProfilerTimer(hz)
   305  }
   306  
   307  func setThreadCPUProfiler(hz int32) {
   308  	setThreadCPUProfilerHz(hz)
   309  }
   310  
   311  //go:nosplit
   312  func validSIGPROF(mp *m, c *sigctxt) bool {
   313  	return true
   314  }
   315  
   316  //go:nosplit
   317  func semacreate(mp *m) {
   318  	if mp.waitsema != 0 {
   319  		return
   320  	}
   321  
   322  	var sem *semt
   323  
   324  	// Call libc's malloc rather than malloc. This will
   325  	// allocate space on the C heap. We can't call malloc
   326  	// here because it could cause a deadlock.
   327  	mp.libcall.fn = uintptr(unsafe.Pointer(&libc_malloc))
   328  	mp.libcall.n = 1
   329  	mp.scratch = mscratch{}
   330  	mp.scratch.v[0] = unsafe.Sizeof(*sem)
   331  	mp.libcall.args = uintptr(unsafe.Pointer(&mp.scratch))
   332  	asmcgocall(unsafe.Pointer(&asmsysvicall6x), unsafe.Pointer(&mp.libcall))
   333  	sem = (*semt)(unsafe.Pointer(mp.libcall.r1))
   334  	if sem_init(sem, 0, 0) != 0 {
   335  		throw("sem_init")
   336  	}
   337  	mp.waitsema = uintptr(unsafe.Pointer(sem))
   338  }
   339  
   340  //go:nosplit
   341  func semasleep(ns int64) int32 {
   342  	mp := getg().m
   343  	if ns >= 0 {
   344  		mp.ts.tv_sec = ns / 1000000000
   345  		mp.ts.tv_nsec = ns % 1000000000
   346  
   347  		mp.libcall.fn = uintptr(unsafe.Pointer(&libc_sem_reltimedwait_np))
   348  		mp.libcall.n = 2
   349  		mp.scratch = mscratch{}
   350  		mp.scratch.v[0] = mp.waitsema
   351  		mp.scratch.v[1] = uintptr(unsafe.Pointer(&mp.ts))
   352  		mp.libcall.args = uintptr(unsafe.Pointer(&mp.scratch))
   353  		asmcgocall(unsafe.Pointer(&asmsysvicall6x), unsafe.Pointer(&mp.libcall))
   354  		if *mp.perrno != 0 {
   355  			if *mp.perrno == _ETIMEDOUT || *mp.perrno == _EAGAIN || *mp.perrno == _EINTR {
   356  				return -1
   357  			}
   358  			throw("sem_reltimedwait_np")
   359  		}
   360  		return 0
   361  	}
   362  	for {
   363  		mp.libcall.fn = uintptr(unsafe.Pointer(&libc_sem_wait))
   364  		mp.libcall.n = 1
   365  		mp.scratch = mscratch{}
   366  		mp.scratch.v[0] = mp.waitsema
   367  		mp.libcall.args = uintptr(unsafe.Pointer(&mp.scratch))
   368  		asmcgocall(unsafe.Pointer(&asmsysvicall6x), unsafe.Pointer(&mp.libcall))
   369  		if mp.libcall.r1 == 0 {
   370  			break
   371  		}
   372  		if *mp.perrno == _EINTR {
   373  			continue
   374  		}
   375  		throw("sem_wait")
   376  	}
   377  	return 0
   378  }
   379  
   380  //go:nosplit
   381  func semawakeup(mp *m) {
   382  	if sem_post((*semt)(unsafe.Pointer(mp.waitsema))) != 0 {
   383  		throw("sem_post")
   384  	}
   385  }
   386  
   387  //go:nosplit
   388  func closefd(fd int32) int32 {
   389  	return int32(sysvicall1(&libc_close, uintptr(fd)))
   390  }
   391  
   392  //go:nosplit
   393  func exit(r int32) {
   394  	sysvicall1(&libc_exit, uintptr(r))
   395  }
   396  
   397  //go:nosplit
   398  func getcontext(context *ucontext) /* int32 */ {
   399  	sysvicall1(&libc_getcontext, uintptr(unsafe.Pointer(context)))
   400  }
   401  
   402  //go:nosplit
   403  func madvise(addr unsafe.Pointer, n uintptr, flags int32) {
   404  	sysvicall3(&libc_madvise, uintptr(addr), uintptr(n), uintptr(flags))
   405  }
   406  
   407  //go:nosplit
   408  func mmap(addr unsafe.Pointer, n uintptr, prot, flags, fd int32, off uint32) (unsafe.Pointer, int) {
   409  	p, err := doMmap(uintptr(addr), n, uintptr(prot), uintptr(flags), uintptr(fd), uintptr(off))
   410  	if p == ^uintptr(0) {
   411  		return nil, int(err)
   412  	}
   413  	return unsafe.Pointer(p), 0
   414  }
   415  
   416  //go:nosplit
   417  //go:cgo_unsafe_args
   418  func doMmap(addr, n, prot, flags, fd, off uintptr) (uintptr, uintptr) {
   419  	var libcall libcall
   420  	libcall.fn = uintptr(unsafe.Pointer(&libc_mmap))
   421  	libcall.n = 6
   422  	libcall.args = uintptr(noescape(unsafe.Pointer(&addr)))
   423  	asmcgocall(unsafe.Pointer(&asmsysvicall6x), unsafe.Pointer(&libcall))
   424  	return libcall.r1, libcall.err
   425  }
   426  
   427  //go:nosplit
   428  func munmap(addr unsafe.Pointer, n uintptr) {
   429  	sysvicall2(&libc_munmap, uintptr(addr), uintptr(n))
   430  }
   431  
   432  const (
   433  	_CLOCK_REALTIME  = 3
   434  	_CLOCK_MONOTONIC = 4
   435  )
   436  
   437  //go:nosplit
   438  func nanotime1() int64 {
   439  	var ts mts
   440  	sysvicall2(&libc_clock_gettime, _CLOCK_MONOTONIC, uintptr(unsafe.Pointer(&ts)))
   441  	return ts.tv_sec*1e9 + ts.tv_nsec
   442  }
   443  
   444  //go:nosplit
   445  func open(path *byte, mode, perm int32) int32 {
   446  	return int32(sysvicall3(&libc_open, uintptr(unsafe.Pointer(path)), uintptr(mode), uintptr(perm)))
   447  }
   448  
   449  func pthread_attr_destroy(attr *pthreadattr) int32 {
   450  	return int32(sysvicall1(&libc_pthread_attr_destroy, uintptr(unsafe.Pointer(attr))))
   451  }
   452  
   453  func pthread_attr_getstack(attr *pthreadattr, addr unsafe.Pointer, size *uint64) int32 {
   454  	return int32(sysvicall3(&libc_pthread_attr_getstack, uintptr(unsafe.Pointer(attr)), uintptr(addr), uintptr(unsafe.Pointer(size))))
   455  }
   456  
   457  func pthread_attr_init(attr *pthreadattr) int32 {
   458  	return int32(sysvicall1(&libc_pthread_attr_init, uintptr(unsafe.Pointer(attr))))
   459  }
   460  
   461  func pthread_attr_setdetachstate(attr *pthreadattr, state int32) int32 {
   462  	return int32(sysvicall2(&libc_pthread_attr_setdetachstate, uintptr(unsafe.Pointer(attr)), uintptr(state)))
   463  }
   464  
   465  func pthread_attr_setstack(attr *pthreadattr, addr uintptr, size uint64) int32 {
   466  	return int32(sysvicall3(&libc_pthread_attr_setstack, uintptr(unsafe.Pointer(attr)), uintptr(addr), uintptr(size)))
   467  }
   468  
   469  func pthread_create(thread *pthread, attr *pthreadattr, fn uintptr, arg unsafe.Pointer) int32 {
   470  	return int32(sysvicall4(&libc_pthread_create, uintptr(unsafe.Pointer(thread)), uintptr(unsafe.Pointer(attr)), uintptr(fn), uintptr(arg)))
   471  }
   472  
   473  func pthread_self() pthread {
   474  	return pthread(sysvicall0(&libc_pthread_self))
   475  }
   476  
   477  func signalM(mp *m, sig int) {
   478  	sysvicall2(&libc_pthread_kill, uintptr(pthread(mp.procid)), uintptr(sig))
   479  }
   480  
   481  //go:nosplit
   482  //go:nowritebarrierrec
   483  func raise(sig uint32) /* int32 */ {
   484  	sysvicall1(&libc_raise, uintptr(sig))
   485  }
   486  
   487  func raiseproc(sig uint32) /* int32 */ {
   488  	pid := sysvicall0(&libc_getpid)
   489  	sysvicall2(&libc_kill, pid, uintptr(sig))
   490  }
   491  
   492  //go:nosplit
   493  func read(fd int32, buf unsafe.Pointer, nbyte int32) int32 {
   494  	r1, err := sysvicall3Err(&libc_read, uintptr(fd), uintptr(buf), uintptr(nbyte))
   495  	if c := int32(r1); c >= 0 {
   496  		return c
   497  	}
   498  	return -int32(err)
   499  }
   500  
   501  //go:nosplit
   502  func sem_init(sem *semt, pshared int32, value uint32) int32 {
   503  	return int32(sysvicall3(&libc_sem_init, uintptr(unsafe.Pointer(sem)), uintptr(pshared), uintptr(value)))
   504  }
   505  
   506  //go:nosplit
   507  func sem_post(sem *semt) int32 {
   508  	return int32(sysvicall1(&libc_sem_post, uintptr(unsafe.Pointer(sem))))
   509  }
   510  
   511  //go:nosplit
   512  func sem_reltimedwait_np(sem *semt, timeout *timespec) int32 {
   513  	return int32(sysvicall2(&libc_sem_reltimedwait_np, uintptr(unsafe.Pointer(sem)), uintptr(unsafe.Pointer(timeout))))
   514  }
   515  
   516  //go:nosplit
   517  func sem_wait(sem *semt) int32 {
   518  	return int32(sysvicall1(&libc_sem_wait, uintptr(unsafe.Pointer(sem))))
   519  }
   520  
   521  func setitimer(which int32, value *itimerval, ovalue *itimerval) /* int32 */ {
   522  	sysvicall3(&libc_setitimer, uintptr(which), uintptr(unsafe.Pointer(value)), uintptr(unsafe.Pointer(ovalue)))
   523  }
   524  
   525  //go:nosplit
   526  //go:nowritebarrierrec
   527  func sigaction(sig uint32, act *sigactiont, oact *sigactiont) /* int32 */ {
   528  	sysvicall3(&libc_sigaction, uintptr(sig), uintptr(unsafe.Pointer(act)), uintptr(unsafe.Pointer(oact)))
   529  }
   530  
   531  //go:nosplit
   532  //go:nowritebarrierrec
   533  func sigaltstack(ss *stackt, oss *stackt) /* int32 */ {
   534  	sysvicall2(&libc_sigaltstack, uintptr(unsafe.Pointer(ss)), uintptr(unsafe.Pointer(oss)))
   535  }
   536  
   537  //go:nosplit
   538  //go:nowritebarrierrec
   539  func sigprocmask(how int32, set *sigset, oset *sigset) /* int32 */ {
   540  	sysvicall3(&libc_sigprocmask, uintptr(how), uintptr(unsafe.Pointer(set)), uintptr(unsafe.Pointer(oset)))
   541  }
   542  
   543  func sysconf(name int32) int64 {
   544  	return int64(sysvicall1(&libc_sysconf, uintptr(name)))
   545  }
   546  
   547  func usleep1(usec uint32)
   548  
   549  //go:nosplit
   550  func usleep_no_g(µs uint32) {
   551  	usleep1(µs)
   552  }
   553  
   554  //go:nosplit
   555  func usleep(µs uint32) {
   556  	usleep1(µs)
   557  }
   558  
   559  func walltime() (sec int64, nsec int32) {
   560  	var ts mts
   561  	sysvicall2(&libc_clock_gettime, _CLOCK_REALTIME, uintptr(unsafe.Pointer(&ts)))
   562  	return ts.tv_sec, int32(ts.tv_nsec)
   563  }
   564  
   565  //go:nosplit
   566  func write1(fd uintptr, buf unsafe.Pointer, nbyte int32) int32 {
   567  	r1, err := sysvicall3Err(&libc_write, fd, uintptr(buf), uintptr(nbyte))
   568  	if c := int32(r1); c >= 0 {
   569  		return c
   570  	}
   571  	return -int32(err)
   572  }
   573  
   574  //go:nosplit
   575  func pipe2(flags int32) (r, w int32, errno int32) {
   576  	var p [2]int32
   577  	_, e := sysvicall2Err(&libc_pipe2, uintptr(noescape(unsafe.Pointer(&p))), uintptr(flags))
   578  	return p[0], p[1], int32(e)
   579  }
   580  
   581  //go:nosplit
   582  func fcntl(fd, cmd, arg int32) (ret int32, errno int32) {
   583  	r1, err := sysvicall3Err(&libc_fcntl, uintptr(fd), uintptr(cmd), uintptr(arg))
   584  	return int32(r1), int32(err)
   585  }
   586  
   587  func osyield1()
   588  
   589  //go:nosplit
   590  func osyield_no_g() {
   591  	osyield1()
   592  }
   593  
   594  //go:nosplit
   595  func osyield() {
   596  	sysvicall0(&libc_sched_yield)
   597  }
   598  
   599  //go:linkname executablePath os.executablePath
   600  var executablePath string
   601  
   602  func sysargs(argc int32, argv **byte) {
   603  	n := argc + 1
   604  
   605  	// skip over argv, envp to get to auxv
   606  	for argv_index(argv, n) != nil {
   607  		n++
   608  	}
   609  
   610  	// skip NULL separator
   611  	n++
   612  
   613  	// now argv+n is auxv
   614  	auxvp := (*[1 << 28]uintptr)(add(unsafe.Pointer(argv), uintptr(n)*goarch.PtrSize))
   615  	pairs := sysauxv(auxvp[:])
   616  	auxv = auxvp[: pairs*2 : pairs*2]
   617  }
   618  
   619  const (
   620  	_AT_NULL         = 0    // Terminates the vector
   621  	_AT_PAGESZ       = 6    // Page size in bytes
   622  	_AT_SUN_EXECNAME = 2014 // exec() path name
   623  )
   624  
   625  func sysauxv(auxv []uintptr) (pairs int) {
   626  	var i int
   627  	for i = 0; auxv[i] != _AT_NULL; i += 2 {
   628  		tag, val := auxv[i], auxv[i+1]
   629  		switch tag {
   630  		case _AT_PAGESZ:
   631  			physPageSize = val
   632  		case _AT_SUN_EXECNAME:
   633  			executablePath = gostringnocopy((*byte)(unsafe.Pointer(val)))
   634  		}
   635  	}
   636  	return i / 2
   637  }
   638  
   639  // sigPerThreadSyscall is only used on linux, so we assign a bogus signal
   640  // number.
   641  const sigPerThreadSyscall = 1 << 31
   642  
   643  //go:nosplit
   644  func runPerThreadSyscall() {
   645  	throw("runPerThreadSyscall only valid on linux")
   646  }
   647  

View as plain text