github.com/megatontech/mynoteforgo@v0.0.0-20200507084910-5d0c6ea6e890/源码/runtime/os_nacl.go (about) 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 type mOS struct { 10 waitsema int32 // semaphore for parking on locks 11 waitsemacount int32 12 waitsemalock int32 13 } 14 15 func nacl_exception_stack(p uintptr, size int32) int32 16 func nacl_exception_handler(fn uintptr, arg unsafe.Pointer) int32 17 func nacl_sem_create(flag int32) int32 18 func nacl_sem_wait(sem int32) int32 19 func nacl_sem_post(sem int32) int32 20 func nacl_mutex_create(flag int32) int32 21 func nacl_mutex_lock(mutex int32) int32 22 func nacl_mutex_trylock(mutex int32) int32 23 func nacl_mutex_unlock(mutex int32) int32 24 func nacl_cond_create(flag int32) int32 25 func nacl_cond_wait(cond, n int32) int32 26 func nacl_cond_signal(cond int32) int32 27 func nacl_cond_broadcast(cond int32) int32 28 29 //go:noescape 30 func nacl_cond_timed_wait_abs(cond, lock int32, ts *timespec) int32 31 func nacl_thread_create(fn uintptr, stk, tls, xx unsafe.Pointer) int32 32 33 //go:noescape 34 func nacl_nanosleep(ts, extra *timespec) int32 35 func nanotime() int64 36 func mmap(addr unsafe.Pointer, n uintptr, prot, flags, fd int32, off uint32) (p unsafe.Pointer, err int) 37 func exit(code int32) 38 func osyield() 39 40 //go:noescape 41 func write(fd uintptr, p unsafe.Pointer, n int32) int32 42 43 //go:linkname os_sigpipe os.sigpipe 44 func os_sigpipe() { 45 throw("too many writes on closed pipe") 46 } 47 48 func dieFromSignal(sig uint32) { 49 exit(2) 50 } 51 52 func sigpanic() { 53 g := getg() 54 if !canpanic(g) { 55 throw("unexpected signal during runtime execution") 56 } 57 58 // Native Client only invokes the exception handler for memory faults. 59 g.sig = _SIGSEGV 60 panicmem() 61 } 62 63 func raiseproc(sig uint32) { 64 } 65 66 // Stubs so tests can link correctly. These should never be called. 67 func open(name *byte, mode, perm int32) int32 68 func closefd(fd int32) int32 69 func read(fd int32, p unsafe.Pointer, n int32) int32 70 71 type sigset struct{} 72 73 // Called to initialize a new m (including the bootstrap m). 74 // Called on the parent thread (main thread in case of bootstrap), can allocate memory. 75 func mpreinit(mp *m) { 76 mp.gsignal = malg(32 * 1024) 77 mp.gsignal.m = mp 78 } 79 80 func sigtramp() 81 82 //go:nosplit 83 func msigsave(mp *m) { 84 } 85 86 //go:nosplit 87 func msigrestore(sigmask sigset) { 88 } 89 90 //go:nosplit 91 //go:nowritebarrierrec 92 func clearSignalHandlers() { 93 } 94 95 //go:nosplit 96 func sigblock() { 97 } 98 99 // Called to initialize a new m (including the bootstrap m). 100 // Called on the new thread, cannot allocate memory. 101 func minit() { 102 _g_ := getg() 103 104 // Initialize signal handling 105 ret := nacl_exception_stack(_g_.m.gsignal.stack.lo, 32*1024) 106 if ret < 0 { 107 print("runtime: nacl_exception_stack: error ", -ret, "\n") 108 } 109 110 ret = nacl_exception_handler(funcPC(sigtramp), nil) 111 if ret < 0 { 112 print("runtime: nacl_exception_handler: error ", -ret, "\n") 113 } 114 } 115 116 // Called from dropm to undo the effect of an minit. 117 func unminit() { 118 } 119 120 func osinit() { 121 ncpu = 1 122 getg().m.procid = 2 123 //nacl_exception_handler(funcPC(sigtramp), nil); 124 physPageSize = 65536 125 } 126 127 func signame(sig uint32) string { 128 if sig >= uint32(len(sigtable)) { 129 return "" 130 } 131 return sigtable[sig].name 132 } 133 134 //go:nosplit 135 func crash() { 136 *(*int32)(nil) = 0 137 } 138 139 //go:noescape 140 func getRandomData([]byte) 141 142 func goenvs() { 143 goenvs_unix() 144 } 145 146 func initsig(preinit bool) { 147 } 148 149 //go:nosplit 150 func usleep(us uint32) { 151 var ts timespec 152 153 ts.tv_sec = int64(us / 1e6) 154 ts.tv_nsec = int32(us%1e6) * 1e3 155 nacl_nanosleep(&ts, nil) 156 } 157 158 func mstart_nacl() 159 160 // May run with m.p==nil, so write barriers are not allowed. 161 //go:nowritebarrier 162 func newosproc(mp *m) { 163 stk := unsafe.Pointer(mp.g0.stack.hi) 164 mp.tls[0] = uintptr(unsafe.Pointer(mp.g0)) 165 mp.tls[1] = uintptr(unsafe.Pointer(mp)) 166 ret := nacl_thread_create(funcPC(mstart_nacl), stk, unsafe.Pointer(&mp.tls[2]), nil) 167 if ret < 0 { 168 print("nacl_thread_create: error ", -ret, "\n") 169 throw("newosproc") 170 } 171 } 172 173 //go:noescape 174 func exitThread(wait *uint32) 175 176 //go:nosplit 177 func semacreate(mp *m) { 178 if mp.waitsema != 0 { 179 return 180 } 181 systemstack(func() { 182 mu := nacl_mutex_create(0) 183 if mu < 0 { 184 print("nacl_mutex_create: error ", -mu, "\n") 185 throw("semacreate") 186 } 187 c := nacl_cond_create(0) 188 if c < 0 { 189 print("nacl_cond_create: error ", -c, "\n") 190 throw("semacreate") 191 } 192 mp.waitsema = c 193 mp.waitsemalock = mu 194 }) 195 } 196 197 //go:nosplit 198 func semasleep(ns int64) int32 { 199 var ret int32 200 systemstack(func() { 201 _g_ := getg() 202 if nacl_mutex_lock(_g_.m.waitsemalock) < 0 { 203 throw("semasleep") 204 } 205 var ts timespec 206 if ns >= 0 { 207 end := ns + nanotime() 208 ts.tv_sec = end / 1e9 209 ts.tv_nsec = int32(end % 1e9) 210 } 211 for _g_.m.waitsemacount == 0 { 212 if ns < 0 { 213 if nacl_cond_wait(_g_.m.waitsema, _g_.m.waitsemalock) < 0 { 214 throw("semasleep") 215 } 216 } else { 217 r := nacl_cond_timed_wait_abs(_g_.m.waitsema, _g_.m.waitsemalock, &ts) 218 if r == -_ETIMEDOUT { 219 nacl_mutex_unlock(_g_.m.waitsemalock) 220 ret = -1 221 return 222 } 223 if r < 0 { 224 throw("semasleep") 225 } 226 } 227 } 228 229 _g_.m.waitsemacount = 0 230 nacl_mutex_unlock(_g_.m.waitsemalock) 231 ret = 0 232 }) 233 return ret 234 } 235 236 //go:nosplit 237 func semawakeup(mp *m) { 238 systemstack(func() { 239 if nacl_mutex_lock(mp.waitsemalock) < 0 { 240 throw("semawakeup") 241 } 242 if mp.waitsemacount != 0 { 243 throw("semawakeup") 244 } 245 mp.waitsemacount = 1 246 nacl_cond_signal(mp.waitsema) 247 nacl_mutex_unlock(mp.waitsemalock) 248 }) 249 } 250 251 // This runs on a foreign stack, without an m or a g. No stack split. 252 //go:nosplit 253 //go:norace 254 //go:nowritebarrierrec 255 func badsignal(sig uintptr) { 256 cgocallback(unsafe.Pointer(funcPC(badsignalgo)), noescape(unsafe.Pointer(&sig)), unsafe.Sizeof(sig), 0) 257 } 258 259 func badsignalgo(sig uintptr) { 260 if !sigsend(uint32(sig)) { 261 // A foreign thread received the signal sig, and the 262 // Go code does not want to handle it. 263 raisebadsignal(uint32(sig)) 264 } 265 } 266 267 // This runs on a foreign stack, without an m or a g. No stack split. 268 //go:nosplit 269 func badsignal2() { 270 write(2, unsafe.Pointer(&badsignal1[0]), int32(len(badsignal1))) 271 exit(2) 272 } 273 274 var badsignal1 = []byte("runtime: signal received on thread not created by Go.\n") 275 276 func raisebadsignal(sig uint32) { 277 badsignal2() 278 } 279 280 func madvise(addr unsafe.Pointer, n uintptr, flags int32) {} 281 func munmap(addr unsafe.Pointer, n uintptr) {} 282 func setProcessCPUProfiler(hz int32) {} 283 func setThreadCPUProfiler(hz int32) {} 284 func sigdisable(uint32) {} 285 func sigenable(uint32) {} 286 func sigignore(uint32) {} 287 func closeonexec(int32) {} 288 289 // gsignalStack is unused on nacl. 290 type gsignalStack struct{} 291 292 var writelock uint32 // test-and-set spin lock for write 293 294 // lastfaketime stores the last faketime value written to fd 1 or 2. 295 var lastfaketime int64 296 297 // lastfaketimefd stores the fd to which lastfaketime was written. 298 // 299 // Subsequent writes to the same fd may use the same timestamp, 300 // but the timestamp must increase if the fd changes. 301 var lastfaketimefd int32 302 303 /* 304 An attempt at IRT. Doesn't work. See end of sys_nacl_amd64.s. 305 306 void (*nacl_irt_query)(void); 307 308 int8 nacl_irt_basic_v0_1_str[] = "nacl-irt-basic-0.1"; 309 void *nacl_irt_basic_v0_1[6]; // exit, gettod, clock, nanosleep, sched_yield, sysconf 310 int32 nacl_irt_basic_v0_1_size = sizeof(nacl_irt_basic_v0_1); 311 312 int8 nacl_irt_memory_v0_3_str[] = "nacl-irt-memory-0.3"; 313 void *nacl_irt_memory_v0_3[3]; // mmap, munmap, mprotect 314 int32 nacl_irt_memory_v0_3_size = sizeof(nacl_irt_memory_v0_3); 315 316 int8 nacl_irt_thread_v0_1_str[] = "nacl-irt-thread-0.1"; 317 void *nacl_irt_thread_v0_1[3]; // thread_create, thread_exit, thread_nice 318 int32 nacl_irt_thread_v0_1_size = sizeof(nacl_irt_thread_v0_1); 319 */ 320 321 // The following functions are implemented in runtime assembly. 322 // Provide a Go declaration to go with its assembly definitions. 323 324 //go:linkname syscall_naclWrite syscall.naclWrite 325 func syscall_naclWrite(fd int, b []byte) int 326 327 //go:linkname syscall_now syscall.now 328 func syscall_now() (sec int64, nsec int32)