]>
Commit | Line | Data |
---|---|---|
899905f6 | 1 | /* Threads compatibility routines for libgcc2 for VxWorks. */ |
7cc34889 MS |
2 | /* Compile this one with gcc. */ |
3 | /* Copyright (C) 1997 Free Software Foundation, Inc. | |
4 | Contributed by Mike Stump <mrs@wrs.com>. | |
5 | ||
6 | This file is part of GNU CC. | |
7 | ||
8 | GNU CC is free software; you can redistribute it and/or modify | |
9 | it under the terms of the GNU General Public License as published by | |
10 | the Free Software Foundation; either version 2, or (at your option) | |
11 | any later version. | |
12 | ||
13 | GNU CC is distributed in the hope that it will be useful, | |
14 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
16 | GNU General Public License for more details. | |
17 | ||
18 | You should have received a copy of the GNU General Public License | |
19 | along with GNU CC; see the file COPYING. If not, write to | |
20 | the Free Software Foundation, 59 Temple Place - Suite 330, | |
21 | Boston, MA 02111-1307, USA. */ | |
22 | ||
23 | /* As a special exception, if you link this library with other files, | |
24 | some of which are compiled with GCC, to produce an executable, | |
25 | this library does not by itself cause the resulting executable | |
26 | to be covered by the GNU General Public License. | |
27 | This exception does not however invalidate any other reasons why | |
28 | the executable file might be covered by the GNU General Public License. */ | |
29 | ||
30 | #ifndef __gthr_vxworks_h | |
31 | #define __gthr_vxworks_h | |
32 | ||
33 | /* POSIX threads specific definitions. | |
34 | Easy, since the interface is just one-to-one mapping. */ | |
35 | ||
36 | #define __GTHREADS 1 | |
37 | ||
38 | #include <vxWorks.h> | |
39 | #include <semLib.h> | |
40 | /* typedef void *SEM_ID; */ | |
41 | ||
42 | typedef int __gthread_key_t; | |
43 | typedef char __gthread_once_t; | |
44 | typedef SEM_ID __gthread_mutex_t; | |
45 | ||
46 | #define __GTHREAD_MUTEX_INIT 0 | |
47 | #define __GTHREAD_ONCE_INIT 0 | |
48 | ||
49 | #ifndef REG_SAVED_REG | |
50 | static inline int | |
d1e51320 | 51 | __gthread_once (__gthread_once_t *once, void (*func) (void)) |
7cc34889 MS |
52 | { |
53 | (*func)(); | |
54 | return 0; | |
55 | } | |
56 | ||
57 | extern __gthread_key_t eh_context_key; | |
58 | ||
59 | /* This is not the right way to do it, but the semantic of pthreads | |
60 | don't map well enough onto VxWorks. */ | |
61 | ||
62 | static void | |
0fcff082 | 63 | __ehdtor (void *pTcb) |
7cc34889 | 64 | { |
0fcff082 MS |
65 | int tid = (int) pTcb; |
66 | void *p = (void*)taskVarGet(tid, &eh_context_key); | |
67 | if (p != (void*)-1) | |
68 | { | |
69 | if (p) | |
70 | free (p); | |
71 | taskVarSet(tid, &eh_context_key, 0); | |
72 | } | |
7cc34889 MS |
73 | } |
74 | ||
75 | /* This only works for the code in libgcc2.c. */ | |
76 | ||
77 | static inline int | |
78 | __gthread_key_create (__gthread_key_t *key, void (*dtor) (void *)) | |
79 | { | |
80 | *key = 0; | |
81 | ||
0fcff082 MS |
82 | /* Do this first so that the task variables are visible during the |
83 | running of the delete hook. */ | |
84 | ||
85 | taskVarInit(); | |
86 | ||
7cc34889 MS |
87 | /* We don't have a way to track dtor here, so instead, we |
88 | register a generic routine that can cleanup any task. */ | |
89 | ||
90 | taskDeleteHookAdd (__ehdtor); | |
91 | ||
92 | return 0; | |
93 | } | |
94 | ||
95 | #define __gthread_setspecific(key, ptr) \ | |
96 | (key = (int) ptr, 0) | |
97 | ||
98 | static inline int | |
99 | __gthread_key_dtor (__gthread_key_t key, void *ptr) | |
100 | { | |
101 | /* Just reset the key value to zero. */ | |
102 | if (ptr) | |
103 | return __gthread_setspecific (key, 0); | |
104 | else | |
105 | return 0; | |
106 | } | |
107 | ||
108 | #define __gthread_key_delete(key) \ | |
109 | taskVarDelete (taskIdSelf (), &key) | |
110 | ||
111 | #define __gthread_getspecific(key) \ | |
112 | ((key == 0) \ | |
113 | ? ((taskVarAdd (taskIdSelf (), &key) != OK) \ | |
114 | ? (__terminate (), (void*)0) \ | |
115 | : (void*)0) \ | |
116 | : (void*)key) | |
117 | #endif | |
118 | ||
119 | static inline int | |
120 | __gthread_mutex_lock (__gthread_mutex_t *mutex) | |
121 | { | |
122 | if (*mutex == 0) | |
123 | *mutex = semMCreate (SEM_Q_PRIORITY | SEM_INVERSION_SAFE | SEM_DELETE_SAFE); | |
124 | return semTake (*mutex, WAIT_FOREVER); | |
125 | } | |
126 | ||
127 | static inline int | |
128 | __gthread_mutex_trylock (__gthread_mutex_t *mutex) | |
129 | { | |
130 | if (*mutex == 0) | |
131 | *mutex = semMCreate (SEM_Q_PRIORITY | SEM_INVERSION_SAFE | SEM_DELETE_SAFE); | |
132 | return semTake (*mutex, NO_WAIT); | |
133 | } | |
134 | ||
135 | static inline int | |
136 | __gthread_mutex_unlock (__gthread_mutex_t *mutex) | |
137 | { | |
138 | /* We could return the */ | |
139 | return semGive (*mutex); | |
140 | } | |
141 | ||
142 | #endif /* not __gthr_vxworks_h */ |