diff options
-rw-r--r-- | gcc/ChangeLog | 9 | ||||
-rw-r--r-- | gcc/gthr-dce.h | 313 | ||||
-rw-r--r-- | gcc/gthr-posix.h | 315 | ||||
-rw-r--r-- | gcc/gthr-single.h | 172 | ||||
-rw-r--r-- | gcc/gthr-solaris.h | 307 | ||||
-rw-r--r-- | gcc/gthr-vxworks.h | 172 | ||||
-rw-r--r-- | gcc/gthr-win32.h | 247 | ||||
-rw-r--r-- | libobjc/ChangeLog | 12 | ||||
-rw-r--r-- | libobjc/Makefile.in | 5 | ||||
-rwxr-xr-x | libobjc/configure | 16 | ||||
-rw-r--r-- | libobjc/configure.in | 10 | ||||
-rw-r--r-- | libobjc/thr-objc.c | 181 |
12 files changed, 1723 insertions, 36 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 840153d7d74..bcd6f9bea5e 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -5122,6 +5122,15 @@ Sat May 13 11:05:47 2000 Philippe De Muyter <phdm@macqel.be> * ifcvt.c (if_convert): Do not free NULL. +2000-05-12 H.J. Lu (hjl@gnu.org) + + * gthr-dce.h: Add support for libobjc. + * gthr-posix.h: Likewise. + * gthr-solaris.h: Likewise. + * gthr-vxworks.h: Likewise. + * gthr-single.h: Likewise. + * gthr-win32.h: Likewise. + 2000-05-12 Nick Clifton <nickc@cygnus.com> * config/fr30/fr30.c (fr30_move_double): New function: Emit code diff --git a/gcc/gthr-dce.h b/gcc/gthr-dce.h index 7c12b00b8b5..e41987b454a 100644 --- a/gcc/gthr-dce.h +++ b/gcc/gthr-dce.h @@ -1,6 +1,6 @@ /* Compile this one with gcc. */ -/* Copyright (C) 1997 Free Software Foundation, Inc. +/* Copyright (C) 1997, 1999, 2000 Free Software Foundation, Inc. This file is part of GNU CC. @@ -48,7 +48,7 @@ typedef pthread_mutex_t __gthread_mutex_t; #pragma weak pthread_once #pragma weak pthread_once_init -#pragma weak pthread_key_create +#pragma weak pthread_keycreate #pragma weak pthread_key_delete #pragma weak pthread_getspecific #pragma weak pthread_setspecific @@ -58,6 +58,21 @@ typedef pthread_mutex_t __gthread_mutex_t; #pragma weak pthread_mutex_trylock #pragma weak pthread_mutex_unlock +#ifdef _LIBOBJC +/* Objective C. */ +#pragma weak pthread_cond_broadcast +#pragma weak pthread_cond_destroy +#pragma weak pthread_cond_init +#pragma weak pthread_cond_signal +#pragma weak pthread_cond_wait +#pragma weak pthread_exit +#pragma weak pthread_getunique_np +#pragma weak pthread_mutex_init +#pragma weak pthread_mutex_destroy +#pragma weak pthread_self +#pragma weak pthread_yield +#endif + static void *__gthread_active_ptr = &pthread_create; static inline int @@ -76,6 +91,298 @@ __gthread_active_p (void) #endif /* SUPPORTS_WEAK */ +#ifdef _LIBOBJC + +/* Key structure for maintaining thread specific storage */ +static pthread_key_t _objc_thread_storage; + +/* Thread local storage for a single thread */ +static void *thread_local_storage = NULL; + +/* Backend initialization functions */ + +/* Initialize the threads subsystem. */ +static inline int +__gthread_objc_init_thread_system(void) +{ + if (__gthread_active_p ()) + /* Initialize the thread storage key */ + return pthread_keycreate (&_objc_thread_storage, NULL); + else + return -1; +} + +/* Close the threads subsystem. */ +static inline int +__gthread_objc_close_thread_system(void) +{ + if (__gthread_active_p ()) + return 0; + else + return -1; +} + +/* Backend thread functions */ + +/* Create a new thread of execution. */ +static inline objc_thread_t +__gthread_objc_thread_detach(void (*func)(void *), void *arg) +{ + objc_thread_t thread_id; + pthread_t new_thread_handle; + + if (!__gthread_active_p ()) + return NULL; + + if ( !(pthread_create(&new_thread_handle, pthread_attr_default, + (void *)func, arg)) ) + { + /* ??? May not work! (64bit) */ + thread_id = *(objc_thread_t *)&new_thread_handle; + pthread_detach(&new_thread_handle); /* Fully detach thread. */ + } + else + thread_id = NULL; + + return thread_id; +} + +/* Set the current thread's priority. */ +static inline int +__gthread_objc_thread_set_priority(int priority) +{ + int sys_priority = 0; + + if (!__gthread_active_p ()) + return -1; + + switch (priority) + { + case OBJC_THREAD_INTERACTIVE_PRIORITY: + sys_priority = (PRI_FG_MIN_NP + PRI_FG_MAX_NP) / 2; + break; + default: + case OBJC_THREAD_BACKGROUND_PRIORITY: + sys_priority = (PRI_BG_MIN_NP + PRI_BG_MAX_NP) / 2; + break; + case OBJC_THREAD_LOW_PRIORITY: + sys_priority = (PRI_BG_MIN_NP + PRI_BG_MAX_NP) / 2; + break; + } + + /* Change the priority. */ + if (pthread_setprio(pthread_self(), sys_priority) >= 0) + return 0; + else + /* Failed */ + return -1; +} + +/* Return the current thread's priority. */ +static inline int +__gthread_objc_thread_get_priority(void) +{ + int sys_priority; + + if (__gthread_active_p ()) + { + if ((sys_priority = pthread_getprio(pthread_self())) >= 0) + { + if (sys_priority >= PRI_FG_MIN_NP + && sys_priority <= PRI_FG_MAX_NP) + return OBJC_THREAD_INTERACTIVE_PRIORITY; + if (sys_priority >= PRI_BG_MIN_NP + && sys_priority <= PRI_BG_MAX_NP) + return OBJC_THREAD_BACKGROUND_PRIORITY; + return OBJC_THREAD_LOW_PRIORITY; + } + + /* Failed */ + return -1; + } + else + return OBJC_THREAD_INTERACTIVE_PRIORITY; +} + +/* Yield our process time to another thread. */ +static inline void +__gthread_objc_thread_yield(void) +{ + if (__gthread_active_p ()) + pthread_yield(); +} + +/* Terminate the current thread. */ +static inline int +__gthread_objc_thread_exit(void) +{ + if (__gthread_active_p ()) + /* exit the thread */ + pthread_exit(&__objc_thread_exit_status); + + /* Failed if we reached here */ + return -1; +} + +/* Returns an integer value which uniquely describes a thread. */ +static inline objc_thread_t +__gthread_objc_thread_id(void) +{ + if (__gthread_active_p ()) + { + pthread_t self = pthread_self(); + + return (objc_thread_t) pthread_getunique_np (&self); + } + else + return (objc_thread_t)1; +} + +/* Sets the thread's local storage pointer. */ +static inline int +__gthread_objc_thread_set_data(void *value) +{ + if (__gthread_active_p ()) + return pthread_setspecific(_objc_thread_storage, value); + else + { + thread_local_storage = value; + return 0; + } +} + +/* Returns the thread's local storage pointer. */ +static inline void * +__gthread_objc_thread_get_data(void) +{ + void *value = NULL; + + if (__gthread_active_p ()) + { + if ( !(pthread_getspecific(_objc_thread_storage, &value)) ) + return value; + + return NULL; + } + else + return thread_local_storage; +} + +/* Backend mutex functions */ + +/* Allocate a mutex. */ +static inline int +__gthread_objc_mutex_allocate(objc_mutex_t mutex) +{ + if (__gthread_active_p () + && pthread_mutex_init((pthread_mutex_t *)mutex->backend, + pthread_mutexattr_default)) + return -1; + + return 0; +} + +/* Deallocate a mutex. */ +static inline int +__gthread_objc_mutex_deallocate(objc_mutex_t mutex) +{ + if (__gthread_active_p () + && pthread_mutex_destroy((pthread_mutex_t *)mutex->backend)) + return -1; + + return 0; +} + +/* Grab a lock on a mutex. */ +static inline int +__gthread_objc_mutex_lock(objc_mutex_t mutex) +{ + if (__gthread_active_p ()) + return pthread_mutex_lock((pthread_mutex_t *)mutex->backend); + else + return 0; +} + +/* Try to grab a lock on a mutex. */ +static inline int +__gthread_objc_mutex_trylock(objc_mutex_t mutex) +{ + if (__gthread_active_p () + && pthread_mutex_trylock((pthread_mutex_t *)mutex->backend) != 1) + return -1; + + return 0; +} + +/* Unlock the mutex */ +static inline int +__gthread_objc_mutex_unlock(objc_mutex_t mutex) +{ + if (__gthread_active_p ()) + return pthread_mutex_unlock((pthread_mutex_t *)mutex->backend); + else + return 0; +} + +/* Backend condition mutex functions */ + +/* Allocate a condition. */ +static inline int +__gthread_objc_condition_allocate(objc_condition_t condition) +{ + if (__gthread_active_p () + /* Unimplemented. */ + return -1; + else + return 0; +} + +/* Deallocate a condition. */ +static inline int +__gthread_objc_condition_deallocate(objc_condition_t condition) +{ + if (__gthread_active_p ()) + /* Unimplemented. */ + return -1; + else + return 0; +} + +/* Wait on the condition */ +static inline int +__gthread_objc_condition_wait(objc_condition_t condition, objc_mutex_t mutex) +{ + if (__gthread_active_p ()) + /* Unimplemented. */ + return -1; + else + return 0; +} + +/* Wake up all threads waiting on this condition. */ +static inline int +__gthread_objc_condition_broadcast(objc_condition_t condition) +{ + if (__gthread_active_p ()) + /* Unimplemented. */ + return -1; + else + return 0; +} + +/* Wake up one thread waiting on this condition. */ +static inline int +__gthread_objc_condition_signal(objc_condition_t condition) +{ + if (__gthread_active_p ()) + /* Unimplemented. */ + return -1; + else + return 0; +} + +#else /* _LIBOBJC */ + static inline int __gthread_once (__gthread_once_t *once, void (*func) (void)) { @@ -147,4 +454,6 @@ __gthread_mutex_unlock (__gthread_mutex_t *mutex) return 0; } +#endif /* _LIBOBJC */ + #endif /* not __gthr_dce_h */ diff --git a/gcc/gthr-posix.h b/gcc/gthr-posix.h index 1b765d2359a..91de78ae4b8 100644 --- a/gcc/gthr-posix.h +++ b/gcc/gthr-posix.h @@ -1,6 +1,6 @@ -/* Threads compatibility routines for libgcc2. */ +/* Threads compatibility routines for libgcc2 and libobjc. */ /* Compile this one with gcc. */ -/* Copyright (C) 1997 Free Software Foundation, Inc. +/* Copyright (C) 1997, 1999, 2000 Free Software Foundation, Inc. This file is part of GNU CC. @@ -45,16 +45,30 @@ typedef pthread_mutex_t __gthread_mutex_t; #if SUPPORTS_WEAK && GTHREAD_USE_WEAK - #pragma weak pthread_once - #pragma weak pthread_key_create - #pragma weak pthread_key_delete - #pragma weak pthread_getspecific - #pragma weak pthread_setspecific - #pragma weak pthread_create +#pragma weak pthread_once +#pragma weak pthread_key_create +#pragma weak pthread_key_delete +#pragma weak pthread_getspecific +#pragma weak pthread_setspecific +#pragma weak pthread_create - #pragma weak pthread_mutex_lock - #pragma weak pthread_mutex_trylock - #pragma weak pthread_mutex_unlock +#pragma weak pthread_mutex_lock +#pragma weak pthread_mutex_trylock +#pragma weak pthread_mutex_unlock + +#ifdef _LIBOBJC +/* Objective C. */ +#pragma weak pthread_cond_broadcast +#pragma weak pthread_cond_destroy +#pragma weak pthread_cond_init +#pragma weak pthread_cond_signal +#pragma weak pthread_cond_wait +#pragma weak pthread_exit +#pragma weak pthread_mutex_init +#pragma weak pthread_mutex_destroy +#pragma weak pthread_self +#pragma weak sched_yield +#endif static void *__gthread_active_ptr = &pthread_create; @@ -74,6 +88,283 @@ __gthread_active_p (void) #endif /* SUPPORTS_WEAK */ +#ifdef _LIBOBJC + +/* Key structure for maintaining thread specific storage */ +static pthread_key_t _objc_thread_storage; + +/* Thread local storage for a single thread */ +static void *thread_local_storage = NULL; + +/* Backend initialization functions */ + +/* Initialize the threads subsystem. */ +static inline int +__gthread_objc_init_thread_system(void) +{ + if (__gthread_active_p ()) + /* Initialize the thread storage key */ + return pthread_key_create(&_objc_thread_storage, NULL); + else + return -1; +} + +/* Close the threads subsystem. */ +static inline int +__gthread_objc_close_thread_system(void) +{ + if (__gthread_active_p ()) + return 0; + else + return -1; +} + +/* Backend thread functions */ + +/* Create a new thread of execution. */ +static inline objc_thread_t +__gthread_objc_thread_detach(void (*func)(void *), void *arg) +{ + objc_thread_t thread_id; + pthread_t new_thread_handle; + + if (!__gthread_active_p ()) + return NULL; + + if ( !(pthread_create(&new_thread_handle, NULL, (void *)func, arg)) ) + thread_id = *(objc_thread_t *)&new_thread_handle; + else + thread_id = NULL; + + return thread_id; +} + +/* Set the current thread's priority. */ +static inline int +__gthread_objc_thread_set_priority(int priority) +{ + /* Not implemented yet */ + return -1; +} + +/* Return the current thread's priority. */ +static inline int +__gthread_objc_thread_get_priority(void) +{ + if (__gthread_active_p ()) + /* Not implemented yet */ + return -1; + else + return OBJC_THREAD_INTERACTIVE_PRIORITY; +} + +/* Yield our process time to another thread. */ +static inline void +__gthread_objc_thread_yield(void) +{ + if (__gthread_active_p ()) + sched_yield(); +} + +/* Terminate the current thread. */ +static inline int +__gthread_objc_thread_exit(void) +{ + if (__gthread_active_p ()) + /* exit the thread */ + pthread_exit(&__objc_thread_exit_status); + + /* Failed if we reached here */ + return -1; +} + +/* Returns an integer value which uniquely describes a thread. */ +static inline objc_thread_t +__gthread_objc_thread_id(void) +{ + if (__gthread_active_p ()) + { + pthread_t self = pthread_self(); + + return *(objc_thread_t *)&self; + } + else + return (objc_thread_t)1; +} + +/* Sets the thread's local storage pointer. */ +static inline int +__gthread_objc_thread_set_data(void *value) +{ + if (__gthread_active_p ()) + return pthread_setspecific(_objc_thread_storage, value); + else + { + thread_local_storage = value; + return 0; + } +} + +/* Returns the thread's local storage pointer. */ +static inline void * +__gthread_objc_thread_get_data(void) +{ + if (__gthread_active_p ()) + return pthread_getspecific(_objc_thread_storage); + else + return thread_local_storage; +} + +/* Backend mutex functions */ + +/* Allocate a mutex. */ +static inline int +__gthread_objc_mutex_allocate(objc_mutex_t mutex) +{ + if (__gthread_active_p ()) + { + mutex->backend = objc_malloc(sizeof(pthread_mutex_t)); + + if (pthread_mutex_init((pthread_mutex_t *)mutex->backend, NULL)) + { + objc_free(mutex->backend); + mutex->backend = NULL; + return -1; + } + } + + return 0; +} + +/* Deallocate a mutex. */ +static inline int +__gthread_objc_mutex_deallocate(objc_mutex_t mutex) +{ + if (__gthread_active_p ()) + { + int count; + + /* + * Posix Threads specifically require that the thread be unlocked + * for pthread_mutex_destroy to work. + */ + + do + { + count = pthread_mutex_unlock((pthread_mutex_t *)mutex->backend); + if (count < 0) + return -1; + } + while (count); + + if (pthread_mutex_destroy((pthread_mutex_t *)mutex->backend)) + return -1; + + objc_free(mutex->backend); + mutex->backend = NULL; + } + return 0; +} + +/* Grab a lock on a mutex. */ +static inline int +__gthread_objc_mutex_lock(objc_mutex_t mutex) +{ + if (__gthread_active_p ()) + return pthread_mutex_lock((pthread_mutex_t *)mutex->backend); + else + return 0; +} + +/* Try to grab a lock on a mutex. */ +static inline int +__gthread_objc_mutex_trylock(objc_mutex_t mutex) +{ + if (__gthread_active_p ()) + return pthread_mutex_trylock((pthread_mutex_t *)mutex->backend); + else + return 0; +} + +/* Unlock the mutex */ +static inline int +__gthread_objc_mutex_unlock(objc_mutex_t mutex) +{ + if (__gthread_active_p ()) + return pthread_mutex_unlock((pthread_mutex_t *)mutex->backend); + else + return 0; +} + +/* Backend condition mutex functions */ + +/* Allocate a condition. */ +static inline int +__gthread_objc_condition_allocate(objc_condition_t condition) +{ + if (__gthread_active_p ()) + { + condition->backend = objc_malloc(sizeof(pthread_cond_t)); + + if (pthread_cond_init((pthread_cond_t *)condition->backend, NULL)) + { + objc_free(condition->backend); + condition->backend = NULL; + return -1; + } + } + + return 0; +} + +/* Deallocate a condition. */ +static inline int +__gthread_objc_condition_deallocate(objc_condition_t condition) +{ + if (__gthread_active_p ()) + { + if (pthread_cond_destroy((pthread_cond_t *)condition->backend)) + return -1; + + objc_free(condition->backend); + condition->backend = NULL; + } + return 0; +} + +/* Wait on the condition */ +static inline int +__gthread_objc_condition_wait(objc_condition_t condition, objc_mutex_t mutex) +{ + if (__gthread_active_p ()) + return pthread_cond_wait((pthread_cond_t *)condition->backend, + (pthread_mutex_t *)mutex->backend); + else + return 0; +} + +/* Wake up all threads waiting on this condition. */ +static inline int +__gthread_objc_condition_broadcast(objc_condition_t condition) +{ + if (__gthread_active_p ()) + return pthread_cond_broadcast((pthread_cond_t *)condition->backend); + else + return 0; +} + +/* Wake up one thread waiting on this condition. */ +static inline int +__gthread_objc_condition_signal(objc_condition_t condition) +{ + if (__gthread_active_p ()) + return pthread_cond_signal((pthread_cond_t *)condition->backend); + else + return 0; +} + +#else /* _LIBOBJC */ + static inline int __gthread_once (__gthread_once_t *once, void (*func) (void)) { @@ -144,4 +435,6 @@ __gthread_mutex_unlock (__gthread_mutex_t *mutex) return 0; } +#endif /* _LIBOBJC */ + #endif /* not __gthr_posix_h */ diff --git a/gcc/gthr-single.h b/gcc/gthr-single.h index 8fb674667b1..4bfea5e3087 100644 --- a/gcc/gthr-single.h +++ b/gcc/gthr-single.h @@ -1,6 +1,6 @@ -/* Threads compatibility routines for libgcc2. */ +/* Threads compatibility routines for libgcc2 and libobjc. */ /* Compile this one with gcc. */ -/* Copyright (C) 1997 Free Software Foundation, Inc. +/* Copyright (C) 1997, 1999, 2000 Free Software Foundation, Inc. This file is part of GNU CC. @@ -35,6 +35,172 @@ typedef int __gthread_mutex_t; #define __GTHREAD_MUTEX_INIT 0 +#ifdef _LIBOBJC + +/* Thread local storage for a single thread */ +static void *thread_local_storage = NULL; + +/* Backend initialization functions */ + +/* Initialize the threads subsystem. */ +static inline int +__gthread_objc_init_thread_system(void) +{ + /* No thread support available */ + return -1; +} + +/* Close the threads subsystem. */ +static inline int +__gthread_objc_close_thread_system(void) +{ + /* No thread support available */ + return -1; +} + +/* Backend thread functions */ + +/* Create a new thread of execution. */ +static inline objc_thread_t +__gthread_objc_thread_detach(void (*func)(void *arg), void *arg) +{ + /* No thread support available */ + return NULL; +} + +/* Set the current thread's priority. */ +static inline int +__gthread_objc_thread_set_priority(int priority) +{ + /* No thread support available */ + return -1; +} + +/* Return the current thread's priority. */ +static inline int +__gthread_objc_thread_get_priority(void) +{ + return OBJC_THREAD_INTERACTIVE_PRIORITY; +} + +/* Yield our process time to another thread. */ +static inline void +__gthread_objc_thread_yield(void) +{ + return; +} + +/* Terminate the current thread. */ +static inline int +__gthread_objc_thread_exit(void) +{ + /* No thread support available */ + /* Should we really exit the program */ + /* exit(&__objc_thread_exit_status); */ + return -1; +} + +/* Returns an integer value which uniquely describes a thread. */ +static inline objc_thread_t +__gthread_objc_thread_id(void) +{ + /* No thread support, use 1. */ + return (objc_thread_t)1; +} + +/* Sets the thread's local storage pointer. */ +static inline int +__gthread_objc_thread_set_data(void *value) +{ + thread_local_storage = value; + return 0; +} + +/* Returns the thread's local storage pointer. */ +static inline void * +__gthread_objc_thread_get_data(void) +{ + return thread_local_storage; +} + +/* Backend mutex functions */ + +/* Allocate a mutex. */ +static inline int +__gthread_objc_mutex_allocate(objc_mutex_t mutex) +{ + return 0; +} + +/* Deallocate a mutex. */ +static inline int +__gthread_objc_mutex_deallocate(objc_mutex_t mutex) +{ + return 0; +} + +/* Grab a lock on a mutex. */ +static inline int +__gthread_objc_mutex_lock(objc_mutex_t mutex) +{ + /* There can only be one thread, so we always get the lock */ + return 0; +} + +/* Try to grab a lock on a mutex. */ +static inline int +__gthread_objc_mutex_trylock(objc_mutex_t mutex) +{ + /* There can only be one thread, so we always get the lock */ + return 0; +} + +/* Unlock the mutex */ +static inline int +__gthread_objc_mutex_unlock(objc_mutex_t mutex) +{ + return 0; +} + +/* Backend condition mutex functions */ + +/* Allocate a condition. */ +static inline int +__gthread_objc_condition_allocate(objc_condition_t condition) +{ + return 0; +} + +/* Deallocate a condition. */ +static inline int +__gthread_objc_condition_deallocate(objc_condition_t condition) +{ + return 0; +} + +/* Wait on the condition */ +static inline int +__gthread_objc_condition_wait(objc_condition_t condition, objc_mutex_t mutex) +{ + return 0; +} + +/* Wake up all threads waiting on this condition. */ +static inline int +__gthread_objc_condition_broadcast(objc_condition_t condition) +{ + return 0; +} + +/* Wake up one thread waiting on this condition. */ +static inline int +__gthread_objc_condition_signal(objc_condition_t condition) +{ + return 0; +} + +#else /* _LIBOBJC */ + static inline int __gthread_active_p (void) { @@ -59,4 +225,6 @@ __gthread_mutex_unlock (__gthread_mutex_t *mutex __attribute__ ((__unused__))) return 0; } +#endif /* _LIBOBJC */ + #endif /* not __gthr_single_h */ diff --git a/gcc/gthr-solaris.h b/gcc/gthr-solaris.h index 0c240608135..fca3084f9a7 100644 --- a/gcc/gthr-solaris.h +++ b/gcc/gthr-solaris.h @@ -1,6 +1,6 @@ -/* Threads compatibility routines for libgcc2. */ +/* Threads compatibility routines for libgcc2 and libobjc. */ /* Compile this one with gcc. */ -/* Copyright (C) 1997 Free Software Foundation, Inc. +/* Copyright (C) 1997, 1999, 2000 Free Software Foundation, Inc. This file is part of GNU CC. @@ -60,6 +60,24 @@ typedef mutex_t __gthread_mutex_t; #pragma weak mutex_trylock #pragma weak mutex_unlock +#ifdef _LIBOBJC +#pragma weak thr_exit +#pragma weak thr_keycreate +#pragma weak thr_getprio +#pragma weak thr_self +#pragma weak thr_setprio +#pragma weak thr_yield + +#pragma weak cond_init +#pragma weak cond_destroy +#pragma weak cond_wait +#pragma weak cond_broadcast +#pragma weak cond_signal + +#pragma weak mutex_init +#pragma weak mutex_destroy +#endif + /* This will not actually work in Solaris 2.5, since libc contains dummy symbols of all thr_* routines. */ @@ -81,6 +99,289 @@ __gthread_active_p (void) #endif /* SUPPORTS_WEAK */ +#ifdef _LIBOBJC + +/* Key structure for maintaining thread specific storage */ +static thread_key_t _objc_thread_storage; + +/* Thread local storage for a single thread */ +static void *thread_local_storage = NULL; + +/* Backend initialization functions */ + +/* Initialize the threads subsystem. */ +static inline int +__gthread_objc_init_thread_system(void) +{ + /* Initialize the thread storage key */ + if (__gthread_active_p () + && thr_keycreate(&_objc_thread_storage, NULL) == 0) + return 0; + + return -1; +} + +/* Close the threads subsystem. */ +static inline int +__gthread_objc_close_thread_system(void) +{ + if (__gthread_active_p ()) + return 0; + else + return -1; +} + +/* Backend thread functions */ + +/* Create a new thread of execution. */ +static inline objc_thread_t +__gthread_objc_thread_detach(void (*func)(void *), void *arg) +{ + objc_thread_t thread_id; + thread_t new_thread_id = 0; + + if (!__gthread_active_p ()) + return NULL; + + if (thr_create(NULL, 0, (void *)func, arg, + THR_DETACHED | THR_NEW_LWP, + &new_thread_id) == 0) + thread_id = *(objc_thread_t *)&new_thread_id; + else + thread_id = NULL; + + return thread_id; +} + +/* Set the current thread's priority. */ +static inline int +__gthread_objc_thread_set_priority(int priority) +{ + int sys_priority = 0; + + if (!__gthread_active_p ()) + return -1; + + switch (priority) + { + case OBJC_THREAD_INTERACTIVE_PRIORITY: + sys_priority = 300; + break; + default: + case OBJC_THREAD_BACKGROUND_PRIORITY: + sys_priority = 200; + break; + case OBJC_THREAD_LOW_PRIORITY: + sys_priority = 1000; + break; + } + + /* Change priority */ + if (thr_setprio(thr_self(), sys_priority) == 0) + return 0; + else + return -1; +} + +/* Return the current thread's priority. */ +static inline int +__gthread_objc_thread_get_priority(void) +{ + int sys_priority; + + if (!__gthread_active_p ()) + return OBJC_THREAD_INTERACTIVE_PRIORITY; + + if (thr_getprio(thr_self(), &sys_priority) == 0) + { + if (sys_priority >= 250) + return OBJC_THREAD_INTERACTIVE_PRIORITY; + else if (sys_priority >= 150) + return OBJC_THREAD_BACKGROUND_PRIORITY; + return OBJC_THREAD_LOW_PRIORITY; + } + + /* Couldn't get priority. */ + return -1; +} + +/* Yield our process time to another thread. */ +static inline void +__gthread_objc_thread_yield(void) +{ + if (__gthread_active_p ()) + thr_yield(); +} + +/* Terminate the current thread. */ +static inline int +__gthread_objc_thread_exit(void) +{ + if (__gthread_active_p ()) + /* exit the thread */ + thr_exit(&__objc_thread_exit_status); + + /* Failed if we reached here */ + return -1; +} + +/* Returns an integer value which uniquely describes a thread. */ +static inline objc_thread_t +__gthread_objc_thread_id(void) +{ + if (__gthread_active_p ()) + return (objc_thread_t)thr_self(); + else + return (objc_thread_t)1; +} + +/* Sets the thread's local storage pointer. */ +static inline int +__gthread_objc_thread_set_data(void *value) +{ + if (__gthread_active_p ()) + { + if (thr_setspecific(_objc_thread_storage, value) == 0) + return 0; + else + return -1; + } + else + { + thread_local_storage = value; + return 0; + } +} + +/* Returns the thread's local storage pointer. */ +static inline void * +__gthread_objc_thread_get_data(void) +{ + void *value = NULL; + + if (__gthread_active_p ()) + { + if (thr_getspecific(_objc_thread_storage, &value) == 0) + return value; + else + return NULL; + } + else + return thread_local_storage; +} + +/* Backend mutex functions */ + +/* Allocate a mutex. */ +static inline int +__gthread_objc_mutex_allocate(objc_mutex_t mutex) +{ + if (__gthread_active_p () + && mutex_init( (mutex_t *)(&(mutex->backend)), USYNC_THREAD, 0)) + return -1; + + return 0; +} + +/* Deallocate a mutex. */ +static inline int +__gthread_objc_mutex_deallocate(objc_mutex_t mutex) +{ + if (__gthread_active_p ()) + mutex_destroy((mutex_t *)(&(mutex->backend))); + + return 0; +} + +/* Grab a lock on a mutex. */ +static inline int +__gthread_objc_mutex_lock(objc_mutex_t mutex) +{ + if (__gthread_active_p () + && mutex_lock((mutex_t *)(&(mutex->backend))) != 0) + return -1; + + return 0; +} + +/* Try to grab a lock on a mutex. */ +static inline int +__gthread_objc_mutex_trylock(objc_mutex_t mutex) +{ + if (__gthread_active_p () + && mutex_trylock((mutex_t *)(&(mutex->backend))) != 0) + return -1; + + return 0; +} + +/* Unlock the mutex */ +static inline int +__gthread_objc_mutex_unlock(objc_mutex_t mutex) +{ + if (__gthread_active_p () + && mutex_unlock((mutex_t *)(&(mutex->backend))) != 0) + return -1; + + return 0; +} + +/* Backend condition mutex functions */ + +/* Allocate a condition. */ +static inline int +__gthread_objc_condition_allocate(objc_condition_t condition) +{ + if (__gthread_active_p ()) + return cond_init((cond_t *)(&(condition->backend)), USYNC_THREAD, + NULL); + else + return 0; +} + +/* Deallocate a condition. */ +static inline int +__gthread_objc_condition_deallocate(objc_condition_t condition) +{ + if (__gthread_active_p ()) + return cond_destroy((cond_t *)(&(condition->backend))); + else + return 0; +} + +/* Wait on the condition */ +static inline int +__gthread_objc_condition_wait(objc_condition_t condition, objc_mutex_t mutex) +{ + if (__gthread_active_p ()) + return cond_wait((cond_t *)(&(condition->backend)), + (mutex_t *)(&(mutex->backend))); + else + return 0; +} + +/* Wake up all threads waiting on this condition. */ +static inline int +__gthread_objc_condition_broadcast(objc_condition_t condition) +{ + if (__gthread_active_p ()) + return cond_broadcast((cond_t *)(&(condition->backend))); + else + return 0; +} + +/* Wake up one thread waiting on this condition. */ +static inline int +__gthread_objc_condition_signal(objc_condition_t condition) +{ + if (__gthread_active_p ()) + return cond_signal((cond_t *)(&(condition->backend))); + else + return 0; +} + +#else /* _LIBOBJC */ + static inline int __gthread_once (__gthread_once_t *once, void (*func) (void)) { @@ -174,4 +475,6 @@ __gthread_mutex_unlock (__gthread_mutex_t *mutex) return 0; } +#endif /* _LIBOBJC */ + #endif /* not __gthr_solaris_h */ diff --git a/gcc/gthr-vxworks.h b/gcc/gthr-vxworks.h index fc6c9dc932d..c140cf85f0e 100644 --- a/gcc/gthr-vxworks.h +++ b/gcc/gthr-vxworks.h @@ -1,6 +1,6 @@ -/* Threads compatibility routines for libgcc2 for VxWorks. */ +/* Threads compatibility routines for libgcc2 and libobjc for VxWorks. */ /* Compile this one with gcc. */ -/* Copyright (C) 1997 Free Software Foundation, Inc. +/* Copyright (C) 1997, 1999, 2000 Free Software Foundation, Inc. Contributed by Mike Stump <mrs@wrs.com>. This file is part of GNU CC. @@ -30,6 +30,172 @@ Boston, MA 02111-1307, USA. */ #ifndef __gthr_vxworks_h #define __gthr_vxworks_h +#ifdef _LIBOBJC + +/* Thread local storage for a single thread */ +static void *thread_local_storage = NULL; + +/* Backend initialization functions */ + +/* Initialize the threads subsystem. */ +int +__gthread_objc_init_thread_system(void) +{ + /* No thread support available */ + return -1; +} + +/* Close the threads subsystem. */ +int +__gthread_objc_close_thread_system(void) +{ + /* No thread support available */ + return -1; +} + +/* Backend thread functions */ + +/* Create a new thread of execution. */ +objc_thread_t +__gthread_objc_thread_detach(void (*func)(void *arg), void *arg) +{ + /* No thread support available */ + return NULL; +} + +/* Set the current thread's priority. */ +int +__gthread_objc_thread_set_priority(int priority) +{ + /* No thread support available */ + return -1; +} + +/* Return the current thread's priority. */ +int +__gthread_objc_thread_get_priority(void) +{ + return OBJC_THREAD_INTERACTIVE_PRIORITY; +} + +/* Yield our process time to another thread. */ +void +__gthread_objc_thread_yield(void) +{ + return; +} + +/* Terminate the current thread. */ +int +__gthread_objc_thread_exit(void) +{ + /* No thread support available */ + /* Should we really exit the program */ + /* exit(&__objc_thread_exit_status); */ + return -1; +} + +/* Returns an integer value which uniquely describes a thread. */ +objc_thread_t +__gthread_objc_thread_id(void) +{ + /* No thread support, use 1. */ + return (objc_thread_t)1; +} + +/* Sets the thread's local storage pointer. */ +int +__gthread_objc_thread_set_data(void *value) +{ + thread_local_storage = value; + return 0; +} + +/* Returns the thread's local storage pointer. */ +void * +__gthread_objc_thread_get_data(void) +{ + return thread_local_storage; +} + +/* Backend mutex functions */ + +/* Allocate a mutex. */ +int +__gthread_objc_mutex_allocate(objc_mutex_t mutex) +{ + return 0; +} + +/* Deallocate a mutex. */ +int +__gthread_objc_mutex_deallocate(objc_mutex_t mutex) +{ + return 0; +} + +/* Grab a lock on a mutex. */ +int +__gthread_objc_mutex_lock(objc_mutex_t mutex) +{ + /* There can only be one thread, so we always get the lock */ + return 0; +} + +/* Try to grab a lock on a mutex. */ +int +__gthread_objc_mutex_trylock(objc_mutex_t mutex) +{ + /* There can only be one thread, so we always get the lock */ + return 0; +} + +/* Unlock the mutex */ +int +__gthread_objc_mutex_unlock(objc_mutex_t mutex) +{ + return 0; +} + +/* Backend condition mutex functions */ + +/* Allocate a condition. */ +int +__gthread_objc_condition_allocate(objc_condition_t condition) +{ + return 0; +} + +/* Deallocate a condition. */ +int +__gthread_objc_condition_deallocate(objc_condition_t condition) +{ + return 0; +} + +/* Wait on the condition */ +int +__gthread_objc_condition_wait(objc_condition_t condition, objc_mutex_t mutex) +{ + return 0; +} + +/* Wake up all threads waiting on this condition. */ +int +__gthread_objc_condition_broadcast(objc_condition_t condition) +{ + return 0; +} + +/* Wake up one thread waiting on this condition. */ +int +__gthread_objc_condition_signal(objc_condition_t condition) +{ + return 0; +} + +#else /* _LIBOBJC */ + /* POSIX threads specific definitions. Easy, since the interface is just one-to-one mapping. */ @@ -139,4 +305,6 @@ __gthread_mutex_unlock (__gthread_mutex_t *mutex) return semGive (*mutex); } +#endif /* _LIBOBJC */ + #endif /* not __gthr_vxworks_h */ diff --git a/gcc/gthr-win32.h b/gcc/gthr-win32.h index 9c822179592..119cbc7d9b9 100644 --- a/gcc/gthr-win32.h +++ b/gcc/gthr-win32.h @@ -1,4 +1,4 @@ -/* Threads compatibility routines for libgcc2. */ +/* Threads compatibility routines for libgcc2 and libobjc. */ /* Compile this one with gcc. */ /* Copyright (C) 1999, 2000 Free Software Foundation, Inc. Contributed by Mumit Khan <khan@xraylith.wisc.edu>. @@ -65,7 +65,248 @@ Boston, MA 02111-1307, USA. */ #define __GTHREADS 1 #include <windows.h> -#include <errno.h> + +#ifdef _LIBOBJC + +/* Key structure for maintaining thread specific storage */ +static DWORD __gthread_objc_data_tls = (DWORD)-1; + +/* Backend initialization functions */ + +/* Initialize the threads subsystem. */ +int +__gthread_objc_init_thread_system(void) +{ + /* Initialize the thread storage key */ + if ((__gthread_objc_data_tls = TlsAlloc()) != (DWORD)-1) + return 0; + else + return -1; +} + +/* Close the threads subsystem. */ +int +__gthread_objc_close_thread_system(void) +{ + if (__gthread_objc_data_tls != (DWORD)-1) + TlsFree(__gthread_objc_data_tls); + return 0; +} + +/* Backend thread functions */ + +/* Create a new thread of execution. */ +objc_thread_t +__gthread_objc_thread_detach(void (*func)(void *arg), void *arg) +{ + DWORD thread_id = 0; + HANDLE win32_handle; + + if (!(win32_handle = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)func, + arg, 0, &thread_id))) + thread_id = 0; + + return (objc_thread_t)thread_id; +} + +/* Set the current thread's priority. */ +int +__gthread_objc_thread_set_priority(int priority) +{ + int sys_priority = 0; + + switch (priority) + { + case OBJC_THREAD_INTERACTIVE_PRIORITY: + sys_priority = THREAD_PRIORITY_NORMAL; + break; + default: + case OBJC_THREAD_BACKGROUND_PRIORITY: + sys_priority = THREAD_PRIORITY_BELOW_NORMAL; + break; + case OBJC_THREAD_LOW_PRIORITY: + sys_priority = THREAD_PRIORITY_LOWEST; + break; + } + + /* Change priority */ + if (SetThreadPriority(GetCurrentThread(), sys_priority)) + return 0; + else + return -1; +} + +/* Return the current thread's priority. */ +int +__gthread_objc_thread_get_priority(void) +{ + int sys_priority; + + sys_priority = GetThreadPriority(GetCurrentThread()); + + switch (sys_priority) + { + case THREAD_PRIORITY_HIGHEST: + case THREAD_PRIORITY_TIME_CRITICAL: + case THREAD_PRIORITY_ABOVE_NORMAL: + case THREAD_PRIORITY_NORMAL: + return OBJC_THREAD_INTERACTIVE_PRIORITY; + + default: + case THREAD_PRIORITY_BELOW_NORMAL: + return OBJC_THREAD_BACKGROUND_PRIORITY; + + case THREAD_PRIORITY_IDLE: + case THREAD_PRIORITY_LOWEST: + return OBJC_THREAD_LOW_PRIORITY; + } + + /* Couldn't get priority. */ + return -1; +} + +/* Yield our process time to another thread. */ +void +__gthread_objc_thread_yield(void) +{ + Sleep(0); +} + +/* Terminate the current thread. */ +int +__gthread_objc_thread_exit(void) +{ + /* exit the thread */ + ExitThread(__gthread_objc_thread_exit_status); + + /* Failed if we reached here */ + return -1; +} + +/* Returns an integer value which uniquely describes a thread. */ +objc_thread_t +__gthread_objc_thread_id(void) +{ + return (objc_thread_t)GetCurrentThreadId(); +} + +/* Sets the thread's local storage pointer. */ +int +__gthread_objc_thread_set_data(void *value) +{ + if (TlsSetValue(__gthread_objc_data_tls, value)) + return 0; + else + return -1; +} + +/* Returns the thread's local storage pointer. */ +void * +__gthread_objc_thread_get_data(void) +{ + return TlsGetValue(__gthread_objc_data_tls); /* Return thread data. */ +} + +/* Backend mutex functions */ + +/* Allocate a mutex. */ +int +__gthread_objc_mutex_allocate(objc_mutex_t mutex) +{ + if ((mutex->backend = (void *)CreateMutex(NULL, 0, NULL)) == NULL) + return -1; + else + return 0; +} + +/* Deallocate a mutex. */ +int +__gthread_objc_mutex_deallocate(objc_mutex_t mutex) +{ + CloseHandle((HANDLE)(mutex->backend)); + return 0; +} + +/* Grab a lock on a mutex. */ +int +__gthread_objc_mutex_lock(objc_mutex_t mutex) +{ + int status; + + status = WaitForSingleObject((HANDLE)(mutex->backend), INFINITE); + if (status != WAIT_OBJECT_0 && status != WAIT_ABANDONED) + return -1; + else + return 0; +} + +/* Try to grab a lock on a mutex. */ +int +__gthread_objc_mutex_trylock(objc_mutex_t mutex) +{ + int status; + + status = WaitForSingleObject((HANDLE)(mutex->backend), 0); + if (status != WAIT_OBJECT_0 && status != WAIT_ABANDONED) + return -1; + else + return 0; +} + +/* Unlock the mutex */ +int +__gthread_objc_mutex_unlock(objc_mutex_t mutex) +{ + if (ReleaseMutex((HANDLE)(mutex->backend)) == 0) + return -1; + else + return 0; +} + +/* Backend condition mutex functions */ + +/* Allocate a condition. */ +int +__gthread_objc_condition_allocate(objc_condition_t condition) +{ + /* Unimplemented. */ + return -1; +} + +/* Deallocate a condition. */ +int +__gthread_objc_condition_deallocate(objc_condition_t condition) +{ + /* Unimplemented. */ + return -1; +} + +/* Wait on the condition */ +int +__gthread_objc_condition_wait(objc_condition_t condition, objc_mutex_t mutex) +{ + /* Unimplemented. */ + return -1; +} + +/* Wake up all threads waiting on this condition. */ +int +__gthread_objc_condition_broadcast(objc_condition_t condition) +{ + /* Unimplemented. */ + return -1; +} + +/* Wake up one thread waiting on this condition. */ +int +__gthread_objc_condition_signal(objc_condition_t condition) +{ + /* Unimplemented. */ + return -1; +} + +#else /* _LIBOBJC */ + #ifdef __MINGW32__ #include <_mingw.h> #endif @@ -227,5 +468,7 @@ __gthread_mutex_unlock (__gthread_mutex_t *mutex) return 0; } +#endif /* _LIBOBJC */ + #endif /* not __gthr_win32_h */ diff --git a/libobjc/ChangeLog b/libobjc/ChangeLog index d3cb386cc5f..d94fcd87374 100644 --- a/libobjc/ChangeLog +++ b/libobjc/ChangeLog @@ -1,3 +1,15 @@ +2000-05-12 H.J. Lu (hjl@gnu.org) + + * Makefile.in (GTHREAD_FLAGS): New. + (ALL_CFLAGS): Add $(GTHREAD_FLAGS). + (OBJC_THREAD_FILE): Changed to thr-objc. + + * configure.in (GTHREAD_FLAGS): New, check and replace it for + Makefile. + (OBJC_THREAD_FILE): Removed. + + * thr-objc.c: New. + 2000-07-13 Kaveh R. Ghazi <ghazi@caip.rutgers.edu> * objc/hash.h: Include string.h. diff --git a/libobjc/Makefile.in b/libobjc/Makefile.in index e7833619e4e..1180d6b5786 100644 --- a/libobjc/Makefile.in +++ b/libobjc/Makefile.in @@ -60,8 +60,9 @@ RANLIB = @RANLIB@ CC = @CC@ CFLAGS = @CFLAGS@ +GTHREAD_FLAGS=@GTHREAD_FLAGS@ ALL_CFLAGS = -I. -I$(srcdir) $(CPPFLAGS) $(DEFS) $(CFLAGS) \ - -DIN_GCC -DIN_TARGET_LIBS + $(GTHREAD_FLAGS) -DIN_GCC -DIN_TARGET_LIBS # # Define the cc1obj in terms of the CC that is passed on from higher @@ -76,7 +77,7 @@ INCLUDES = -I$(srcdir)/objc -I$(srcdir)/$(MULTISRCTOP)../gcc \ -I$(srcdir)/$(MULTISRCTOP)../include OBJC_GCFLAGS=-DOBJC_WITH_GC=1 -OBJC_THREAD_FILE=thr-@OBJC_THREAD_FILE@ +OBJC_THREAD_FILE=thr-objc .SUFFIXES: .SUFFIXES: .c .m .o diff --git a/libobjc/configure b/libobjc/configure index 0469252015a..9d0322d79ac 100755 --- a/libobjc/configure +++ b/libobjc/configure @@ -1140,23 +1140,23 @@ EOF fi -# Determine the name of the GCC thread file. +# Determine gthread FLAGS. -echo $ac_n "checking for thread file""... $ac_c" 1>&6 -echo "configure:1147: checking for thread file" >&5 -if eval "test \"`echo '$''{'objc_cv_thread_file'+set}'`\" = set"; then +echo $ac_n "checking for gthread FLAGS""... $ac_c" 1>&6 +echo "configure:1147: checking for gthread FLAGS" >&5 +if eval "test \"`echo '$''{'objc_cv_gthread_flags'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else if test -f "$r"/gcc/Makefile then - objc_cv_thread_file=`grep \^GCC_THREAD_FILE "$r"/gcc/Makefile | awk -F= '{ print $2 }'` + objc_cv_gthread_flags=`grep \^GTHREAD_FLAGS "$r"/gcc/Makefile | awk -F= '{ print $2 }'` else { echo "configure: error: not found" 1>&2; exit 1; } fi fi -echo "$ac_t""$objc_cv_thread_file" 1>&6 -OBJC_THREAD_FILE=$objc_cv_thread_file +echo "$ac_t""$objc_cv_gthread_flags" 1>&6 +GTHREAD_FLAGS=$objc_cv_gthread_flags # Check whether --enable-objc-gc or --disable-objc-gc was given. @@ -1327,7 +1327,7 @@ s%@INSTALL_PROGRAM@%$INSTALL_PROGRAM%g s%@INSTALL_SCRIPT@%$INSTALL_SCRIPT%g s%@INSTALL_DATA@%$INSTALL_DATA%g s%@CPP@%$CPP%g -s%@OBJC_THREAD_FILE@%$OBJC_THREAD_FILE%g +s%@GTHREAD_FLAGS@%$GTHREAD_FLAGS%g s%@OBJC_BOEHM_GC@%$OBJC_BOEHM_GC%g CEOF diff --git a/libobjc/configure.in b/libobjc/configure.in index 821dcd2a9de..b2d656a2773 100644 --- a/libobjc/configure.in +++ b/libobjc/configure.in @@ -91,17 +91,17 @@ the Objective C runtime system. If necessary, install gcc now with AC_HEADER_STDC -# Determine the name of the GCC thread file. +# Determine CFLAGS for gthread. -AC_CACHE_CHECK([for thread file],objc_cv_thread_file, +AC_CACHE_CHECK([for gthread cflags],objc_cv_gthread_flags, [if test -f "$r"/gcc/Makefile then - objc_cv_thread_file=`grep \^GCC_THREAD_FILE "$r"/gcc/Makefile | awk -F= '{ print $2 }'` + objc_cv_gthread_flags=`grep \^GTHREAD_FLAGS "$r"/gcc/Makefile | awk -F= '{ print $2 }'` else AC_MSG_ERROR([not found]) fi]) -OBJC_THREAD_FILE=$objc_cv_thread_file -AC_SUBST(OBJC_THREAD_FILE) +GTHREAD_FLAGS=$objc_cv_gthread_flags +AC_SUBST(GTHREAD_FLAGS) AC_ARG_ENABLE(objc-gc, [ --enable-objc-gc enable the use of Boehm's garbage collector with diff --git a/libobjc/thr-objc.c b/libobjc/thr-objc.c new file mode 100644 index 00000000000..48150f0ef3e --- /dev/null +++ b/libobjc/thr-objc.c @@ -0,0 +1,181 @@ +/* GNU Objective C Runtime Thread Interface. + Copyright (C) 1999 Free Software Foundation, Inc. + +This file is part of GNU CC. + +GNU CC is free software; you can redistribute it and/or modify it under the +terms of the GNU General Public License as published by the Free Software +Foundation; either version 2, or (at your option) any later version. + +GNU CC is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +FOR A PARTICULAR PURPOSE. See the GNU General Public License for more +details. + +You should have received a copy of the GNU General Public License +along with GNU CC; see the file COPYING. If not, write to +the Free Software Foundation, 59 Temple Place - Suite 330, +Boston, MA 02111-1307, USA. */ + +/* As a special exception, if you link this library with files compiled with + GCC to produce an executable, this does not cause the resulting executable + to be covered by the GNU General Public License. This exception does not + however invalidate any other reasons why the executable file might be + covered by the GNU General Public License. */ + +#define _LIBOBJC +#include "tconfig.h" +#include "defaults.h" +#include <objc/thr.h> +#include "runtime.h" +#include <gthr.h> + +/* Backend initialization functions */ + +/* Initialize the threads subsystem. */ +int +__objc_init_thread_system(void) +{ + return __gthread_objc_init_thread_system (); +} + +/* Close the threads subsystem. */ +int +__objc_close_thread_system(void) +{ + return __gthread_objc_close_thread_system (); +} + +/* Backend thread functions */ + +/* Create a new thread of execution. */ +objc_thread_t +__objc_thread_detach(void (*func)(void *), void *arg) +{ + return __gthread_objc_thread_detach (func, arg); +} + +/* Set the current thread's priority. */ +int +__objc_thread_set_priority(int priority) +{ + return __gthread_objc_thread_set_priority (priority); +} + +/* Return the current thread's priority. */ +int +__objc_thread_get_priority(void) +{ + return __gthread_objc_thread_get_priority (); +} + +/* Yield our process time to another thread. */ +void +__objc_thread_yield(void) +{ + __gthread_objc_thread_yield (); +} + +/* Terminate the current thread. */ +int +__objc_thread_exit(void) +{ + return __gthread_objc_thread_exit (); +} + +/* Returns an integer value which uniquely describes a thread. */ +objc_thread_t +__objc_thread_id(void) +{ + return __gthread_objc_thread_id (); +} + +/* Sets the thread's local storage pointer. */ +int +__objc_thread_set_data(void *value) +{ + return __gthread_objc_thread_set_data (value); +} + +/* Returns the thread's local storage pointer. */ +void * +__objc_thread_get_data(void) +{ + return __gthread_objc_thread_get_data (); +} + +/* Backend mutex functions */ + +/* Allocate a mutex. */ +int +__objc_mutex_allocate(objc_mutex_t mutex) +{ + return __gthread_objc_mutex_allocate (mutex); +} + +/* Deallocate a mutex. */ +int +__objc_mutex_deallocate(objc_mutex_t mutex) +{ + return __gthread_objc_mutex_deallocate (mutex); +} + +/* Grab a lock on a mutex. */ +int +__objc_mutex_lock(objc_mutex_t mutex) +{ + return __gthread_objc_mutex_lock (mutex); +} + +/* Try to grab a lock on a mutex. */ +int +__objc_mutex_trylock(objc_mutex_t mutex) +{ + return __gthread_objc_mutex_trylock (mutex); +} + +/* Unlock the mutex */ +int +__objc_mutex_unlock(objc_mutex_t mutex) +{ + return __gthread_objc_mutex_unlock (mutex); +} + +/* Backend condition mutex functions */ + +/* Allocate a condition. */ +int +__objc_condition_allocate(objc_condition_t condition) +{ + return __gthread_objc_condition_allocate (condition); +} + +/* Deallocate a condition. */ +int +__objc_condition_deallocate(objc_condition_t condition) +{ + return __gthread_objc_condition_deallocate (condition); +} + +/* Wait on the condition */ +int +__objc_condition_wait(objc_condition_t condition, objc_mutex_t mutex) +{ + return __gthread_objc_condition_wait (condition, mutex); +} + +/* Wake up all threads waiting on this condition. */ +int +__objc_condition_broadcast(objc_condition_t condition) +{ + return __gthread_objc_condition_broadcast (condition); +} + +/* Wake up one thread waiting on this condition. */ +int +__objc_condition_signal(objc_condition_t condition) +{ + return __gthread_objc_condition_signal (condition); +} + +/* End of File */ |