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  }