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