Home | History | Annotate | Download | only in runtime
      1 // Copyright 2010 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 // Called to initialize a new m (including the bootstrap m).
     10 // Called on the parent thread (main thread in case of bootstrap), can allocate memory.
     11 func mpreinit(mp *m) {
     12 	mp.gsignal = malg(32 * 1024)
     13 	mp.gsignal.m = mp
     14 }
     15 
     16 func sigtramp()
     17 
     18 func msigsave(mp *m) {
     19 }
     20 
     21 // Called to initialize a new m (including the bootstrap m).
     22 // Called on the new thread, can not allocate memory.
     23 func minit() {
     24 	_g_ := getg()
     25 
     26 	// Initialize signal handling
     27 	ret := nacl_exception_stack(_g_.m.gsignal.stack.lo, 32*1024)
     28 	if ret < 0 {
     29 		print("runtime: nacl_exception_stack: error ", -ret, "\n")
     30 	}
     31 
     32 	ret = nacl_exception_handler(funcPC(sigtramp), nil)
     33 	if ret < 0 {
     34 		print("runtime: nacl_exception_handler: error ", -ret, "\n")
     35 	}
     36 }
     37 
     38 // Called from dropm to undo the effect of an minit.
     39 func unminit() {
     40 }
     41 
     42 func osinit() {
     43 	ncpu = 1
     44 	getg().m.procid = 2
     45 	//nacl_exception_handler(funcPC(sigtramp), nil);
     46 }
     47 
     48 func crash() {
     49 	*(*int32)(nil) = 0
     50 }
     51 
     52 //go:noescape
     53 func getRandomData([]byte)
     54 
     55 func goenvs() {
     56 	goenvs_unix()
     57 }
     58 
     59 func initsig() {
     60 }
     61 
     62 //go:nosplit
     63 func usleep(us uint32) {
     64 	var ts timespec
     65 
     66 	ts.tv_sec = int64(us / 1e6)
     67 	ts.tv_nsec = int32(us%1e6) * 1e3
     68 	nacl_nanosleep(&ts, nil)
     69 }
     70 
     71 func mstart_nacl()
     72 
     73 // May run with m.p==nil, so write barriers are not allowed.
     74 //go:nowritebarrier
     75 func newosproc(mp *m, stk unsafe.Pointer) {
     76 	mp.tls[0] = uintptr(unsafe.Pointer(mp.g0))
     77 	mp.tls[1] = uintptr(unsafe.Pointer(mp))
     78 	ret := nacl_thread_create(funcPC(mstart_nacl), stk, unsafe.Pointer(&mp.tls[2]), nil)
     79 	if ret < 0 {
     80 		print("nacl_thread_create: error ", -ret, "\n")
     81 		throw("newosproc")
     82 	}
     83 }
     84 
     85 //go:nosplit
     86 func semacreate() uintptr {
     87 	var cond uintptr
     88 	systemstack(func() {
     89 		mu := nacl_mutex_create(0)
     90 		if mu < 0 {
     91 			print("nacl_mutex_create: error ", -mu, "\n")
     92 			throw("semacreate")
     93 		}
     94 		c := nacl_cond_create(0)
     95 		if c < 0 {
     96 			print("nacl_cond_create: error ", -cond, "\n")
     97 			throw("semacreate")
     98 		}
     99 		cond = uintptr(c)
    100 		_g_ := getg()
    101 		_g_.m.waitsemalock = uint32(mu)
    102 	})
    103 	return cond
    104 }
    105 
    106 //go:nosplit
    107 func semasleep(ns int64) int32 {
    108 	var ret int32
    109 
    110 	systemstack(func() {
    111 		_g_ := getg()
    112 		if nacl_mutex_lock(int32(_g_.m.waitsemalock)) < 0 {
    113 			throw("semasleep")
    114 		}
    115 
    116 		for _g_.m.waitsemacount == 0 {
    117 			if ns < 0 {
    118 				if nacl_cond_wait(int32(_g_.m.waitsema), int32(_g_.m.waitsemalock)) < 0 {
    119 					throw("semasleep")
    120 				}
    121 			} else {
    122 				var ts timespec
    123 				end := ns + nanotime()
    124 				ts.tv_sec = end / 1e9
    125 				ts.tv_nsec = int32(end % 1e9)
    126 				r := nacl_cond_timed_wait_abs(int32(_g_.m.waitsema), int32(_g_.m.waitsemalock), &ts)
    127 				if r == -_ETIMEDOUT {
    128 					nacl_mutex_unlock(int32(_g_.m.waitsemalock))
    129 					ret = -1
    130 					return
    131 				}
    132 				if r < 0 {
    133 					throw("semasleep")
    134 				}
    135 			}
    136 		}
    137 
    138 		_g_.m.waitsemacount = 0
    139 		nacl_mutex_unlock(int32(_g_.m.waitsemalock))
    140 		ret = 0
    141 	})
    142 	return ret
    143 }
    144 
    145 //go:nosplit
    146 func semawakeup(mp *m) {
    147 	systemstack(func() {
    148 		if nacl_mutex_lock(int32(mp.waitsemalock)) < 0 {
    149 			throw("semawakeup")
    150 		}
    151 		if mp.waitsemacount != 0 {
    152 			throw("semawakeup")
    153 		}
    154 		mp.waitsemacount = 1
    155 		nacl_cond_signal(int32(mp.waitsema))
    156 		nacl_mutex_unlock(int32(mp.waitsemalock))
    157 	})
    158 }
    159 
    160 func memlimit() uintptr {
    161 	return 0
    162 }
    163 
    164 // This runs on a foreign stack, without an m or a g.  No stack split.
    165 //go:nosplit
    166 func badsignal2() {
    167 	write(2, unsafe.Pointer(&badsignal1[0]), int32(len(badsignal1)))
    168 	exit(2)
    169 }
    170 
    171 var badsignal1 = []byte("runtime: signal received on thread not created by Go.\n")
    172 
    173 func raisebadsignal(sig int32) {
    174 	badsignal2()
    175 }
    176 
    177 func madvise(addr unsafe.Pointer, n uintptr, flags int32) {}
    178 func munmap(addr unsafe.Pointer, n uintptr)               {}
    179 func resetcpuprofiler(hz int32)                           {}
    180 func sigdisable(uint32)                                   {}
    181 func sigenable(uint32)                                    {}
    182 func sigignore(uint32)                                    {}
    183 func closeonexec(int32)                                   {}
    184 
    185 var writelock uint32 // test-and-set spin lock for write
    186 
    187 /*
    188 An attempt at IRT. Doesn't work. See end of sys_nacl_amd64.s.
    189 
    190 void (*nacl_irt_query)(void);
    191 
    192 int8 nacl_irt_basic_v0_1_str[] = "nacl-irt-basic-0.1";
    193 void *nacl_irt_basic_v0_1[6]; // exit, gettod, clock, nanosleep, sched_yield, sysconf
    194 int32 nacl_irt_basic_v0_1_size = sizeof(nacl_irt_basic_v0_1);
    195 
    196 int8 nacl_irt_memory_v0_3_str[] = "nacl-irt-memory-0.3";
    197 void *nacl_irt_memory_v0_3[3]; // mmap, munmap, mprotect
    198 int32 nacl_irt_memory_v0_3_size = sizeof(nacl_irt_memory_v0_3);
    199 
    200 int8 nacl_irt_thread_v0_1_str[] = "nacl-irt-thread-0.1";
    201 void *nacl_irt_thread_v0_1[3]; // thread_create, thread_exit, thread_nice
    202 int32 nacl_irt_thread_v0_1_size = sizeof(nacl_irt_thread_v0_1);
    203 */
    204