// Copyright 2010 The Go Authors. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. #include #include #include "runtime.h" #include "go-assert.h" /* For targets which don't have the required sync support. Really these should be provided by gcc itself. FIXME. */ #if !defined (HAVE_SYNC_BOOL_COMPARE_AND_SWAP_4) || !defined (HAVE_SYNC_FETCH_AND_ADD_4) static pthread_mutex_t sync_lock = PTHREAD_MUTEX_INITIALIZER; #endif #ifndef HAVE_SYNC_BOOL_COMPARE_AND_SWAP_4 _Bool __sync_bool_compare_and_swap_4 (uint32*, uint32, uint32) __attribute__ ((visibility ("hidden"))); _Bool __sync_bool_compare_and_swap_4 (uint32* ptr, uint32 old, uint32 new) { int i; _Bool ret; i = pthread_mutex_lock (&sync_lock); __go_assert (i == 0); if (*ptr != old) ret = 0; else { *ptr = new; ret = 1; } i = pthread_mutex_unlock (&sync_lock); __go_assert (i == 0); return ret; } #endif #ifndef HAVE_SYNC_FETCH_AND_ADD_4 uint32 __sync_fetch_and_add_4 (uint32*, uint32) __attribute__ ((visibility ("hidden"))); uint32 __sync_fetch_and_add_4 (uint32* ptr, uint32 add) { int i; uint32 ret; i = pthread_mutex_lock (&sync_lock); __go_assert (i == 0); ret = *ptr; *ptr += add; i = pthread_mutex_unlock (&sync_lock); __go_assert (i == 0); return ret; } #endif // Called to initialize a new m (including the bootstrap m). void runtime_minit(void) { byte* stack; size_t stacksize; stack_t ss; // Initialize signal handling. runtime_m()->gsignal = runtime_malg(32*1024, &stack, &stacksize); // OS X wants >=8K, Linux >=2K ss.ss_sp = stack; ss.ss_flags = 0; ss.ss_size = stacksize; if(sigaltstack(&ss, nil) < 0) *(int *)0xf1 = 0xf1; } // Temporary functions, which will be removed when we stop using // condition variables. void runtime_cond_wait(pthread_cond_t* cond, pthread_mutex_t* mutex) { int i; runtime_entersyscall(); i = pthread_cond_wait(cond, mutex); if(i != 0) runtime_throw("pthread_cond_wait"); i = pthread_mutex_unlock(mutex); if(i != 0) runtime_throw("pthread_mutex_unlock"); runtime_exitsyscall(); i = pthread_mutex_lock(mutex); if(i != 0) runtime_throw("pthread_mutex_lock"); }