* const-uniq-1.c: Expand regex to match AIX XCOFF labels.
[official-gcc.git] / libgo / runtime / thread.c
blob12d009926e316c75f1b662f7bfc173e0c3dc94d0
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.
5 #include <errno.h>
6 #include <signal.h>
7 #include <sys/time.h>
8 #include <sys/resource.h>
10 #include "runtime.h"
11 #include "go-assert.h"
13 /* For targets which don't have the required sync support. Really
14 these should be provided by gcc itself. FIXME. */
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)
18 static pthread_mutex_t sync_lock = PTHREAD_MUTEX_INITIALIZER;
20 #endif
22 #ifndef HAVE_SYNC_BOOL_COMPARE_AND_SWAP_4
24 _Bool
25 __sync_bool_compare_and_swap_4 (uint32*, uint32, uint32)
26 __attribute__ ((visibility ("hidden")));
28 _Bool
29 __sync_bool_compare_and_swap_4 (uint32* ptr, uint32 old, uint32 new)
31 int i;
32 _Bool ret;
34 i = pthread_mutex_lock (&sync_lock);
35 __go_assert (i == 0);
37 if (*ptr != old)
38 ret = 0;
39 else
41 *ptr = new;
42 ret = 1;
45 i = pthread_mutex_unlock (&sync_lock);
46 __go_assert (i == 0);
48 return ret;
51 #endif
53 #ifndef HAVE_SYNC_BOOL_COMPARE_AND_SWAP_8
55 _Bool
56 __sync_bool_compare_and_swap_8 (uint64*, uint64, uint64)
57 __attribute__ ((visibility ("hidden")));
59 _Bool
60 __sync_bool_compare_and_swap_8 (uint64* ptr, uint64 old, uint64 new)
62 int i;
63 _Bool ret;
65 i = pthread_mutex_lock (&sync_lock);
66 __go_assert (i == 0);
68 if (*ptr != old)
69 ret = 0;
70 else
72 *ptr = new;
73 ret = 1;
76 i = pthread_mutex_unlock (&sync_lock);
77 __go_assert (i == 0);
79 return ret;
82 #endif
84 #ifndef HAVE_SYNC_FETCH_AND_ADD_4
86 uint32
87 __sync_fetch_and_add_4 (uint32*, uint32)
88 __attribute__ ((visibility ("hidden")));
90 uint32
91 __sync_fetch_and_add_4 (uint32* ptr, uint32 add)
93 int i;
94 uint32 ret;
96 i = pthread_mutex_lock (&sync_lock);
97 __go_assert (i == 0);
99 ret = *ptr;
100 *ptr += add;
102 i = pthread_mutex_unlock (&sync_lock);
103 __go_assert (i == 0);
105 return ret;
108 #endif
110 #ifndef HAVE_SYNC_ADD_AND_FETCH_8
112 uint64
113 __sync_add_and_fetch_8 (uint64*, uint64)
114 __attribute__ ((visibility ("hidden")));
116 uint64
117 __sync_add_and_fetch_8 (uint64* ptr, uint64 add)
119 int i;
120 uint64 ret;
122 i = pthread_mutex_lock (&sync_lock);
123 __go_assert (i == 0);
125 *ptr += add;
126 ret = *ptr;
128 i = pthread_mutex_unlock (&sync_lock);
129 __go_assert (i == 0);
131 return ret;
134 #endif
136 // Called to initialize a new m (including the bootstrap m).
137 void
138 runtime_minit(void)
140 byte* stack;
141 size_t stacksize;
142 stack_t ss;
143 sigset_t sigs;
145 // Initialize signal handling.
146 runtime_m()->gsignal = runtime_malg(32*1024, &stack, &stacksize); // OS X wants >=8K, Linux >=2K
147 ss.ss_sp = stack;
148 ss.ss_flags = 0;
149 ss.ss_size = stacksize;
150 if(sigaltstack(&ss, nil) < 0)
151 *(int *)0xf1 = 0xf1;
152 if (sigemptyset(&sigs) != 0)
153 runtime_throw("sigemptyset");
154 sigprocmask(SIG_SETMASK, &sigs, nil);
157 uintptr
158 runtime_memlimit(void)
160 struct rlimit rl;
161 uintptr used;
163 if(getrlimit(RLIMIT_AS, &rl) != 0)
164 return 0;
165 if(rl.rlim_cur >= 0x7fffffff)
166 return 0;
168 // Estimate our VM footprint excluding the heap.
169 // Not an exact science: use size of binary plus
170 // some room for thread stacks.
171 used = (64<<20);
172 if(used >= rl.rlim_cur)
173 return 0;
175 // If there's not at least 16 MB left, we're probably
176 // not going to be able to do much. Treat as no limit.
177 rl.rlim_cur -= used;
178 if(rl.rlim_cur < (16<<20))
179 return 0;
181 return rl.rlim_cur - used;