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  }