github.com/razvanm/vanadium-go-1.3@v0.0.0-20160721203343-4a65068e5915/src/runtime/os_nacl.c (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 #include "runtime.h" 6 #include "defs_GOOS_GOARCH.h" 7 #include "irt_nacl.h" 8 #include "os_GOOS.h" 9 #include "arch_GOARCH.h" 10 #include "textflag.h" 11 #include "stack.h" 12 #include "syscall_nacl.h" 13 14 int8 *goos = "nacl"; 15 extern SigTab runtime·sigtab[]; 16 17 void runtime·sigtramp(void); 18 19 // Called to initialize a new m (including the bootstrap m). 20 // Called on the parent thread (main thread in case of bootstrap), can allocate memory. 21 void 22 runtime·mpreinit(M *mp) 23 { 24 mp->gsignal = runtime·malg(32*1024); // OS X wants >=8K, Linux >=2K 25 mp->gsignal->m = mp; 26 } 27 28 // Called to initialize a new m (including the bootstrap m). 29 // Called on the new thread, can not allocate memory. 30 void 31 runtime·minit(void) 32 { 33 int32 ret; 34 35 // Initialize signal handling 36 ret = runtime·nacl_exception_stack((byte*)g->m->gsignal->stack.lo, 32*1024); 37 if(ret < 0) 38 runtime·printf("runtime: nacl_exception_stack: error %d\n", -ret); 39 40 ret = runtime·nacl_exception_handler(runtime·sigtramp, nil); 41 if(ret < 0) 42 runtime·printf("runtime: nacl_exception_handler: error %d\n", -ret); 43 } 44 45 // Called from dropm to undo the effect of an minit. 46 void 47 runtime·unminit(void) 48 { 49 } 50 51 int8 runtime·sigtrampf[] = "runtime: signal at PC=%X AX=%X CX=%X DX=%X BX=%X DI=%X R15=%X *SP=%X\n"; 52 int8 runtime·sigtrampp[] = "runtime: sigtramp"; 53 54 extern byte runtime·tls0[]; 55 56 void 57 runtime·osinit(void) 58 { 59 runtime·ncpu = 1; 60 g->m->procid = 2; 61 //runtime·nacl_exception_handler(runtime·sigtramp, nil); 62 } 63 64 void 65 runtime·crash(void) 66 { 67 *(int32*)0 = 0; 68 } 69 70 #pragma textflag NOSPLIT 71 void 72 runtime·get_random_data(byte **rnd, int32 *rnd_len) 73 { 74 *rnd = nil; 75 *rnd_len = 0; 76 } 77 78 void 79 runtime·goenvs(void) 80 { 81 runtime·goenvs_unix(); 82 } 83 84 void 85 runtime·initsig(void) 86 { 87 } 88 89 #pragma textflag NOSPLIT 90 void 91 runtime·usleep(uint32 us) 92 { 93 Timespec ts; 94 95 ts.tv_sec = us/1000000; 96 ts.tv_nsec = (us%1000000)*1000; 97 runtime·nacl_nanosleep(&ts, nil); 98 } 99 100 void runtime·mstart_nacl(void); 101 102 void 103 runtime·newosproc(M *mp, void *stk) 104 { 105 int32 ret; 106 void **tls; 107 108 tls = (void**)mp->tls; 109 tls[0] = mp->g0; 110 tls[1] = mp; 111 ret = runtime·nacl_thread_create(runtime·mstart_nacl, stk, tls+2, 0); 112 if(ret < 0) { 113 runtime·printf("nacl_thread_create: error %d\n", -ret); 114 runtime·throw("newosproc"); 115 } 116 } 117 118 static void 119 semacreate(void) 120 { 121 int32 mu, cond; 122 123 mu = runtime·nacl_mutex_create(0); 124 if(mu < 0) { 125 // runtime·printf("nacl_mutex_create: error %d\n", -mu); 126 runtime·throw("semacreate"); 127 } 128 cond = runtime·nacl_cond_create(0); 129 if(cond < 0) { 130 runtime·printf("nacl_cond_create: error %d\n", -cond); 131 runtime·throw("semacreate"); 132 } 133 g->m->waitsemalock = mu; 134 g->m->scalararg[0] = cond; // assigned to m->waitsema 135 } 136 137 #pragma textflag NOSPLIT 138 uint32 139 runtime·semacreate(void) 140 { 141 void (*fn)(void); 142 uint32 x; 143 144 fn = semacreate; 145 runtime·onM(&fn); 146 x = g->m->scalararg[0]; 147 g->m->scalararg[0] = 0; 148 return x; 149 } 150 151 static void 152 semasleep(void) 153 { 154 int32 ret; 155 int64 ns; 156 157 ns = (int64)(uint32)g->m->scalararg[0] | (int64)(uint32)g->m->scalararg[1]<<32; 158 g->m->scalararg[0] = 0; 159 g->m->scalararg[1] = 0; 160 161 ret = runtime·nacl_mutex_lock(g->m->waitsemalock); 162 if(ret < 0) { 163 runtime·printf("nacl_mutex_lock: error %d\n", -ret); 164 runtime·throw("semasleep"); 165 } 166 if(g->m->waitsemacount > 0) { 167 g->m->waitsemacount = 0; 168 runtime·nacl_mutex_unlock(g->m->waitsemalock); 169 g->m->scalararg[0] = 0; 170 return; 171 } 172 173 while(g->m->waitsemacount == 0) { 174 if(ns < 0) { 175 ret = runtime·nacl_cond_wait(g->m->waitsema, g->m->waitsemalock); 176 if(ret < 0) { 177 runtime·printf("nacl_cond_wait: error %d\n", -ret); 178 runtime·throw("semasleep"); 179 } 180 } else { 181 Timespec ts; 182 183 ns += runtime·nanotime(); 184 ts.tv_sec = runtime·timediv(ns, 1000000000, (int32*)&ts.tv_nsec); 185 ret = runtime·nacl_cond_timed_wait_abs(g->m->waitsema, g->m->waitsemalock, &ts); 186 if(ret == -ETIMEDOUT) { 187 runtime·nacl_mutex_unlock(g->m->waitsemalock); 188 g->m->scalararg[0] = -1; 189 return; 190 } 191 if(ret < 0) { 192 runtime·printf("nacl_cond_timed_wait_abs: error %d\n", -ret); 193 runtime·throw("semasleep"); 194 } 195 } 196 } 197 198 g->m->waitsemacount = 0; 199 runtime·nacl_mutex_unlock(g->m->waitsemalock); 200 g->m->scalararg[0] = 0; 201 } 202 203 #pragma textflag NOSPLIT 204 int32 205 runtime·semasleep(int64 ns) 206 { 207 int32 r; 208 void (*fn)(void); 209 210 g->m->scalararg[0] = (uint32)ns; 211 g->m->scalararg[1] = (uint32)(ns>>32); 212 fn = semasleep; 213 runtime·onM(&fn); 214 r = g->m->scalararg[0]; 215 g->m->scalararg[0] = 0; 216 return r; 217 } 218 219 static void 220 semawakeup(void) 221 { 222 int32 ret; 223 M *mp; 224 225 mp = g->m->ptrarg[0]; 226 g->m->ptrarg[0] = nil; 227 228 ret = runtime·nacl_mutex_lock(mp->waitsemalock); 229 if(ret < 0) { 230 //runtime·printf("nacl_mutex_lock: error %d\n", -ret); 231 runtime·throw("semawakeup"); 232 } 233 if(mp->waitsemacount != 0) { 234 //runtime·printf("semawakeup: double wakeup\n"); 235 runtime·throw("semawakeup"); 236 } 237 mp->waitsemacount = 1; 238 runtime·nacl_cond_signal(mp->waitsema); 239 runtime·nacl_mutex_unlock(mp->waitsemalock); 240 } 241 242 #pragma textflag NOSPLIT 243 void 244 runtime·semawakeup(M *mp) 245 { 246 void (*fn)(void); 247 248 g->m->ptrarg[0] = mp; 249 fn = semawakeup; 250 runtime·onM(&fn); 251 } 252 253 uintptr 254 runtime·memlimit(void) 255 { 256 runtime·printf("memlimit\n"); 257 return 0; 258 } 259 260 #pragma dataflag NOPTR 261 static int8 badsignal[] = "runtime: signal received on thread not created by Go.\n"; 262 263 // This runs on a foreign stack, without an m or a g. No stack split. 264 #pragma textflag NOSPLIT 265 void 266 runtime·badsignal2(void) 267 { 268 runtime·write(2, badsignal, sizeof badsignal - 1); 269 runtime·exit(2); 270 } 271 272 void runtime·madvise(byte*, uintptr, int32) { } 273 void runtime·munmap(byte*, uintptr) {} 274 275 void 276 runtime·resetcpuprofiler(int32 hz) 277 { 278 USED(hz); 279 } 280 281 void 282 runtime·sigdisable(uint32) 283 { 284 } 285 286 void 287 runtime·sigenable(uint32) 288 { 289 } 290 291 void 292 runtime·closeonexec(int32) 293 { 294 } 295 296 uint32 runtime·writelock; // test-and-set spin lock for runtime.write 297 298 299 typedef int32 (*TYPE_nacl_irt_query)(const int8 *interface_ident, 300 void *table, int32 tablesize); 301 302 struct nacl_irt_entry { 303 int8 *name; 304 void **funtab; 305 int32 size; 306 int32 is_required; 307 }; 308 309 TYPE_nacl_irt_query runtime·nacl_irt_query; 310 311 int32 runtime·nacl_irt_is_enabled; 312 313 #pragma dataflag NOPTR 314 void *runtime·nacl_irt_basic_v0_1[IRT_BASIC_SIZE]; 315 #pragma dataflag NOPTR 316 void *runtime·nacl_irt_memory_v0_3[IRT_MEMORY_SIZE]; 317 #pragma dataflag NOPTR 318 void *runtime·nacl_irt_thread_v0_1[IRT_THREAD_SIZE]; 319 #pragma dataflag NOPTR 320 void *runtime·nacl_irt_futex_v0_1[IRT_FUTEX_SIZE]; 321 #pragma dataflag NOPTR 322 void *runtime·nacl_irt_fdio_v0_1[IRT_FDIO_SIZE]; 323 #pragma dataflag NOPTR 324 void *runtime·nacl_irt_filename_v0_1[IRT_FILENAME_SIZE]; 325 #pragma dataflag NOPTR 326 void *runtime·nacl_irt_exception_handling_v0_1[IRT_EXCEPTION_SIZE]; 327 #pragma dataflag NOPTR 328 void *runtime·nacl_irt_mutex_v0_1[IRT_MUTEX_SIZE]; 329 #pragma dataflag NOPTR 330 void *runtime·nacl_irt_cond_v0_1[IRT_COND_SIZE]; 331 #pragma dataflag NOPTR 332 void *runtime·nacl_irt_sem_v0_1[IRT_SEM_SIZE]; 333 #pragma dataflag NOPTR 334 void *runtime·nacl_irt_tls_v0_1[IRT_TLS_SIZE]; 335 #pragma dataflag NOPTR 336 void *runtime·nacl_irt_random_v0_1[IRT_RANDOM_SIZE]; 337 #pragma dataflag NOPTR 338 void *runtime·nacl_irt_clock_v0_1[IRT_CLOCK_SIZE]; 339 #pragma dataflag NOPTR 340 void *runtime·nacl_irt_ppapihook_v0_1[IRT_PPAPIHOOK_SIZE]; 341 342 #pragma dataflag NOPTR 343 struct nacl_irt_entry runtime·nacl_irt_entries[] = { 344 #define NACL_IRT_ENTRY(name, s) { (name), (s), sizeof(s) } 345 NACL_IRT_ENTRY("nacl-irt-basic-0.1", runtime·nacl_irt_basic_v0_1), 346 NACL_IRT_ENTRY("nacl-irt-memory-0.3", runtime·nacl_irt_memory_v0_3), 347 NACL_IRT_ENTRY("nacl-irt-thread-0.1", runtime·nacl_irt_thread_v0_1), 348 NACL_IRT_ENTRY("nacl-irt-futex-0.1", runtime·nacl_irt_futex_v0_1), 349 NACL_IRT_ENTRY("nacl-irt-fdio-0.1", runtime·nacl_irt_fdio_v0_1), 350 NACL_IRT_ENTRY("nacl-irt-filename-0.1", runtime·nacl_irt_filename_v0_1), 351 NACL_IRT_ENTRY("nacl-irt-exception-handling-0.1", runtime·nacl_irt_exception_handling_v0_1), 352 NACL_IRT_ENTRY("nacl-irt-mutex-0.1", runtime·nacl_irt_mutex_v0_1), 353 NACL_IRT_ENTRY("nacl-irt-cond-0.1", runtime·nacl_irt_cond_v0_1), 354 NACL_IRT_ENTRY("nacl-irt-sem-0.1", runtime·nacl_irt_sem_v0_1), 355 NACL_IRT_ENTRY("nacl-irt-tls-0.1", runtime·nacl_irt_tls_v0_1), 356 NACL_IRT_ENTRY("nacl-irt-random-0.1", runtime·nacl_irt_random_v0_1), 357 NACL_IRT_ENTRY("nacl-irt-clock_get-0.1", runtime·nacl_irt_clock_v0_1), 358 NACL_IRT_ENTRY("nacl-irt-ppapihook-0.1", runtime·nacl_irt_ppapihook_v0_1), 359 { 0 }, 360 #undef NACL_IRT_ENTRY 361 };