/[pearpc]/src/system/osapi/beos/systhread.cc
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Contents of /src/system/osapi/beos/systhread.cc

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1 - (show annotations)
Wed Sep 5 17:11:21 2007 UTC (16 years, 7 months ago) by dpavlin
File size: 7183 byte(s)
import upstream CVS
1 /*
2 * HT Editor
3 * systhread.cc
4 *
5 * Copyright (C) 2003 Sebastian Biallas (sb@biallas.net)
6 * Copyright (C) 2004 Francois Revol (revol@free.fr)
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */
21
22 #include <cstdlib>
23 #include <OS.h>
24 #include "system/systhread.h"
25 #include <stdio.h>
26 #include "system/types.h"
27 #include "tools/snprintf.h"
28
29 //#define DEBUG_VERBOSE
30 //#define DEBUG_ASSERTS
31
32 #ifdef DEBUG_VERBOSE
33 #define PPC_BTH_TRACE(msg...) ht_printf("[BEOS/THREAD] "msg)
34 #else
35 #define PPC_BTH_TRACE(msg...)
36 #endif
37
38 #ifdef DEBUG_ASSERTS
39 #define ASSERT_SEM(s) assert_sem(s)
40 #define ASSERT_THREAD(t) assert_thread(t)
41 #else
42 #define ASSERT_SEM(s)
43 #define ASSERT_THREAD(t)
44 #endif
45
46 struct sys_beos_mutex {
47 thread_id thread;
48 sem_id sem;
49 };
50
51 struct sys_beos_semaphore {
52 sem_id sem;
53 sem_id mutex;
54 };
55
56 void assert_sem(sem_id s)
57 {
58 int32 cookie = 0;
59 sem_info si;
60 while (get_next_sem_info(0, &cookie, &si) == B_OK) {
61 if (si.sem == s)
62 return; /* it belongs to the team, ok */
63 }
64 debugger("trying to use a sem we don't own!!!");
65 }
66
67 void assert_thread(thread_id t)
68 {
69 int32 cookie = 0;
70 thread_info ti;
71 while (get_next_thread_info(0, &cookie, &ti) == B_OK) {
72 if (ti.thread == t)
73 return; /* it belongs to the team, ok */
74 }
75 debugger("trying to use a thread we don't own!!!");
76 }
77
78 int sys_create_mutex(sys_mutex *m)
79 {
80 sys_beos_mutex *bm;
81 PPC_BTH_TRACE("%s(%p)\n", __FUNCTION__, m);
82 bm = (sys_beos_mutex *)malloc(sizeof (sys_beos_mutex));
83 bm->thread = 0;
84 bm->sem = create_sem(1, "a PearPC mutex");
85 PPC_BTH_TRACE("%s: {T:%d, S:%d})\n", __FUNCTION__, bm->thread, bm->sem);
86 if (bm->sem < B_OK) {
87 free(bm);
88 return bm->sem;
89 }
90 *m = bm;
91 return B_OK;
92 }
93
94 int sys_create_semaphore(sys_semaphore *s)
95 {
96 sys_beos_semaphore *bs;
97 status_t err;
98 PPC_BTH_TRACE("%s(%p)\n", __FUNCTION__, s);
99 bs = (sys_beos_semaphore *)malloc(sizeof (sys_beos_semaphore));
100 if (!bs)
101 return B_NO_MEMORY;
102 err = bs->sem = create_sem(0, "a PearPC sem.sem");
103 if (err < B_OK) {
104 free(bs);
105 return err;
106 }
107 err = bs->mutex = create_sem(1, "a PearPC sem.mutex");
108 if (err < B_OK) {
109 delete_sem(bs->sem);
110 free(bs);
111 return err;
112 }
113 PPC_BTH_TRACE("%s: {S:%d, M:%d})\n", __FUNCTION__, bs->sem, bs->mutex);
114 *s = bs;
115 return B_OK;
116 }
117
118 int sys_create_thread(sys_thread *t, int flags, sys_thread_function start_routine, void *arg)
119 {
120 thread_id th;
121 status_t err;
122 PPC_BTH_TRACE("%s(%p, 0x%08x, %p, %p)\n", __FUNCTION__, t, flags, start_routine, arg);
123 th = spawn_thread((thread_func)start_routine, "a PearPC thread", B_NORMAL_PRIORITY, arg);
124 if (th < B_OK)
125 return th;
126 err = resume_thread(th);
127 if (!err)
128 *(thread_id *)t = th;
129 PPC_BTH_TRACE("%s: T:%d\n", __FUNCTION__, th);
130 return err;
131 }
132
133 void sys_destroy_mutex(sys_mutex m)
134 {
135 sys_beos_mutex *bm = (sys_beos_mutex *)m;
136 PPC_BTH_TRACE("%s(%p {T:%d, S:%d})\n", __FUNCTION__, m, bm->thread, bm->sem);
137 ASSERT_SEM(bm->sem);
138 delete_sem(bm->sem);
139 free(m);
140 }
141
142 void sys_destroy_semaphore(sys_semaphore s)
143 {
144 sys_beos_semaphore *bs = (sys_beos_semaphore *)s;
145 PPC_BTH_TRACE("%s(%p {S:%d, M:%d})\n", __FUNCTION__, s, bs->sem, bs->mutex);
146 ASSERT_SEM(bs->sem);
147 delete_sem(bs->sem);
148 ASSERT_SEM(bs->mutex);
149 delete_sem(bs->mutex);
150 free(s);
151 }
152
153 void sys_destroy_thread(sys_thread t)
154 {
155 status_t err;
156 thread_id th = (thread_id)t;
157 PPC_BTH_TRACE("%s(T:%d)\n", __FUNCTION__, th);
158 ASSERT_THREAD(th);
159 //kill_thread(th); // just to make sure
160 //wait_for_thread(th, &err);
161 }
162
163 int sys_lock_mutex(sys_mutex m)
164 {
165 status_t err;
166 sys_beos_mutex *bm = (sys_beos_mutex *)m;
167 PPC_BTH_TRACE("%s(%p {T:%d, S:%d})\n", __FUNCTION__, m, bm->thread, bm->sem);
168 if (bm->thread == find_thread(NULL))
169 return B_OK;
170 ASSERT_SEM(bm->sem);
171 err = acquire_sem(bm->sem);
172 if (err)
173 return err;
174 bm->thread = find_thread(NULL);
175 return B_OK;
176 }
177
178 int sys_trylock_mutex(sys_mutex m)
179 {
180 status_t err;
181 sys_beos_mutex *bm = (sys_beos_mutex *)m;
182 PPC_BTH_TRACE("%s(%p {T:%d, S:%d})\n", __FUNCTION__, m, bm->thread, bm->sem);
183 if (bm->thread == find_thread(NULL))
184 return B_OK;
185 ASSERT_SEM(bm->sem);
186 err = acquire_sem_etc(bm->sem, 1, B_RELATIVE_TIMEOUT, 0LL);
187 if (err)
188 return err;
189 bm->thread = find_thread(NULL);
190 return B_OK;
191 }
192
193 void sys_unlock_mutex(sys_mutex m)
194 {
195 sys_beos_mutex *bm = (sys_beos_mutex *)m;
196 PPC_BTH_TRACE("%s(%p {T:%d, S:%d})\n", __FUNCTION__, m, bm->thread, bm->sem);
197 bm->thread = 0;
198 ASSERT_SEM(bm->sem);
199 release_sem(bm->sem);
200 }
201
202 void sys_signal_semaphore(sys_semaphore s)
203 {
204 sys_beos_semaphore *bs = (sys_beos_semaphore *)s;
205 PPC_BTH_TRACE("%s(%p {S:%d, M:%d})\n", __FUNCTION__, s, bs->sem, bs->mutex);
206 ASSERT_SEM(bs->sem);
207 release_sem(bs->sem);
208 }
209
210 void sys_signal_all_semaphore(sys_semaphore s)
211 {
212 int32 count;
213 sys_beos_semaphore *bs = (sys_beos_semaphore *)s;
214 PPC_BTH_TRACE("%s(%p {S:%d, M:%d})\n", __FUNCTION__, s, bs->sem, bs->mutex);
215 ASSERT_SEM(bs->sem);
216 // XXX that's not safe! that should be a kernel atomic op!
217 if (get_sem_count(bs->sem, &count) < B_OK)
218 return;
219 release_sem_etc(bs->sem, count, 0L);
220 }
221
222 void sys_wait_semaphore(sys_semaphore s)
223 {
224 sys_beos_semaphore *bs = (sys_beos_semaphore *)s;
225 PPC_BTH_TRACE("%s(%p {S:%d, M:%d})\n", __FUNCTION__, s, bs->sem, bs->mutex);
226 ASSERT_SEM(bs->mutex);
227 ASSERT_SEM(bs->sem);
228 release_sem(bs->mutex);
229 acquire_sem(bs->sem);
230 acquire_sem(bs->mutex);
231 }
232
233 void sys_wait_semaphore_bounded(sys_semaphore s, int ms)
234 {
235 sys_beos_semaphore *bs = (sys_beos_semaphore *)s;
236 PPC_BTH_TRACE("%s(%p {S:%d, M:%d}, %dms)\n", __FUNCTION__, s, bs->sem, bs->mutex, ms);
237 ASSERT_SEM(bs->mutex);
238 ASSERT_SEM(bs->sem);
239 release_sem(bs->mutex);
240 acquire_sem_etc(bs->sem, 1, B_RELATIVE_TIMEOUT, (bigtime_t)ms*1000);
241 acquire_sem(bs->mutex);
242 }
243
244 void sys_lock_semaphore(sys_semaphore s)
245 {
246 sys_beos_semaphore *bs = (sys_beos_semaphore *)s;
247 PPC_BTH_TRACE("%s(%p {S:%d, M:%d})\n", __FUNCTION__, s, bs->sem, bs->mutex);
248 ASSERT_SEM(bs->mutex);
249 acquire_sem(bs->mutex);
250 }
251
252 void sys_unlock_semaphore(sys_semaphore s)
253 {
254 sys_beos_semaphore *bs = (sys_beos_semaphore *)s;
255 PPC_BTH_TRACE("%s(%p {S:%d, M:%d})\n", __FUNCTION__, s, bs->sem, bs->mutex);
256 ASSERT_SEM(bs->mutex);
257 release_sem(bs->mutex);
258 }
259
260 void sys_exit_thread(void *ret)
261 {
262 PPC_BTH_TRACE("%s(%p)\n", __FUNCTION__, ret);
263 // in BeOS the exit code is supposed to be a success/errno
264 // code, but that shouldn't matter, it's just an int32.
265 // (as long as it can be casted to a void* (beware 64 bits...))
266 exit_thread((status_t)ret);
267 }
268
269 void *sys_join_thread(sys_thread t)
270 {
271 void *ret = NULL;
272 thread_id th = (thread_id)t;
273 PPC_BTH_TRACE("%s(%d)\n", __FUNCTION__, th);
274 ASSERT_THREAD(th);
275 //kill_thread(th); // just to make sure
276 wait_for_thread(th, (status_t *)&ret);
277 return ret;
278 }

  ViewVC Help
Powered by ViewVC 1.1.26