github.com/zach-klippenstein/go@v0.0.0-20150108044943-fcfbeb3adf58/src/runtime/os1_nacl.go (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  package runtime
     6  
     7  import "unsafe"
     8  
     9  // Called to initialize a new m (including the bootstrap m).
    10  // Called on the parent thread (main thread in case of bootstrap), can allocate memory.
    11  func mpreinit(mp *m) {
    12  	mp.gsignal = malg(32 * 1024)
    13  	mp.gsignal.m = mp
    14  }
    15  
    16  func sigtramp()
    17  
    18  // Called to initialize a new m (including the bootstrap m).
    19  // Called on the new thread, can not allocate memory.
    20  func minit() {
    21  	_g_ := getg()
    22  
    23  	// Initialize signal handling
    24  	ret := nacl_exception_stack(_g_.m.gsignal.stack.lo, 32*1024)
    25  	if ret < 0 {
    26  		print("runtime: nacl_exception_stack: error ", -ret, "\n")
    27  	}
    28  
    29  	ret = nacl_exception_handler(funcPC(sigtramp), nil)
    30  	if ret < 0 {
    31  		print("runtime: nacl_exception_handler: error ", -ret, "\n")
    32  	}
    33  }
    34  
    35  // Called from dropm to undo the effect of an minit.
    36  func unminit() {
    37  }
    38  
    39  func osinit() {
    40  	ncpu = 1
    41  	getg().m.procid = 2
    42  	//nacl_exception_handler(funcPC(sigtramp), nil);
    43  }
    44  
    45  func crash() {
    46  	*(*int32)(nil) = 0
    47  }
    48  
    49  //go:nosplit
    50  func getRandomData(r []byte) {
    51  	// TODO: does nacl have a random source we can use?
    52  	extendRandom(r, 0)
    53  }
    54  
    55  func goenvs() {
    56  	goenvs_unix()
    57  }
    58  
    59  func initsig() {
    60  }
    61  
    62  //go:nosplit
    63  func usleep(us uint32) {
    64  	var ts timespec
    65  
    66  	ts.tv_sec = int64(us / 1e6)
    67  	ts.tv_nsec = int32(us%1e6) * 1e3
    68  	nacl_nanosleep(&ts, nil)
    69  }
    70  
    71  func mstart_nacl()
    72  
    73  func newosproc(mp *m, stk unsafe.Pointer) {
    74  	tls := (*[3]unsafe.Pointer)(unsafe.Pointer(&mp.tls))
    75  	tls[0] = unsafe.Pointer(mp.g0)
    76  	tls[1] = unsafe.Pointer(mp)
    77  	ret := nacl_thread_create(funcPC(mstart_nacl), stk, unsafe.Pointer(&tls[2]), nil)
    78  	if ret < 0 {
    79  		print("nacl_thread_create: error ", -ret, "\n")
    80  		throw("newosproc")
    81  	}
    82  }
    83  
    84  //go:nosplit
    85  func semacreate() uintptr {
    86  	var cond uintptr
    87  	systemstack(func() {
    88  		mu := nacl_mutex_create(0)
    89  		if mu < 0 {
    90  			print("nacl_mutex_create: error ", -mu, "\n")
    91  			throw("semacreate")
    92  		}
    93  		c := nacl_cond_create(0)
    94  		if c < 0 {
    95  			print("nacl_cond_create: error ", -cond, "\n")
    96  			throw("semacreate")
    97  		}
    98  		cond = uintptr(c)
    99  		_g_ := getg()
   100  		_g_.m.waitsemalock = uint32(mu)
   101  	})
   102  	return cond
   103  }
   104  
   105  //go:nosplit
   106  func semasleep(ns int64) int32 {
   107  	var ret int32
   108  
   109  	systemstack(func() {
   110  		_g_ := getg()
   111  		if nacl_mutex_lock(int32(_g_.m.waitsemalock)) < 0 {
   112  			throw("semasleep")
   113  		}
   114  
   115  		for _g_.m.waitsemacount == 0 {
   116  			if ns < 0 {
   117  				if nacl_cond_wait(int32(_g_.m.waitsema), int32(_g_.m.waitsemalock)) < 0 {
   118  					throw("semasleep")
   119  				}
   120  			} else {
   121  				var ts timespec
   122  				end := ns + nanotime()
   123  				ts.tv_sec = end / 1e9
   124  				ts.tv_nsec = int32(end % 1e9)
   125  				r := nacl_cond_timed_wait_abs(int32(_g_.m.waitsema), int32(_g_.m.waitsemalock), &ts)
   126  				if r == -_ETIMEDOUT {
   127  					nacl_mutex_unlock(int32(_g_.m.waitsemalock))
   128  					ret = -1
   129  					return
   130  				}
   131  				if r < 0 {
   132  					throw("semasleep")
   133  				}
   134  			}
   135  		}
   136  
   137  		_g_.m.waitsemacount = 0
   138  		nacl_mutex_unlock(int32(_g_.m.waitsemalock))
   139  		ret = 0
   140  	})
   141  	return ret
   142  }
   143  
   144  //go:nosplit
   145  func semawakeup(mp *m) {
   146  	systemstack(func() {
   147  		if nacl_mutex_lock(int32(mp.waitsemalock)) < 0 {
   148  			throw("semawakeup")
   149  		}
   150  		if mp.waitsemacount != 0 {
   151  			throw("semawakeup")
   152  		}
   153  		mp.waitsemacount = 1
   154  		nacl_cond_signal(int32(mp.waitsema))
   155  		nacl_mutex_unlock(int32(mp.waitsemalock))
   156  	})
   157  }
   158  
   159  func memlimit() uintptr {
   160  	return 0
   161  }
   162  
   163  // This runs on a foreign stack, without an m or a g.  No stack split.
   164  //go:nosplit
   165  func badsignal2() {
   166  	write(2, unsafe.Pointer(&badsignal1[0]), int32(len(badsignal1)))
   167  	exit(2)
   168  }
   169  
   170  var badsignal1 = []byte("runtime: signal received on thread not created by Go.\n")
   171  
   172  func madvise(addr unsafe.Pointer, n uintptr, flags int32) {}
   173  func munmap(addr unsafe.Pointer, n uintptr)               {}
   174  func resetcpuprofiler(hz int32)                           {}
   175  func sigdisable(uint32)                                   {}
   176  func sigenable(uint32)                                    {}
   177  func closeonexec(int32)                                   {}
   178  
   179  var writelock uint32 // test-and-set spin lock for write
   180  
   181  /*
   182  An attempt at IRT. Doesn't work. See end of sys_nacl_amd64.s.
   183  
   184  void (*nacl_irt_query)(void);
   185  
   186  int8 nacl_irt_basic_v0_1_str[] = "nacl-irt-basic-0.1";
   187  void *nacl_irt_basic_v0_1[6]; // exit, gettod, clock, nanosleep, sched_yield, sysconf
   188  int32 nacl_irt_basic_v0_1_size = sizeof(nacl_irt_basic_v0_1);
   189  
   190  int8 nacl_irt_memory_v0_3_str[] = "nacl-irt-memory-0.3";
   191  void *nacl_irt_memory_v0_3[3]; // mmap, munmap, mprotect
   192  int32 nacl_irt_memory_v0_3_size = sizeof(nacl_irt_memory_v0_3);
   193  
   194  int8 nacl_irt_thread_v0_1_str[] = "nacl-irt-thread-0.1";
   195  void *nacl_irt_thread_v0_1[3]; // thread_create, thread_exit, thread_nice
   196  int32 nacl_irt_thread_v0_1_size = sizeof(nacl_irt_thread_v0_1);
   197  */