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