github.com/prattmic/llgo-embedded@v0.0.0-20150820070356-41cfecea0e1e/third_party/gofrontend/libgo/runtime/thread.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 <errno.h>
     6  #include <signal.h>
     7  #include <sys/time.h>
     8  #include <sys/resource.h>
     9  
    10  #include "runtime.h"
    11  #include "go-assert.h"
    12  
    13  /* For targets which don't have the required sync support.  Really
    14     these should be provided by gcc itself.  FIXME.  */
    15  
    16  #if !defined (HAVE_SYNC_BOOL_COMPARE_AND_SWAP_4) || !defined (HAVE_SYNC_BOOL_COMPARE_AND_SWAP_8) || !defined (HAVE_SYNC_FETCH_AND_ADD_4) || !defined (HAVE_SYNC_ADD_AND_FETCH_8)
    17  
    18  /* FIXME(prattmic): see below */
    19  #if 0
    20  static pthread_mutex_t sync_lock = PTHREAD_MUTEX_INITIALIZER;
    21  #endif
    22  
    23  #endif
    24  
    25  #ifndef HAVE_SYNC_BOOL_COMPARE_AND_SWAP_4
    26  
    27  _Bool
    28  __sync_bool_compare_and_swap_4 (uint32*, uint32, uint32)
    29    __attribute__ ((visibility ("hidden")));
    30  
    31  _Bool
    32  __sync_bool_compare_and_swap_4 (uint32* ptr, uint32 old, uint32 new)
    33  {
    34    int i;
    35    _Bool ret;
    36  
    37    i = pthread_mutex_lock (&sync_lock);
    38    __go_assert (i == 0);
    39  
    40    if (*ptr != old)
    41      ret = 0;
    42    else
    43      {
    44        *ptr = new;
    45        ret = 1;
    46      }
    47  
    48    i = pthread_mutex_unlock (&sync_lock);
    49    __go_assert (i == 0);
    50  
    51    return ret;
    52  }
    53  
    54  #endif
    55  
    56  #ifndef HAVE_SYNC_BOOL_COMPARE_AND_SWAP_8
    57  
    58  _Bool
    59  __sync_bool_compare_and_swap_8 (uint64*, uint64, uint64)
    60    __attribute__ ((visibility ("hidden")));
    61  
    62  _Bool
    63  __sync_bool_compare_and_swap_8 (uint64* ptr, uint64 old, uint64 new)
    64  {
    65    int i;
    66    _Bool ret;
    67  
    68    i = pthread_mutex_lock (&sync_lock);
    69    __go_assert (i == 0);
    70  
    71    if (*ptr != old)
    72      ret = 0;
    73    else
    74      {
    75        *ptr = new;
    76        ret = 1;
    77      }
    78  
    79    i = pthread_mutex_unlock (&sync_lock);
    80    __go_assert (i == 0);
    81  
    82    return ret;
    83  }
    84  
    85  #endif
    86  
    87  #ifndef HAVE_SYNC_FETCH_AND_ADD_4
    88  
    89  uint32
    90  __sync_fetch_and_add_4 (uint32*, uint32)
    91    __attribute__ ((visibility ("hidden")));
    92  
    93  uint32
    94  __sync_fetch_and_add_4 (uint32* ptr, uint32 add)
    95  {
    96    int i;
    97    uint32 ret;
    98  
    99    i = pthread_mutex_lock (&sync_lock);
   100    __go_assert (i == 0);
   101  
   102    ret = *ptr;
   103    *ptr += add;
   104  
   105    i = pthread_mutex_unlock (&sync_lock);
   106    __go_assert (i == 0);
   107  
   108    return ret;
   109  }
   110  
   111  #endif
   112  
   113  #ifndef HAVE_SYNC_ADD_AND_FETCH_8
   114  
   115  /*
   116   * FIXME(prattmic): LLVM thinks this is overriding a builtin, even though it
   117   * doesn't provide this builtin.
   118   */
   119  #if 0
   120  long long
   121  __sync_add_and_fetch_8 (volatile long long*, long long, ...)
   122    __attribute__ ((visibility ("hidden")));
   123  
   124  long long
   125  __sync_add_and_fetch_8 (volatile long long* ptr, long long add, ...)
   126  {
   127    int i;
   128    uint64 ret;
   129  
   130    i = pthread_mutex_lock (&sync_lock);
   131    __go_assert (i == 0);
   132  
   133    *ptr += add;
   134    ret = *ptr;
   135  
   136    i = pthread_mutex_unlock (&sync_lock);
   137    __go_assert (i == 0);
   138  
   139    return ret;
   140  }
   141  #endif
   142  
   143  #endif
   144  
   145  uintptr
   146  runtime_memlimit(void)
   147  {
   148  	struct rlimit rl;
   149  	uintptr used;
   150  
   151  	if(getrlimit(RLIMIT_AS, &rl) != 0)
   152  		return 0;
   153  	if(rl.rlim_cur >= 0x7fffffff)
   154  		return 0;
   155  
   156  	// Estimate our VM footprint excluding the heap.
   157  	// Not an exact science: use size of binary plus
   158  	// some room for thread stacks.
   159  	used = (64<<20);
   160  	if(used >= rl.rlim_cur)
   161  		return 0;
   162  
   163  	// If there's not at least 16 MB left, we're probably
   164  	// not going to be able to do much.  Treat as no limit.
   165  	rl.rlim_cur -= used;
   166  	if(rl.rlim_cur < (16<<20))
   167  		return 0;
   168  
   169  	return rl.rlim_cur - used;
   170  }