github.com/llvm-mirror/llgo@v0.0.0-20190322182713-bf6f0a60fce1/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  static pthread_mutex_t sync_lock = PTHREAD_MUTEX_INITIALIZER;
    19  
    20  #endif
    21  
    22  #ifndef HAVE_SYNC_BOOL_COMPARE_AND_SWAP_4
    23  
    24  _Bool
    25  __sync_bool_compare_and_swap_4 (uint32*, uint32, uint32)
    26    __attribute__ ((visibility ("hidden")));
    27  
    28  _Bool
    29  __sync_bool_compare_and_swap_4 (uint32* ptr, uint32 old, uint32 new)
    30  {
    31    int i;
    32    _Bool ret;
    33  
    34    i = pthread_mutex_lock (&sync_lock);
    35    __go_assert (i == 0);
    36  
    37    if (*ptr != old)
    38      ret = 0;
    39    else
    40      {
    41        *ptr = new;
    42        ret = 1;
    43      }
    44  
    45    i = pthread_mutex_unlock (&sync_lock);
    46    __go_assert (i == 0);
    47  
    48    return ret;
    49  }
    50  
    51  #endif
    52  
    53  #ifndef HAVE_SYNC_BOOL_COMPARE_AND_SWAP_8
    54  
    55  _Bool
    56  __sync_bool_compare_and_swap_8 (uint64*, uint64, uint64)
    57    __attribute__ ((visibility ("hidden")));
    58  
    59  _Bool
    60  __sync_bool_compare_and_swap_8 (uint64* ptr, uint64 old, uint64 new)
    61  {
    62    int i;
    63    _Bool ret;
    64  
    65    i = pthread_mutex_lock (&sync_lock);
    66    __go_assert (i == 0);
    67  
    68    if (*ptr != old)
    69      ret = 0;
    70    else
    71      {
    72        *ptr = new;
    73        ret = 1;
    74      }
    75  
    76    i = pthread_mutex_unlock (&sync_lock);
    77    __go_assert (i == 0);
    78  
    79    return ret;
    80  }
    81  
    82  #endif
    83  
    84  #ifndef HAVE_SYNC_FETCH_AND_ADD_4
    85  
    86  uint32
    87  __sync_fetch_and_add_4 (uint32*, uint32)
    88    __attribute__ ((visibility ("hidden")));
    89  
    90  uint32
    91  __sync_fetch_and_add_4 (uint32* ptr, uint32 add)
    92  {
    93    int i;
    94    uint32 ret;
    95  
    96    i = pthread_mutex_lock (&sync_lock);
    97    __go_assert (i == 0);
    98  
    99    ret = *ptr;
   100    *ptr += add;
   101  
   102    i = pthread_mutex_unlock (&sync_lock);
   103    __go_assert (i == 0);
   104  
   105    return ret;
   106  }
   107  
   108  #endif
   109  
   110  #ifndef HAVE_SYNC_ADD_AND_FETCH_8
   111  
   112  uint64
   113  __sync_add_and_fetch_8 (uint64*, uint64)
   114    __attribute__ ((visibility ("hidden")));
   115  
   116  uint64
   117  __sync_add_and_fetch_8 (uint64* ptr, uint64 add)
   118  {
   119    int i;
   120    uint64 ret;
   121  
   122    i = pthread_mutex_lock (&sync_lock);
   123    __go_assert (i == 0);
   124  
   125    *ptr += add;
   126    ret = *ptr;
   127  
   128    i = pthread_mutex_unlock (&sync_lock);
   129    __go_assert (i == 0);
   130  
   131    return ret;
   132  }
   133  
   134  #endif
   135  
   136  uintptr
   137  runtime_memlimit(void)
   138  {
   139  	struct rlimit rl;
   140  	uintptr used;
   141  
   142  	if(getrlimit(RLIMIT_AS, &rl) != 0)
   143  		return 0;
   144  	if(rl.rlim_cur >= 0x7fffffff)
   145  		return 0;
   146  
   147  	// Estimate our VM footprint excluding the heap.
   148  	// Not an exact science: use size of binary plus
   149  	// some room for thread stacks.
   150  	used = (64<<20);
   151  	if(used >= rl.rlim_cur)
   152  		return 0;
   153  
   154  	// If there's not at least 16 MB left, we're probably
   155  	// not going to be able to do much.  Treat as no limit.
   156  	rl.rlim_cur -= used;
   157  	if(rl.rlim_cur < (16<<20))
   158  		return 0;
   159  
   160  	return rl.rlim_cur - used;
   161  }