thread.c 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  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. #include <errno.h>
  5. #include <signal.h>
  6. #include <sys/time.h>
  7. #include <sys/resource.h>
  8. #include "runtime.h"
  9. #include "go-assert.h"
  10. /* For targets which don't have the required sync support. Really
  11. these should be provided by gcc itself. FIXME. */
  12. #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)
  13. static pthread_mutex_t sync_lock = PTHREAD_MUTEX_INITIALIZER;
  14. #endif
  15. #ifndef HAVE_SYNC_BOOL_COMPARE_AND_SWAP_4
  16. _Bool
  17. __sync_bool_compare_and_swap_4 (uint32*, uint32, uint32)
  18. __attribute__ ((visibility ("hidden")));
  19. _Bool
  20. __sync_bool_compare_and_swap_4 (uint32* ptr, uint32 old, uint32 new)
  21. {
  22. int i;
  23. _Bool ret;
  24. i = pthread_mutex_lock (&sync_lock);
  25. __go_assert (i == 0);
  26. if (*ptr != old)
  27. ret = 0;
  28. else
  29. {
  30. *ptr = new;
  31. ret = 1;
  32. }
  33. i = pthread_mutex_unlock (&sync_lock);
  34. __go_assert (i == 0);
  35. return ret;
  36. }
  37. #endif
  38. #ifndef HAVE_SYNC_BOOL_COMPARE_AND_SWAP_8
  39. _Bool
  40. __sync_bool_compare_and_swap_8 (uint64*, uint64, uint64)
  41. __attribute__ ((visibility ("hidden")));
  42. _Bool
  43. __sync_bool_compare_and_swap_8 (uint64* ptr, uint64 old, uint64 new)
  44. {
  45. int i;
  46. _Bool ret;
  47. i = pthread_mutex_lock (&sync_lock);
  48. __go_assert (i == 0);
  49. if (*ptr != old)
  50. ret = 0;
  51. else
  52. {
  53. *ptr = new;
  54. ret = 1;
  55. }
  56. i = pthread_mutex_unlock (&sync_lock);
  57. __go_assert (i == 0);
  58. return ret;
  59. }
  60. #endif
  61. #ifndef HAVE_SYNC_FETCH_AND_ADD_4
  62. uint32
  63. __sync_fetch_and_add_4 (uint32*, uint32)
  64. __attribute__ ((visibility ("hidden")));
  65. uint32
  66. __sync_fetch_and_add_4 (uint32* ptr, uint32 add)
  67. {
  68. int i;
  69. uint32 ret;
  70. i = pthread_mutex_lock (&sync_lock);
  71. __go_assert (i == 0);
  72. ret = *ptr;
  73. *ptr += add;
  74. i = pthread_mutex_unlock (&sync_lock);
  75. __go_assert (i == 0);
  76. return ret;
  77. }
  78. #endif
  79. #ifndef HAVE_SYNC_ADD_AND_FETCH_8
  80. uint64
  81. __sync_add_and_fetch_8 (uint64*, uint64)
  82. __attribute__ ((visibility ("hidden")));
  83. uint64
  84. __sync_add_and_fetch_8 (uint64* ptr, uint64 add)
  85. {
  86. int i;
  87. uint64 ret;
  88. i = pthread_mutex_lock (&sync_lock);
  89. __go_assert (i == 0);
  90. *ptr += add;
  91. ret = *ptr;
  92. i = pthread_mutex_unlock (&sync_lock);
  93. __go_assert (i == 0);
  94. return ret;
  95. }
  96. #endif
  97. uintptr
  98. runtime_memlimit(void)
  99. {
  100. struct rlimit rl;
  101. uintptr used;
  102. if(getrlimit(RLIMIT_AS, &rl) != 0)
  103. return 0;
  104. if(rl.rlim_cur >= 0x7fffffff)
  105. return 0;
  106. // Estimate our VM footprint excluding the heap.
  107. // Not an exact science: use size of binary plus
  108. // some room for thread stacks.
  109. used = (64<<20);
  110. if(used >= rl.rlim_cur)
  111. return 0;
  112. // If there's not at least 16 MB left, we're probably
  113. // not going to be able to do much. Treat as no limit.
  114. rl.rlim_cur -= used;
  115. if(rl.rlim_cur < (16<<20))
  116. return 0;
  117. return rl.rlim_cur - used;
  118. }