1 2/* Compile this one with gcc. */ 3/* Copyright (C) 1997, 1999, 2000, 2001 Free Software Foundation, Inc. 4 5This file is part of GCC. 6 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 --- 60 unchanged lines hidden (view full) --- 69#pragma weak pthread_setspecific 70#pragma weak pthread_create 71#pragma weak pthread_mutex_init 72#pragma weak pthread_mutex_lock 73#pragma weak pthread_mutex_trylock 74#pragma weak pthread_mutex_unlock 75 76#ifdef _LIBOBJC |
77/* Objective-C. */ |
78#pragma weak pthread_cond_broadcast 79#pragma weak pthread_cond_destroy 80#pragma weak pthread_cond_init 81#pragma weak pthread_cond_signal 82#pragma weak pthread_cond_wait 83#pragma weak pthread_exit 84#pragma weak pthread_getunique_np 85#pragma weak pthread_mutex_destroy --- 25 unchanged lines hidden (view full) --- 111 112/* Thread local storage for a single thread */ 113static void *thread_local_storage = NULL; 114 115/* Backend initialization functions */ 116 117/* Initialize the threads subsystem. */ 118static inline int |
119__gthread_objc_init_thread_system (void) |
120{ 121 if (__gthread_active_p ()) 122 /* Initialize the thread storage key */ 123 return pthread_keycreate (&_objc_thread_storage, NULL); 124 else 125 return -1; 126} 127 128/* Close the threads subsystem. */ 129static inline int |
130__gthread_objc_close_thread_system (void) |
131{ 132 if (__gthread_active_p ()) 133 return 0; 134 else 135 return -1; 136} 137 138/* Backend thread functions */ 139 140/* Create a new thread of execution. */ 141static inline objc_thread_t |
142__gthread_objc_thread_detach (void (*func)(void *), void *arg) |
143{ 144 objc_thread_t thread_id; 145 pthread_t new_thread_handle; 146 147 if (!__gthread_active_p ()) 148 return NULL; |
149 150 if (!(pthread_create (&new_thread_handle, pthread_attr_default, 151 (void *) func, arg))) |
152 { 153 /* ??? May not work! (64bit) */ |
154 thread_id = *(objc_thread_t *) &new_thread_handle; 155 pthread_detach (&new_thread_handle); /* Fully detach thread. */ |
156 } 157 else 158 thread_id = NULL; |
159 |
160 return thread_id; 161} 162 163/* Set the current thread's priority. */ 164static inline int |
165__gthread_objc_thread_set_priority (int priority) |
166{ 167 int sys_priority = 0; 168 169 if (!__gthread_active_p ()) 170 return -1; 171 172 switch (priority) 173 { 174 case OBJC_THREAD_INTERACTIVE_PRIORITY: 175 sys_priority = (PRI_FG_MIN_NP + PRI_FG_MAX_NP) / 2; 176 break; 177 default: 178 case OBJC_THREAD_BACKGROUND_PRIORITY: 179 sys_priority = (PRI_BG_MIN_NP + PRI_BG_MAX_NP) / 2; 180 break; 181 case OBJC_THREAD_LOW_PRIORITY: 182 sys_priority = (PRI_BG_MIN_NP + PRI_BG_MAX_NP) / 2; 183 break; 184 } |
185 |
186 /* Change the priority. */ |
187 if (pthread_setprio (pthread_self (), sys_priority) >= 0) |
188 return 0; 189 else 190 /* Failed */ 191 return -1; 192} 193 194/* Return the current thread's priority. */ 195static inline int |
196__gthread_objc_thread_get_priority (void) |
197{ 198 int sys_priority; 199 200 if (__gthread_active_p ()) 201 { |
202 if ((sys_priority = pthread_getprio (pthread_self ())) >= 0) 203 { |
204 if (sys_priority >= PRI_FG_MIN_NP 205 && sys_priority <= PRI_FG_MAX_NP) 206 return OBJC_THREAD_INTERACTIVE_PRIORITY; 207 if (sys_priority >= PRI_BG_MIN_NP 208 && sys_priority <= PRI_BG_MAX_NP) 209 return OBJC_THREAD_BACKGROUND_PRIORITY; 210 return OBJC_THREAD_LOW_PRIORITY; 211 } 212 213 /* Failed */ 214 return -1; 215 } 216 else 217 return OBJC_THREAD_INTERACTIVE_PRIORITY; 218} 219 220/* Yield our process time to another thread. */ 221static inline void |
222__gthread_objc_thread_yield (void) |
223{ 224 if (__gthread_active_p ()) |
225 pthread_yield (); |
226} 227 228/* Terminate the current thread. */ 229static inline int |
230__gthread_objc_thread_exit (void) |
231{ 232 if (__gthread_active_p ()) 233 /* exit the thread */ |
234 pthread_exit (&__objc_thread_exit_status); |
235 236 /* Failed if we reached here */ 237 return -1; 238} 239 240/* Returns an integer value which uniquely describes a thread. */ 241static inline objc_thread_t |
242__gthread_objc_thread_id (void) |
243{ 244 if (__gthread_active_p ()) 245 { |
246 pthread_t self = pthread_self (); |
247 248 return (objc_thread_t) pthread_getunique_np (&self); 249 } 250 else |
251 return (objc_thread_t) 1; |
252} 253 254/* Sets the thread's local storage pointer. */ 255static inline int |
256__gthread_objc_thread_set_data (void *value) |
257{ 258 if (__gthread_active_p ()) |
259 return pthread_setspecific (_objc_thread_storage, value); |
260 else 261 { 262 thread_local_storage = value; 263 return 0; 264 } 265} 266 267/* Returns the thread's local storage pointer. */ 268static inline void * |
269__gthread_objc_thread_get_data (void) |
270{ 271 void *value = NULL; 272 273 if (__gthread_active_p ()) 274 { |
275 if (!(pthread_getspecific (_objc_thread_storage, &value))) |
276 return value; 277 278 return NULL; 279 } 280 else 281 return thread_local_storage; 282} 283 284/* Backend mutex functions */ 285 286/* Allocate a mutex. */ 287static inline int |
288__gthread_objc_mutex_allocate (objc_mutex_t mutex) |
289{ 290 if (__gthread_active_p ()) 291 { |
292 mutex->backend = objc_malloc (sizeof (pthread_mutex_t)); |
293 |
294 if (pthread_mutex_init ((pthread_mutex_t *) mutex->backend, 295 pthread_mutexattr_default)) 296 { 297 objc_free (mutex->backend); 298 mutex->backend = NULL; 299 return -1; 300 } |
301 } 302 303 return 0; 304} 305 306/* Deallocate a mutex. */ 307static inline int |
308__gthread_objc_mutex_deallocate (objc_mutex_t mutex) |
309{ 310 if (__gthread_active_p ()) 311 { |
312 if (pthread_mutex_destroy ((pthread_mutex_t *) mutex->backend)) 313 return -1; |
314 |
315 objc_free (mutex->backend); |
316 mutex->backend = NULL; 317 } 318 319 return 0; 320} 321 322/* Grab a lock on a mutex. */ 323static inline int |
324__gthread_objc_mutex_lock (objc_mutex_t mutex) |
325{ 326 if (__gthread_active_p ()) |
327 return pthread_mutex_lock ((pthread_mutex_t *) mutex->backend); |
328 else 329 return 0; 330} 331 332/* Try to grab a lock on a mutex. */ 333static inline int |
334__gthread_objc_mutex_trylock (objc_mutex_t mutex) |
335{ 336 if (__gthread_active_p () |
337 && pthread_mutex_trylock ((pthread_mutex_t *) mutex->backend) != 1) |
338 return -1; 339 340 return 0; 341} 342 343/* Unlock the mutex */ 344static inline int |
345__gthread_objc_mutex_unlock (objc_mutex_t mutex) |
346{ 347 if (__gthread_active_p ()) |
348 return pthread_mutex_unlock ((pthread_mutex_t *) mutex->backend); |
349 else 350 return 0; 351} 352 353/* Backend condition mutex functions */ 354 355/* Allocate a condition. */ 356static inline int |
357__gthread_objc_condition_allocate (objc_condition_t condition) |
358{ 359 if (__gthread_active_p ()) 360 /* Unimplemented. */ 361 return -1; 362 else 363 return 0; 364} 365 366/* Deallocate a condition. */ 367static inline int |
368__gthread_objc_condition_deallocate (objc_condition_t condition) |
369{ 370 if (__gthread_active_p ()) 371 /* Unimplemented. */ 372 return -1; 373 else 374 return 0; 375} 376 377/* Wait on the condition */ 378static inline int |
379__gthread_objc_condition_wait (objc_condition_t condition, objc_mutex_t mutex) |
380{ 381 if (__gthread_active_p ()) 382 /* Unimplemented. */ 383 return -1; 384 else 385 return 0; 386} 387 388/* Wake up all threads waiting on this condition. */ 389static inline int |
390__gthread_objc_condition_broadcast (objc_condition_t condition) |
391{ 392 if (__gthread_active_p ()) 393 /* Unimplemented. */ 394 return -1; 395 else 396 return 0; 397} 398 399/* Wake up one thread waiting on this condition. */ 400static inline int |
401__gthread_objc_condition_signal (objc_condition_t condition) |
402{ 403 if (__gthread_active_p ()) 404 /* Unimplemented. */ 405 return -1; 406 else 407 return 0; 408} 409 --- 87 unchanged lines hidden --- |