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