github.com/xushiwei/go@v0.0.0-20130601165731-2b9d83f45bc9/src/pkg/runtime/os_plan9.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 "os_GOOS.h" 7 #include "arch_GOARCH.h" 8 9 int8 *goos = "plan9"; 10 extern SigTab runtime·sigtab[]; 11 12 int32 runtime·postnote(int32, int8*); 13 14 // Called to initialize a new m (including the bootstrap m). 15 // Called on the parent thread (main thread in case of bootstrap), can allocate memory. 16 void 17 runtime·mpreinit(M *mp) 18 { 19 // Initialize stack and goroutine for note handling. 20 mp->gsignal = runtime·malg(32*1024); 21 mp->notesig = (int8*)runtime·malloc(ERRMAX*sizeof(int8)); 22 23 // Initialize stack for handling strings from the 24 // errstr system call, as used in package syscall. 25 mp->errstr = (byte*)runtime·malloc(ERRMAX*sizeof(byte)); 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 // Mask all SSE floating-point exceptions 34 // when running on the 64-bit kernel. 35 runtime·setfpmasks(); 36 } 37 38 // Called from dropm to undo the effect of an minit. 39 void 40 runtime·unminit(void) 41 { 42 } 43 44 45 static int32 46 getproccount(void) 47 { 48 int32 fd, i, n, ncpu; 49 byte buf[2048]; 50 51 fd = runtime·open("/dev/sysstat", OREAD, 0); 52 if(fd < 0) 53 return 1; 54 ncpu = 0; 55 for(;;) { 56 n = runtime·read(fd, buf, sizeof buf); 57 if(n <= 0) 58 break; 59 for(i = 0; i < n; i++) { 60 if(buf[i] == '\n') 61 ncpu++; 62 } 63 } 64 runtime·close(fd); 65 return ncpu > 0 ? ncpu : 1; 66 } 67 68 static int32 69 getpid(void) 70 { 71 byte b[20], *c; 72 int32 fd; 73 74 runtime·memclr(b, sizeof(b)); 75 fd = runtime·open("#c/pid", 0, 0); 76 if(fd >= 0) { 77 runtime·read(fd, b, sizeof(b)); 78 runtime·close(fd); 79 } 80 c = b; 81 while(*c == ' ' || *c == '\t') 82 c++; 83 return runtime·atoi(c); 84 } 85 86 void 87 runtime·osinit(void) 88 { 89 runtime·ncpu = getproccount(); 90 m->procid = getpid(); 91 runtime·notify(runtime·sigtramp); 92 } 93 94 void 95 runtime·crash(void) 96 { 97 runtime·notify(nil); 98 *(int32*)0 = 0; 99 } 100 101 void 102 runtime·get_random_data(byte **rnd, int32 *rnd_len) 103 { 104 *rnd = nil; 105 *rnd_len = 0; 106 } 107 108 void 109 runtime·goenvs(void) 110 { 111 } 112 113 void 114 runtime·initsig(void) 115 { 116 } 117 118 #pragma textflag 7 119 void 120 runtime·osyield(void) 121 { 122 runtime·sleep(0); 123 } 124 125 void 126 runtime·usleep(uint32 µs) 127 { 128 uint32 ms; 129 130 ms = µs/1000; 131 if(ms == 0) 132 ms = 1; 133 runtime·sleep(ms); 134 } 135 136 void 137 time·now(int64 sec, int32 nsec) 138 { 139 int64 ns; 140 141 ns = runtime·nanotime(); 142 sec = ns / 1000000000LL; 143 nsec = ns - sec * 1000000000LL; 144 FLUSH(&sec); 145 FLUSH(&nsec); 146 } 147 148 void 149 runtime·itoa(int32 n, byte *p, uint32 len) 150 { 151 byte *q, c; 152 uint32 i; 153 154 if(len <= 1) 155 return; 156 157 runtime·memclr(p, len); 158 q = p; 159 160 if(n==0) { 161 *q++ = '0'; 162 USED(q); 163 return; 164 } 165 if(n < 0) { 166 *q++ = '-'; 167 p++; 168 n = -n; 169 } 170 for(i=0; n > 0 && i < len; i++) { 171 *q++ = '0' + (n%10); 172 n = n/10; 173 } 174 for(q--; q >= p; ) { 175 c = *p; 176 *p++ = *q; 177 *q-- = c; 178 } 179 } 180 181 void 182 runtime·goexitsall(int8 *status) 183 { 184 M *mp; 185 int32 pid; 186 187 pid = getpid(); 188 for(mp=runtime·atomicloadp(&runtime·allm); mp; mp=mp->alllink) 189 if(mp->procid != pid) 190 runtime·postnote(mp->procid, status); 191 } 192 193 int32 194 runtime·postnote(int32 pid, int8* msg) 195 { 196 int32 fd, len; 197 uint8 buf[128]; 198 uint8 tmp[16]; 199 uint8 *p, *q; 200 201 runtime·memclr(buf, sizeof buf); 202 203 /* build path string /proc/pid/note */ 204 q = tmp; 205 p = buf; 206 runtime·itoa(pid, tmp, sizeof tmp); 207 runtime·memmove((void*)p, (void*)"/proc/", 6); 208 for(p += 6; *p++ = *q++; ); 209 p--; 210 runtime·memmove((void*)p, (void*)"/note", 5); 211 212 fd = runtime·open((int8*)buf, OWRITE, 0); 213 if(fd < 0) 214 return -1; 215 216 len = runtime·findnull((byte*)msg); 217 if(runtime·write(fd, msg, len) != len) { 218 runtime·close(fd); 219 return -1; 220 } 221 runtime·close(fd); 222 return 0; 223 } 224 225 void 226 runtime·exit(int32 e) 227 { 228 byte tmp[16]; 229 int8 *status; 230 231 if(e == 0) 232 status = ""; 233 else { 234 /* build error string */ 235 runtime·itoa(e, tmp, sizeof tmp); 236 status = (int8*)tmp; 237 } 238 239 runtime·goexitsall(status); 240 runtime·exits(status); 241 } 242 243 void 244 runtime·newosproc(M *mp, void *stk) 245 { 246 mp->tls[0] = mp->id; // so 386 asm can find it 247 if(0){ 248 runtime·printf("newosproc stk=%p m=%p g=%p rfork=%p id=%d/%d ostk=%p\n", 249 stk, mp, mp->g0, runtime·rfork, mp->id, (int32)mp->tls[0], &mp); 250 } 251 252 if(runtime·rfork(RFPROC|RFMEM|RFNOWAIT, stk, mp, mp->g0, runtime·mstart) < 0) 253 runtime·throw("newosproc: rfork failed"); 254 } 255 256 uintptr 257 runtime·semacreate(void) 258 { 259 return 1; 260 } 261 262 int32 263 runtime·semasleep(int64 ns) 264 { 265 int32 ret; 266 int32 ms; 267 268 if(ns >= 0) { 269 if(ns/1000000 > 0x7fffffffll) 270 ms = 0x7fffffff; 271 else 272 ms = ns/1000000; 273 ret = runtime·plan9_tsemacquire(&m->waitsemacount, ms); 274 if(ret == 1) 275 return 0; // success 276 return -1; // timeout or interrupted 277 } 278 279 while(runtime·plan9_semacquire(&m->waitsemacount, 1) < 0) { 280 /* interrupted; try again (c.f. lock_sema.c) */ 281 } 282 return 0; // success 283 } 284 285 void 286 runtime·semawakeup(M *mp) 287 { 288 runtime·plan9_semrelease(&mp->waitsemacount, 1); 289 } 290 291 void 292 os·sigpipe(void) 293 { 294 runtime·throw("too many writes on closed pipe"); 295 } 296 297 void 298 runtime·sigpanic(void) 299 { 300 if(g->sigpc == 0) 301 runtime·panicstring("call of nil func value"); 302 runtime·panicstring(m->notesig); 303 304 if(g->sig == 1 || g->sig == 2) 305 runtime·throw("fault"); 306 } 307 308 int32 309 runtime·read(int32 fd, void *buf, int32 nbytes) 310 { 311 return runtime·pread(fd, buf, nbytes, -1LL); 312 } 313 314 int32 315 runtime·write(int32 fd, void *buf, int32 nbytes) 316 { 317 return runtime·pwrite(fd, buf, nbytes, -1LL); 318 } 319 320 uintptr 321 runtime·memlimit(void) 322 { 323 return 0; 324 } 325 326 void 327 runtime·setprof(bool on) 328 { 329 USED(on); 330 } 331 332 static int8 badcallback[] = "runtime: cgo callback on thread not created by Go.\n"; 333 334 // This runs on a foreign stack, without an m or a g. No stack split. 335 #pragma textflag 7 336 void 337 runtime·badcallback(void) 338 { 339 runtime·pwrite(2, badcallback, sizeof badcallback - 1, -1LL); 340 } 341 342 static int8 badsignal[] = "runtime: signal received on thread not created by Go.\n"; 343 344 // This runs on a foreign stack, without an m or a g. No stack split. 345 #pragma textflag 7 346 void 347 runtime·badsignal(void) 348 { 349 runtime·pwrite(2, badsignal, sizeof badsignal - 1, -1LL); 350 runtime·exits(badsignal); 351 }