]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/gthr-nks.h
re PR target/37170 (gcc.dg/weak/weak-1.c)
[thirdparty/gcc.git] / gcc / gthr-nks.h
CommitLineData
61fec9ff
JB
1/* Threads compatibility routines for libgcc2 and libobjc. */
2/* Compile this one with gcc. */
f199d860 3/* Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
61fec9ff
JB
4
5This file is part of GCC.
6
f199d860
JB
7GCC is free software; you can redistribute it and/or modify it under
8the terms of the GNU General Public License as published by the Free
9Software Foundation; either version 2, or (at your option) any later
10version.
61fec9ff 11
f199d860
JB
12GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13WARRANTY; without even the implied warranty of MERCHANTABILITY or
14FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15for more details.
61fec9ff
JB
16
17You should have received a copy of the GNU General Public License
f199d860 18along with GCC; see the file COPYING. If not, write to the Free
366ccddb
KC
19Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
2002110-1301, USA. */
61fec9ff
JB
21
22/* As a special exception, if you link this library with other files,
23 some of which are compiled with GCC, to produce an executable,
24 this library does not by itself cause the resulting executable
25 to be covered by the GNU General Public License.
26 This exception does not however invalidate any other reasons why
27 the executable file might be covered by the GNU General Public License. */
28
f199d860
JB
29#ifndef GCC_GTHR_NKS_H
30#define GCC_GTHR_NKS_H
61fec9ff
JB
31
32/* NKS threads specific definitions.
8c27b7d4 33 Easy, since the interface is mostly one-to-one mapping. */
61fec9ff
JB
34
35#define __GTHREADS 1
36
37#define NKS_NO_INLINE_FUNCS
38#include <nksapi.h>
39#include <string.h>
40
41typedef NXKey_t __gthread_key_t;
42typedef NXMutex_t *__gthread_mutex_t;
f199d860 43typedef NXMutex_t *__gthread_recursive_mutex_t;
61fec9ff
JB
44
45#define __GTHREAD_MUTEX_INIT_FUNCTION __gthread_mutex_init_function
f199d860 46#define __GTHREAD_RECURSIVE_MUTEX_INIT_FUNCTION __gthread_recursive_mutex_init_function
61fec9ff
JB
47
48static inline int
49__gthread_active_p (void)
50{
51 return 1;
52}
53
54#ifdef _LIBOBJC
55
56/* This is the config.h file in libobjc/ */
57#include <config.h>
58
59#ifdef HAVE_SCHED_H
60# include <sched.h>
61#endif
62
63/* Key structure for maintaining thread specific storage */
64static NXKey_t _objc_thread_storage;
65
66/* Backend initialization functions */
67
8c27b7d4 68/* Initialize the threads subsystem. */
61fec9ff 69static inline int
f199d860 70__gthread_objc_init_thread_system (void)
61fec9ff 71{
f199d860
JB
72 /* Initialize the thread storage key. */
73 if (NXKeyCreate (NULL, NULL, &_objc_thread_storage) == 0)
61fec9ff
JB
74 return 0;
75 return -1;
76}
77
8c27b7d4 78/* Close the threads subsystem. */
61fec9ff 79static inline int
f199d860 80__gthread_objc_close_thread_system (void)
61fec9ff 81{
f199d860 82 if (NXKeyDelete (_objc_thread_storage) == 0)
61fec9ff
JB
83 return 0;
84 return -1;
85}
86
87/* Backend thread functions */
88
8c27b7d4 89/* Create a new thread of execution. */
61fec9ff 90static inline objc_thread_t
f199d860 91__gthread_objc_thread_detach (void (*func)(void *), void *arg)
61fec9ff
JB
92{
93 objc_thread_t thread_id;
94 NXContext_t context;
95 NXThreadId_t new_thread_handle;
96 int err;
97
f199d860 98 if ((context = NXContextAlloc (func, arg, NX_PRIO_MED, 0, 0, 0, &err)) == NULL)
61fec9ff 99 thread_id = NULL;
f199d860 100 else if (NXThreadCreate (context, NX_THR_DETACHED, &new_thread_handle) == 0)
61fec9ff
JB
101 thread_id = (objc_thread_t) new_thread_handle;
102 else {
f199d860 103 NXContextFree (context);
61fec9ff
JB
104 thread_id = NULL;
105 }
106
107 return thread_id;
108}
109
8c27b7d4 110/* Set the current thread's priority. */
61fec9ff 111static inline int
f199d860 112__gthread_objc_thread_set_priority (int priority)
61fec9ff 113{
f199d860 114 if (NXThreadSetPriority (NXThreadGetId (), priority) == 0)
61fec9ff
JB
115 return 0;
116 return -1;
117}
118
8c27b7d4 119/* Return the current thread's priority. */
61fec9ff 120static inline int
f199d860 121__gthread_objc_thread_get_priority (void)
61fec9ff
JB
122{
123 int priority;
124
f199d860 125 if (NXThreadGetPriority (NXThreadGetId (), &priority) == 0)
61fec9ff
JB
126 return priority;
127 return -1;
128}
129
8c27b7d4 130/* Yield our process time to another thread. */
61fec9ff 131static inline void
f199d860 132__gthread_objc_thread_yield (void)
61fec9ff 133{
f199d860 134 NXThreadYield ();
61fec9ff
JB
135}
136
8c27b7d4 137/* Terminate the current thread. */
61fec9ff 138static inline int
f199d860 139__gthread_objc_thread_exit (void)
61fec9ff
JB
140{
141 /* exit the thread */
f199d860 142 NXThreadExit (&__objc_thread_exit_status);
61fec9ff
JB
143
144 /* Failed if we reached here */
145 return -1;
146}
147
8c27b7d4 148/* Returns an integer value which uniquely describes a thread. */
61fec9ff 149static inline objc_thread_t
f199d860 150__gthread_objc_thread_id (void)
61fec9ff 151{
f199d860 152 (objc_thread_t) NXThreadGetId ();
61fec9ff
JB
153}
154
8c27b7d4 155/* Sets the thread's local storage pointer. */
61fec9ff 156static inline int
f199d860 157__gthread_objc_thread_set_data (void *value)
61fec9ff 158{
f199d860 159 return NXKeySetValue (_objc_thread_storage, value);
61fec9ff
JB
160}
161
8c27b7d4 162/* Returns the thread's local storage pointer. */
61fec9ff 163static inline void *
f199d860 164__gthread_objc_thread_get_data (void)
61fec9ff
JB
165{
166 void *value;
167
f199d860 168 if (NXKeyGetValue (_objc_thread_storage, &value) == 0)
61fec9ff
JB
169 return value;
170 return NULL;
171}
172
173/* Backend mutex functions */
174
8c27b7d4 175/* Allocate a mutex. */
61fec9ff 176static inline int
f199d860 177__gthread_objc_mutex_allocate (objc_mutex_t mutex)
61fec9ff 178{
f199d860 179 static const NX_LOCK_INFO_ALLOC (info, "GNU ObjC", 0);
61fec9ff 180
019275a2 181 if ((mutex->backend = NXMutexAlloc (0, 0, &info)) == NULL)
61fec9ff
JB
182 return 0;
183 return -1;
184}
185
8c27b7d4 186/* Deallocate a mutex. */
61fec9ff 187static inline int
f199d860 188__gthread_objc_mutex_deallocate (objc_mutex_t mutex)
61fec9ff 189{
f199d860
JB
190 while (NXMutexIsOwned ((NXMutex_t *)mutex->backend))
191 NXUnlock ((NXMutex_t *)mutex->backend);
192 if (NXMutexFree ((NXMutex_t *)mutex->backend) != 0)
61fec9ff
JB
193 return -1;
194 mutex->backend = NULL;
195 return 0;
196}
197
8c27b7d4 198/* Grab a lock on a mutex. */
61fec9ff 199static inline int
f199d860 200__gthread_objc_mutex_lock (objc_mutex_t mutex)
61fec9ff 201{
f199d860 202 return NXLock ((NXMutex_t *)mutex->backend);
61fec9ff
JB
203}
204
8c27b7d4 205/* Try to grab a lock on a mutex. */
61fec9ff 206static inline int
f199d860 207__gthread_objc_mutex_trylock (objc_mutex_t mutex)
61fec9ff 208{
f199d860 209 if (!NXTryLock ((NXMutex_t *)mutex->backend))
61fec9ff
JB
210 return -1;
211 return 0;
212}
213
214/* Unlock the mutex */
215static inline int
f199d860 216__gthread_objc_mutex_unlock (objc_mutex_t mutex)
61fec9ff 217{
f199d860 218 return NXUnlock ((NXMutex_t *)mutex->backend);
61fec9ff
JB
219}
220
221/* Backend condition mutex functions */
222
8c27b7d4 223/* Allocate a condition. */
61fec9ff 224static inline int
f199d860 225__gthread_objc_condition_allocate (objc_condition_t condition)
61fec9ff 226{
f199d860 227 condition->backend = NXCondAlloc (NULL);
61fec9ff
JB
228 if (condition->backend == NULL)
229 return -1;
230
231 return 0;
232}
233
8c27b7d4 234/* Deallocate a condition. */
61fec9ff 235static inline int
f199d860 236__gthread_objc_condition_deallocate (objc_condition_t condition)
61fec9ff 237{
f199d860 238 if (NXCondFree ((NXCond_t *)condition->backend) != 0)
61fec9ff
JB
239 return -1;
240 condition->backend = NULL;
241 return 0;
242}
243
244/* Wait on the condition */
245static inline int
f199d860 246__gthread_objc_condition_wait (objc_condition_t condition, objc_mutex_t mutex)
61fec9ff 247{
f199d860 248 return NXCondWait ((NXCond_t *)condition->backend, (NXMutex_t *)mutex->backend);
61fec9ff
JB
249}
250
8c27b7d4 251/* Wake up all threads waiting on this condition. */
61fec9ff 252static inline int
f199d860 253__gthread_objc_condition_broadcast (objc_condition_t condition)
61fec9ff 254{
f199d860 255 return NXCondBroadcast ((NXCond_t *)condition->backend);
61fec9ff
JB
256}
257
8c27b7d4 258/* Wake up one thread waiting on this condition. */
61fec9ff 259static inline int
f199d860 260__gthread_objc_condition_signal (objc_condition_t condition)
61fec9ff 261{
f199d860 262 return NXCondSignal ((NXCond_t *)condition->backend);
61fec9ff
JB
263}
264
265#else /* _LIBOBJC */
266
267#if defined(__cplusplus)
268# include <bits/atomicity.h>
269/* The remaining conditions here are temporary until there is
270 an application accessible atomic operations API set... */
271#elif defined(_M_IA64) || defined(__ia64__)
272# include <../libstdc++-v3/config/cpu/ia64/bits/atomicity.h>
273#elif defined(_M_IX86) || defined(__i486__)
274# include <../libstdc++-v3/config/cpu/i486/bits/atomicity.h>
275#elif defined(_M_AMD64) || defined(__x86_64__)
276# include <../libstdc++-v3/config/cpu/x86-64/bits/atomicity.h>
277#endif
278
279typedef volatile long __gthread_once_t;
280
281#define __GTHREAD_ONCE_INIT 0
282
283static inline int
284__gthread_once (__gthread_once_t *once, void (*func) (void))
285{
f199d860 286 if (__compare_and_swap (once, 0, 1))
61fec9ff
JB
287 {
288 func();
289 *once |= 2;
290 }
291 else
292 {
f199d860
JB
293 while (!(*once & 2))
294 NXThreadYield ();
61fec9ff
JB
295 }
296 return 0;
297}
298
299static inline int
300__gthread_key_create (__gthread_key_t *key, void (*dtor) (void *))
301{
302 return NXKeyCreate (dtor, NULL, key);
303}
304
305static inline int
306__gthread_key_dtor (__gthread_key_t key, void *ptr)
307{
f199d860 308 /* Just reset the key value to zero. */
61fec9ff
JB
309 if (ptr)
310 return NXKeySetValue (key, NULL);
311 return 0;
312}
313
314static inline int
315__gthread_key_delete (__gthread_key_t key)
316{
317 return NXKeyDelete (key);
318}
319
320static inline void *
321__gthread_getspecific (__gthread_key_t key)
322{
323 void *value;
324
f199d860 325 if (NXKeyGetValue (key, &value) == 0)
61fec9ff
JB
326 return value;
327 return NULL;
328}
329
330static inline int
331__gthread_setspecific (__gthread_key_t key, const void *ptr)
332{
f199d860 333 return NXKeySetValue (key, (void *)ptr);
61fec9ff
JB
334}
335
336static inline void
337__gthread_mutex_init_function (__gthread_mutex_t *mutex)
338{
f199d860 339 static const NX_LOCK_INFO_ALLOC (info, "GTHREADS", 0);
61fec9ff 340
f199d860 341 *mutex = NXMutexAlloc (0, 0, &info);
61fec9ff
JB
342}
343
4dabf736
JB
344static inline int
345__gthread_mutex_destroy (__gthread_mutex_t * UNUSED(mutex))
346{
347 return 0;
348}
349
61fec9ff
JB
350static inline int
351__gthread_mutex_lock (__gthread_mutex_t *mutex)
352{
f199d860 353 return NXLock (*mutex);
61fec9ff
JB
354}
355
356static inline int
357__gthread_mutex_trylock (__gthread_mutex_t *mutex)
358{
f199d860 359 if (NXTryLock (*mutex))
61fec9ff
JB
360 return 0;
361 return -1;
362}
363
364static inline int
365__gthread_mutex_unlock (__gthread_mutex_t *mutex)
366{
f199d860
JB
367 return NXUnlock (*mutex);
368}
369
370static inline void
371__gthread_recursive_mutex_init_function (__gthread_recursive_mutex_t *mutex)
372{
373 static const NX_LOCK_INFO_ALLOC (info, "GTHREADS", 0);
374
375 *mutex = NXMutexAlloc (NX_MUTEX_RECURSIVE, 0, &info);
376}
377
378static inline int
379__gthread_recursive_mutex_lock (__gthread_recursive_mutex_t *mutex)
380{
381 return NXLock (*mutex);
382}
383
384static inline int
385__gthread_recursive_mutex_trylock (__gthread_recursive_mutex_t *mutex)
386{
387 if (NXTryLock (*mutex))
388 return 0;
389 return -1;
390}
391
392static inline int
393__gthread_recursive_mutex_unlock (__gthread_recursive_mutex_t *mutex)
394{
395 return NXUnlock (*mutex);
61fec9ff
JB
396}
397
398#endif /* _LIBOBJC */
399
f199d860 400#endif /* not GCC_GTHR_NKS_H */