Black Lives Matter. Support the Equal Justice Initiative.

Source file src/runtime/os_solaris.go

Documentation: runtime

     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  	r1, _ := sysvicall1Err(fn, a1)
    67  	return r1
    68  }
    69  
    70  //go:nosplit
    71  
    72  // sysvicall1Err returns both the system call result and the errno value.
    73  // This is used by sysvicall1 and pipe.
    74  func sysvicall1Err(fn *libcFunc, a1 uintptr) (r1, err uintptr) {
    75  	// Leave caller's PC/SP around for traceback.
    76  	gp := getg()
    77  	var mp *m
    78  	if gp != nil {
    79  		mp = gp.m
    80  	}
    81  	if mp != nil && mp.libcallsp == 0 {
    82  		mp.libcallg.set(gp)
    83  		mp.libcallpc = getcallerpc()
    84  		// sp must be the last, because once async cpu profiler finds
    85  		// all three values to be non-zero, it will use them
    86  		mp.libcallsp = getcallersp()
    87  	} else {
    88  		mp = nil
    89  	}
    90  
    91  	var libcall libcall
    92  	libcall.fn = uintptr(unsafe.Pointer(fn))
    93  	libcall.n = 1
    94  	// TODO(rsc): Why is noescape necessary here and below?
    95  	libcall.args = uintptr(noescape(unsafe.Pointer(&a1)))
    96  	asmcgocall(unsafe.Pointer(&asmsysvicall6x), unsafe.Pointer(&libcall))
    97  	if mp != nil {
    98  		mp.libcallsp = 0
    99  	}
   100  	return libcall.r1, libcall.err
   101  }
   102  
   103  //go:nosplit
   104  func sysvicall2(fn *libcFunc, a1, a2 uintptr) uintptr {
   105  	r1, _ := sysvicall2Err(fn, a1, a2)
   106  	return r1
   107  }
   108  
   109  //go:nosplit
   110  //go:cgo_unsafe_args
   111  
   112  // sysvicall2Err returns both the system call result and the errno value.
   113  // This is used by sysvicall2 and pipe2.
   114  func sysvicall2Err(fn *libcFunc, a1, a2 uintptr) (uintptr, uintptr) {
   115  	// Leave caller's PC/SP around for traceback.
   116  	gp := getg()
   117  	var mp *m
   118  	if gp != nil {
   119  		mp = gp.m
   120  	}
   121  	if mp != nil && mp.libcallsp == 0 {
   122  		mp.libcallg.set(gp)
   123  		mp.libcallpc = getcallerpc()
   124  		// sp must be the last, because once async cpu profiler finds
   125  		// all three values to be non-zero, it will use them
   126  		mp.libcallsp = getcallersp()
   127  	} else {
   128  		mp = nil
   129  	}
   130  
   131  	var libcall libcall
   132  	libcall.fn = uintptr(unsafe.Pointer(fn))
   133  	libcall.n = 2
   134  	libcall.args = uintptr(noescape(unsafe.Pointer(&a1)))
   135  	asmcgocall(unsafe.Pointer(&asmsysvicall6x), unsafe.Pointer(&libcall))
   136  	if mp != nil {
   137  		mp.libcallsp = 0
   138  	}
   139  	return libcall.r1, libcall.err
   140  }
   141  
   142  //go:nosplit
   143  func sysvicall3(fn *libcFunc, a1, a2, a3 uintptr) uintptr {
   144  	r1, _ := sysvicall3Err(fn, a1, a2, a3)
   145  	return r1
   146  }
   147  
   148  //go:nosplit
   149  //go:cgo_unsafe_args
   150  
   151  // sysvicall3Err returns both the system call result and the errno value.
   152  // This is used by sysicall3 and write1.
   153  func sysvicall3Err(fn *libcFunc, a1, a2, a3 uintptr) (r1, err 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 = 3
   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, libcall.err
   179  }
   180  
   181  //go:nosplit
   182  func sysvicall4(fn *libcFunc, a1, a2, a3, a4 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 = 4
   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 sysvicall5(fn *libcFunc, a1, a2, a3, a4, a5 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 = 5
   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  
   239  //go:nosplit
   240  func sysvicall6(fn *libcFunc, a1, a2, a3, a4, a5, a6 uintptr) uintptr {
   241  	// Leave caller's PC/SP around for traceback.
   242  	gp := getg()
   243  	var mp *m
   244  	if gp != nil {
   245  		mp = gp.m
   246  	}
   247  	if mp != nil && mp.libcallsp == 0 {
   248  		mp.libcallg.set(gp)
   249  		mp.libcallpc = getcallerpc()
   250  		// sp must be the last, because once async cpu profiler finds
   251  		// all three values to be non-zero, it will use them
   252  		mp.libcallsp = getcallersp()
   253  	} else {
   254  		mp = nil
   255  	}
   256  
   257  	var libcall libcall
   258  	libcall.fn = uintptr(unsafe.Pointer(fn))
   259  	libcall.n = 6
   260  	libcall.args = uintptr(noescape(unsafe.Pointer(&a1)))
   261  	asmcgocall(unsafe.Pointer(&asmsysvicall6x), unsafe.Pointer(&libcall))
   262  	if mp != nil {
   263  		mp.libcallsp = 0
   264  	}
   265  	return libcall.r1
   266  }
   267  

View as plain text