...

Source file src/runtime/os_solaris.go

     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	
     5	package runtime
     6	
     7	import "unsafe"
     8	
     9	type mts struct {
    10		tv_sec  int64
    11		tv_nsec int64
    12	}
    13	
    14	type mscratch struct {
    15		v [6]uintptr
    16	}
    17	
    18	type mOS struct {
    19		waitsema uintptr // semaphore for parking on locks
    20		perrno   *int32  // pointer to tls errno
    21		// these are here because they are too large to be on the stack
    22		// of low-level NOSPLIT functions.
    23		//LibCall       libcall;
    24		ts      mts
    25		scratch mscratch
    26	}
    27	
    28	type libcFunc uintptr
    29	
    30	//go:linkname asmsysvicall6x runtime.asmsysvicall6
    31	var asmsysvicall6x libcFunc // name to take addr of asmsysvicall6
    32	
    33	func asmsysvicall6() // declared for vet; do NOT call
    34	
    35	//go:nosplit
    36	func sysvicall0(fn *libcFunc) uintptr {
    37		// Leave caller's PC/SP around for traceback.
    38		gp := getg()
    39		var mp *m
    40		if gp != nil {
    41			mp = gp.m
    42		}
    43		if mp != nil && mp.libcallsp == 0 {
    44			mp.libcallg.set(gp)
    45			mp.libcallpc = getcallerpc()
    46			// sp must be the last, because once async cpu profiler finds
    47			// all three values to be non-zero, it will use them
    48			mp.libcallsp = getcallersp()
    49		} else {
    50			mp = nil // See comment in sys_darwin.go:libcCall
    51		}
    52	
    53		var libcall libcall
    54		libcall.fn = uintptr(unsafe.Pointer(fn))
    55		libcall.n = 0
    56		libcall.args = uintptr(unsafe.Pointer(fn)) // it's unused but must be non-nil, otherwise crashes
    57		asmcgocall(unsafe.Pointer(&asmsysvicall6x), unsafe.Pointer(&libcall))
    58		if mp != nil {
    59			mp.libcallsp = 0
    60		}
    61		return libcall.r1
    62	}
    63	
    64	//go:nosplit
    65	func sysvicall1(fn *libcFunc, a1 uintptr) uintptr {
    66		// Leave caller's PC/SP around for traceback.
    67		gp := getg()
    68		var mp *m
    69		if gp != nil {
    70			mp = gp.m
    71		}
    72		if mp != nil && mp.libcallsp == 0 {
    73			mp.libcallg.set(gp)
    74			mp.libcallpc = getcallerpc()
    75			// sp must be the last, because once async cpu profiler finds
    76			// all three values to be non-zero, it will use them
    77			mp.libcallsp = getcallersp()
    78		} else {
    79			mp = nil
    80		}
    81	
    82		var libcall libcall
    83		libcall.fn = uintptr(unsafe.Pointer(fn))
    84		libcall.n = 1
    85		// TODO(rsc): Why is noescape necessary here and below?
    86		libcall.args = uintptr(noescape(unsafe.Pointer(&a1)))
    87		asmcgocall(unsafe.Pointer(&asmsysvicall6x), unsafe.Pointer(&libcall))
    88		if mp != nil {
    89			mp.libcallsp = 0
    90		}
    91		return libcall.r1
    92	}
    93	
    94	//go:nosplit
    95	func sysvicall2(fn *libcFunc, a1, a2 uintptr) uintptr {
    96		// Leave caller's PC/SP around for traceback.
    97		gp := getg()
    98		var mp *m
    99		if gp != nil {
   100			mp = gp.m
   101		}
   102		if mp != nil && mp.libcallsp == 0 {
   103			mp.libcallg.set(gp)
   104			mp.libcallpc = getcallerpc()
   105			// sp must be the last, because once async cpu profiler finds
   106			// all three values to be non-zero, it will use them
   107			mp.libcallsp = getcallersp()
   108		} else {
   109			mp = nil
   110		}
   111	
   112		var libcall libcall
   113		libcall.fn = uintptr(unsafe.Pointer(fn))
   114		libcall.n = 2
   115		libcall.args = uintptr(noescape(unsafe.Pointer(&a1)))
   116		asmcgocall(unsafe.Pointer(&asmsysvicall6x), unsafe.Pointer(&libcall))
   117		if mp != nil {
   118			mp.libcallsp = 0
   119		}
   120		return libcall.r1
   121	}
   122	
   123	//go:nosplit
   124	func sysvicall3(fn *libcFunc, a1, a2, a3 uintptr) uintptr {
   125		// Leave caller's PC/SP around for traceback.
   126		gp := getg()
   127		var mp *m
   128		if gp != nil {
   129			mp = gp.m
   130		}
   131		if mp != nil && mp.libcallsp == 0 {
   132			mp.libcallg.set(gp)
   133			mp.libcallpc = getcallerpc()
   134			// sp must be the last, because once async cpu profiler finds
   135			// all three values to be non-zero, it will use them
   136			mp.libcallsp = getcallersp()
   137		} else {
   138			mp = nil
   139		}
   140	
   141		var libcall libcall
   142		libcall.fn = uintptr(unsafe.Pointer(fn))
   143		libcall.n = 3
   144		libcall.args = uintptr(noescape(unsafe.Pointer(&a1)))
   145		asmcgocall(unsafe.Pointer(&asmsysvicall6x), unsafe.Pointer(&libcall))
   146		if mp != nil {
   147			mp.libcallsp = 0
   148		}
   149		return libcall.r1
   150	}
   151	
   152	//go:nosplit
   153	func sysvicall4(fn *libcFunc, a1, a2, a3, a4 uintptr) uintptr {
   154		// Leave caller's PC/SP around for traceback.
   155		gp := getg()
   156		var mp *m
   157		if gp != nil {
   158			mp = gp.m
   159		}
   160		if mp != nil && mp.libcallsp == 0 {
   161			mp.libcallg.set(gp)
   162			mp.libcallpc = getcallerpc()
   163			// sp must be the last, because once async cpu profiler finds
   164			// all three values to be non-zero, it will use them
   165			mp.libcallsp = getcallersp()
   166		} else {
   167			mp = nil
   168		}
   169	
   170		var libcall libcall
   171		libcall.fn = uintptr(unsafe.Pointer(fn))
   172		libcall.n = 4
   173		libcall.args = uintptr(noescape(unsafe.Pointer(&a1)))
   174		asmcgocall(unsafe.Pointer(&asmsysvicall6x), unsafe.Pointer(&libcall))
   175		if mp != nil {
   176			mp.libcallsp = 0
   177		}
   178		return libcall.r1
   179	}
   180	
   181	//go:nosplit
   182	func sysvicall5(fn *libcFunc, a1, a2, a3, a4, a5 uintptr) uintptr {
   183		// Leave caller's PC/SP around for traceback.
   184		gp := getg()
   185		var mp *m
   186		if gp != nil {
   187			mp = gp.m
   188		}
   189		if mp != nil && mp.libcallsp == 0 {
   190			mp.libcallg.set(gp)
   191			mp.libcallpc = getcallerpc()
   192			// sp must be the last, because once async cpu profiler finds
   193			// all three values to be non-zero, it will use them
   194			mp.libcallsp = getcallersp()
   195		} else {
   196			mp = nil
   197		}
   198	
   199		var libcall libcall
   200		libcall.fn = uintptr(unsafe.Pointer(fn))
   201		libcall.n = 5
   202		libcall.args = uintptr(noescape(unsafe.Pointer(&a1)))
   203		asmcgocall(unsafe.Pointer(&asmsysvicall6x), unsafe.Pointer(&libcall))
   204		if mp != nil {
   205			mp.libcallsp = 0
   206		}
   207		return libcall.r1
   208	}
   209	
   210	//go:nosplit
   211	func sysvicall6(fn *libcFunc, a1, a2, a3, a4, a5, a6 uintptr) uintptr {
   212		// Leave caller's PC/SP around for traceback.
   213		gp := getg()
   214		var mp *m
   215		if gp != nil {
   216			mp = gp.m
   217		}
   218		if mp != nil && mp.libcallsp == 0 {
   219			mp.libcallg.set(gp)
   220			mp.libcallpc = getcallerpc()
   221			// sp must be the last, because once async cpu profiler finds
   222			// all three values to be non-zero, it will use them
   223			mp.libcallsp = getcallersp()
   224		} else {
   225			mp = nil
   226		}
   227	
   228		var libcall libcall
   229		libcall.fn = uintptr(unsafe.Pointer(fn))
   230		libcall.n = 6
   231		libcall.args = uintptr(noescape(unsafe.Pointer(&a1)))
   232		asmcgocall(unsafe.Pointer(&asmsysvicall6x), unsafe.Pointer(&libcall))
   233		if mp != nil {
   234			mp.libcallsp = 0
   235		}
   236		return libcall.r1
   237	}
   238	

View as plain text