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