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  };