aboutsummaryrefslogtreecommitdiff
path: root/gcc/objc
diff options
context:
space:
mode:
authorRichard Kenner <kenner@gcc.gnu.org>1997-06-25 16:25:24 -0400
committerRichard Kenner <kenner@gcc.gnu.org>1997-06-25 16:25:24 -0400
commit2024f9e4dc4746fc1f87a82ccd998d0c24f75d8c (patch)
tree938bbdc79bc8962b1b6cd7bb530731700295bc79 /gcc/objc
parentf15e9e7ef22cffbdff2f1792dfc0d539fdd26a01 (diff)
downloadgcc-2024f9e4dc4746fc1f87a82ccd998d0c24f75d8c.zip
gcc-2024f9e4dc4746fc1f87a82ccd998d0c24f75d8c.tar.gz
gcc-2024f9e4dc4746fc1f87a82ccd998d0c24f75d8c.tar.bz2
Completely rework according to new interface.
From-SVN: r14310
Diffstat (limited to 'gcc/objc')
-rw-r--r--gcc/objc/thr-decosf1.c385
-rw-r--r--gcc/objc/thr-irix.c353
-rw-r--r--gcc/objc/thr-mach.c492
-rw-r--r--gcc/objc/thr-os2.c306
-rw-r--r--gcc/objc/thr-posix.c340
-rw-r--r--gcc/objc/thr-pthreads.c354
-rw-r--r--gcc/objc/thr-single.c284
-rw-r--r--gcc/objc/thr-solaris.c428
-rw-r--r--gcc/objc/thr-win32.c383
-rw-r--r--gcc/objc/thr.c505
10 files changed, 1632 insertions, 2198 deletions
diff --git a/gcc/objc/thr-decosf1.c b/gcc/objc/thr-decosf1.c
index fa432aa..0c611b8 100644
--- a/gcc/objc/thr-decosf1.c
+++ b/gcc/objc/thr-decosf1.c
@@ -28,299 +28,254 @@ Boston, MA 02111-1307, USA. */
#include <objc/thr.h>
#include "runtime.h"
-/********
- * This structure represents a single mutual exclusion lock. Lock semantics
- * are detailed with the subsequent functions. We use whatever lock is
- * provided by the system. We augment it with depth and current owner id
- * fields to implement and re-entrant lock.
- */
-struct objc_mutex
-{
- volatile objc_thread_t owner; /* Id of thread that owns. */
- volatile int depth; /* # of acquires. */
- pthread_mutex_t lock; /* pthread mutex. */
-};
-
-/*****************************************************************************
- * Static variables.
- */
-static pthread_key_t __objc_thread_data_key; /* Data key for thread data.*/
+/* Key structure for maintiain thread specific storage */
+static pthread_key_t _objc_thread_storage;
+/* Backend initialization functions */
-/********
- * Initialize the threads subsystem. Returns 0 if successful, or -1 if no
- * thread support is available.
- */
+/* Initialize the threads subsystem. */
int
__objc_init_thread_system(void)
{
- printf("__objc_init_thread_system\n");
-
- if (pthread_keycreate(&__objc_thread_data_key, NULL) == 0)
- return 0; /* Yes, return success. */
-
- return -1; /* Failed. */
+ /* Initialize the thread storage key */
+ return pthread_keycreate(&_objc_thread_storage, NULL);
}
+/* Close the threads subsystem. */
int
-__objc_fini_thread_system(void)
+__objc_close_thread_system(void)
{
+ /* Destroy the thread storage key */
+ /* Not implemented yet */
+ /* return pthread_key_delete(&_objc_thread_storage); */
return 0;
}
-/********
- * Create a new thread of execution and return its id. Return NULL if fails.
- * The new thread starts in "func" with the given argument.
- */
+/* Backend thread functions */
+
+/* Create a new thread of execution. */
objc_thread_t
-objc_thread_create(void (*func)(void *arg), void *arg)
+__objc_thread_detach(void (*func)(void *arg), void *arg)
{
- objc_thread_t thread_id = NULL; /* Detached thread id. */
- pthread_t new_thread_handle; /* DCE thread handle. */
-
- objc_mutex_lock(__objc_runtime_mutex);
-
- if (pthread_create(&new_thread_handle, pthread_attr_default,
- (void *)func, arg) == 0) {
- /* ??? May not work! (64bit)*/
- thread_id = *(objc_thread_t *)&new_thread_handle;
- pthread_detach(&new_thread_handle); /* Fully detach thread. */
- __objc_runtime_threads_alive++;
+ objc_thread_t thread_id;
+ pthread_t new_thread_handle;
+
+ if (pthread_create(&new_thread_handle, pthread_attr_default,
+ (void *)func, arg) == 0)
+ {
+ /* ??? May not work! (64bit) */
+ thread_id = *(objc_thread_t *)&new_thread_handle;
+ pthread_detach(&new_thread_handle); /* Fully detach thread. */
}
-
- objc_mutex_unlock(__objc_runtime_mutex);
- return thread_id;
+ else
+ thread_id = NULL;
+
+ return thread_id;
}
-/********
- * Set the current thread's priority.
- */
+/* Set the current thread's priority. */
int
-objc_thread_set_priority(int priority)
+__objc_thread_set_priority(int priority)
{
- int sys_priority = 0;
+ int sys_priority = 0;
- switch (priority) {
+ switch (priority)
+ {
case OBJC_THREAD_INTERACTIVE_PRIORITY:
- sys_priority = (PRI_FG_MIN_NP + PRI_FG_MAX_NP) / 2;
- break;
+ 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;
+ 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;
+ sys_priority = (PRI_BG_MIN_NP + PRI_BG_MAX_NP) / 2;
+ break;
}
- if (pthread_setprio(pthread_self(), sys_priority) >= 0)
- return 0; /* Changed priority. End. */
-
- return -1; /* Failed. */
+ /* Change the priority. */
+ if (pthread_setprio(pthread_self(), sys_priority) >= 0)
+ return 0;
+ else
+ /* Failed */
+ return -1;
}
-/********
- * Return the current thread's priority.
- */
+/* Return the current thread's priority. */
int
-objc_thread_get_priority(void)
+__objc_thread_get_priority(void)
{
- int sys_priority; /* DCE thread priority. */
+ int sys_priority;
- 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;
- }
- return -1; /* Couldn't get priority. */
+ 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;
}
-/********
- * Yield our process time to another thread. Any BUSY waiting that is done
- * by a thread should use this function to make sure that other threads can
- * make progress even on a lazy uniprocessor system.
- */
+/* Yield our process time to another thread. */
void
-objc_thread_yield(void)
+__objc_thread_yield(void)
{
- pthread_yield(); /* Yield to equal thread. */
+ pthread_yield();
}
-/********
- * Terminate the current tread. Doesn't return anything. Doesn't return.
- * Actually, if it failed returns -1.
- */
+/* Terminate the current thread. */
int
-objc_thread_exit(void)
+__objc_thread_exit(void)
{
- objc_mutex_lock(__objc_runtime_mutex);
- __objc_runtime_threads_alive--;
- objc_mutex_unlock(__objc_runtime_mutex);
-
- pthread_exit(&__objc_thread_exit_status); /* Terminate thread. */
+ /* 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. Must not be
- * -1 which is reserved as a marker for "no thread".
- */
+/* Returns an integer value which uniquely describes a thread. */
objc_thread_t
-objc_thread_id(void)
+__objc_thread_id(void)
{
pthread_t self = pthread_self();
return (objc_thread_t) pthread_getuniqe_np (&self);
}
-/********
- * Sets the thread's local storage pointer. Returns 0 if successful or -1
- * if failed.
- */
+/* Sets the thread's local storage pointer. */
int
-objc_thread_set_data(void *value)
+__objc_thread_set_data(void *value)
{
- if (pthread_setspecific(__objc_thread_data_key, (void *)value) == 0)
- return 0; /* Return thread data. */
- return -1;
+ return pthread_setspecific(_objc_thread_storage, value);
}
-/********
- * Returns the thread's local storage pointer. Returns NULL on failure.
- */
+/* Returns the thread's local storage pointer. */
void *
-objc_thread_get_data(void)
+__objc_thread_get_data(void)
{
- void * value = NULL;
-
- if (pthread_getspecific(__objc_thread_data_key, (void *)&value) == 0)
- return value; /* Return thread data. */
-
- return NULL;
+ void *value = NULL;
+
+ if ( !(pthread_getspecific(_objc_thread_storage, &value)) )
+ return value;
+
+ return NULL;
}
-/********
- * Allocate a mutex. Return the mutex pointer if successful or NULL if
- * the allocation fails for any reason.
- */
-objc_mutex_t
-objc_mutex_allocate(void)
+/* Backend mutex functions */
+
+/* Allocate a mutex. */
+int
+__objc_mutex_allocate(objc_mutex_t mutex)
{
- objc_mutex_t mutex;
- int err = 0;
-
- if (!(mutex = (objc_mutex_t)objc_malloc(sizeof(struct objc_mutex))))
- return NULL; /* Abort if malloc failed. */
-
- err = pthread_mutex_init(&mutex->lock, pthread_mutexattr_default);
-
- if (err != 0) { /* System init failed? */
- objc_free(mutex); /* Yes, free local memory. */
- return NULL; /* Abort. */
- }
- mutex->owner = (objc_thread_t) -1; /* No owner. */
- mutex->depth = 0; /* No locks. */
- return mutex; /* Return mutex handle. */
+ if (pthread_mutex_init((pthread_mutex_t *)(&(mutex->backend)),
+ pthread_mutexattr_default))
+ return -1;
+ else
+ return 0;
}
-/********
- * Deallocate a mutex. Note that this includes an implicit mutex_lock to
- * insure that no one else is using the lock. It is legal to deallocate
- * a lock if we have a lock on it, but illegal to deallotcate a lock held
- * by anyone else.
- * Returns the number of locks on the thread. (1 for deallocate).
- */
+/* Deallocate a mutex. */
int
-objc_mutex_deallocate(objc_mutex_t mutex)
+__objc_mutex_deallocate(objc_mutex_t mutex)
{
- int depth; /* # of locks on mutex. */
+ if (pthread_mutex_destroy((pthread_mutex_t *)(&(mutex->backend))))
+ return -1;
+ else
+ return 0;
+}
- if (!mutex) /* Is argument bad? */
- return -1; /* Yes, abort. */
- depth = objc_mutex_lock(mutex); /* Must have lock. */
-
- pthread_mutex_unlock(&mutex->lock); /* Must unlock system mutex.*/
- pthread_mutex_destroy(&mutex->lock); /* Free system mutex. */
-
- objc_free(mutex); /* Free memory. */
- return depth; /* Return last depth. */
+/* Grab a lock on a mutex. */
+int
+__objc_mutex_lock(objc_mutex_t mutex)
+{
+ return pthread_mutex_lock((pthread_mutex_t *)(&(mutex->backend)));
}
-/********
- * Grab a lock on a mutex. If this thread already has a lock on this mutex
- * then we increment the lock count. If another thread has a lock on the
- * mutex we block and wait for the thread to release the lock.
- * Returns the lock count on the mutex held by this thread.
- */
+/* Try to grab a lock on a mutex. */
int
-objc_mutex_lock(objc_mutex_t mutex)
+__objc_mutex_trylock(objc_mutex_t mutex)
{
- objc_thread_t thread_id; /* Cache our thread id. */
+ if (pthread_mutex_trylock((pthread_mutex_t *)(&(mutex->backend))) != 1)
+ return -1;
+ else
+ return 0;
+}
+
+/* Unlock the mutex */
+int
+__objc_mutex_unlock(objc_mutex_t mutex)
+{
+ return pthread_mutex_unlock((pthread_mutex_t *)(&(mutex->backend)));
+}
- if (!mutex) /* Is argument bad? */
- return -1; /* Yes, abort. */
- thread_id = objc_thread_id(); /* Get this thread's id. */
- if (mutex->owner == thread_id) /* Already own lock? */
- return ++mutex->depth; /* Yes, increment depth. */
+/* Backend condition mutex functions */
- if (pthread_mutex_lock(&mutex->lock) != 0) /* Lock DCE system mutex. */
- return -1; /* Failed, abort. */
-
- mutex->owner = thread_id; /* Mark thread as owner. */
- return mutex->depth = 1; /* Increment depth to end. */
+/* Allocate a condition. */
+int
+__objc_condition_allocate(objc_condition_t condition)
+{
+ /* Unimplemented. */
+ return -1;
+
+ /*
+ if (pthread_cond_init((pthread_cond_t *)(&(condition->backend)), NULL))
+ return -1;
+ else
+ return 0;
+ */
}
-/********
- * Try to grab a lock on a mutex. If this thread already has a lock on
- * this mutex then we increment the lock count and return it. If another
- * thread has a lock on the mutex returns -1.
- */
+/* Deallocate a condition. */
int
-objc_mutex_trylock(objc_mutex_t mutex)
+__objc_condition_deallocate(objc_condition_t condition)
{
- objc_thread_t thread_id; /* Cache our thread id. */
+ /* Unimplemented. */
+ return -1;
- if (!mutex) /* Is argument bad? */
- return -1; /* Yes, abort. */
- thread_id = objc_thread_id(); /* Get this thread's id. */
- if (mutex->owner == thread_id) /* Already own lock? */
- return ++mutex->depth; /* Yes, increment depth. */
-
- if (pthread_mutex_trylock(&mutex->lock) != 1) /* Lock DCE system mutex. */
- return -1; /* Failed, abort. */
-
- mutex->owner = thread_id; /* Mark thread as owner. */
- return mutex->depth = 1; /* Increment depth to end. */
+ /*
+ return pthread_cond_destroy((pthread_cond_t *)(&(condition->backend)));
+ */
}
-/********
- * Decrements the lock count on this mutex by one. If the lock count reaches
- * zero, release the lock on the mutex. Returns the lock count on the mutex.
- * It is an error to attempt to unlock a mutex which this thread doesn't hold
- * in which case return -1 and the mutex is unaffected.
- * Will also return -1 if the mutex free fails.
- */
+/* Wait on the condition */
int
-objc_mutex_unlock(objc_mutex_t mutex)
+__objc_condition_wait(objc_condition_t condition, objc_mutex_t mutex)
{
- objc_thread_t thread_id; /* Cache our thread id. */
-
- if (!mutex) /* Is argument bad? */
- return -1; /* Yes, abort. */
- thread_id = objc_thread_id(); /* Get this thread's id. */
- if (mutex->owner != thread_id) /* Does some else own lock? */
- return -1; /* Yes, abort. */
- if (mutex->depth > 1) /* Released last lock? */
- return --mutex->depth; /* No, Decrement depth, end.*/
- mutex->depth = 0; /* Yes, reset depth to 0. */
- mutex->owner = (objc_thread_t) -1; /* Set owner to "no thread".*/
-
- if (pthread_mutex_unlock(&mutex->lock) != 0) /* Unlock system mutex. */
- return -1; /* Failed, abort. */
-
- return 0; /* No, return success. */
+ /* Unimplemented. */
+ return -1;
+
+ /*
+ return pthread_cond_wait((pthread_cond_t *)(&(condition->backend)),
+ (pthread_mutex_t *)(&(mutex->backend)));
+ */
+}
+
+/* Wake up all threads waiting on this condition. */
+int
+__objc_condition_broadcast(objc_condition_t condition)
+{
+ /* Unimplemented. */
+ return -1;
+
+ /*
+ return pthread_cond_broadcast((pthread_cond_t *)(&(condition->backend)));
+ */
+}
+
+/* Wake up one thread waiting on this condition. */
+int
+__objc_condition_signal(objc_condition_t condition)
+{
+ /* Unimplemented. */
+ return -1;
+
+ /*
+ return pthread_cond_signal((pthread_cond_t *)(&(condition->backend)));
+ */
}
/* End of File */
diff --git a/gcc/objc/thr-irix.c b/gcc/objc/thr-irix.c
index 6ea883e..4203254 100644
--- a/gcc/objc/thr-irix.c
+++ b/gcc/objc/thr-irix.c
@@ -32,283 +32,204 @@ Boston, MA 02111-1307, USA. */
#include <objc/thr.h>
#include "runtime.h"
-/********
- * This structure represents a single mutual exclusion lock. Lock semantics
- * are detailed with the subsequent functions. We use whatever lock is
- * provided by the system. We augment it with depth and current owner id
- * fields to implement and re-entrant lock.
- */
-struct objc_mutex
-{
- volatile objc_thread_t owner; /* Id of thread that owns. */
- volatile int depth; /* # of acquires. */
- ulock_t lock; /* Irix lock. */
-};
-
-/*****************************************************************************
- * Static variables.
- */
-static void * __objc_shared_arena_handle = NULL; /* Storage arena locks. */
-
-/********
- * Initialize the threads subsystem. Returns 0 if successful, or -1 if no
- * thread support is available.
- */
+/* Key structure for maintiain thread specific storage */
+static void * __objc_shared_arena_handle = NULL;
+
+/* Backend initialization functions */
+
+/* Initialize the threads subsystem. */
int
__objc_init_thread_system(void)
{
- char arena_name[64]; /* Name of IRIX arena. */
-
- DEBUG_PRINTF("__objc_init_thread_system\n");
- sprintf(arena_name, "/usr/tmp/objc_%05u", (unsigned)getpid());
- usconfig(CONF_INITUSERS, 256); /* Up to 256 threads. */
- usconfig(CONF_ARENATYPE, US_SHAREDONLY); /* Arena only for threads. */
- if (!(__objc_shared_arena_handle = usinit(arena_name))) /* Init Failed? */
- return -1; /* Yes, return error code. */
-
- return 0;
+ /* Name of IRIX arena. */
+ char arena_name[64];
+
+ DEBUG_PRINTF("__objc_init_thread_system\n");
+
+ /* Construct a temporary name for arena. */
+ sprintf(arena_name, "/usr/tmp/objc_%05u", (unsigned)getpid());
+
+ /* Up to 256 threads. Arena only for threads. */
+ usconfig(CONF_INITUSERS, 256);
+ usconfig(CONF_ARENATYPE, US_SHAREDONLY);
+
+ /* Initialize the arena */
+ if (!(__objc_shared_arena_handle = usinit(arena_name)))
+ /* Failed */
+ return -1;
+
+ return 0;
}
+/* Close the threads subsystem. */
int
-__objc_fini_thread_system(void)
+__objc_close_thread_system(void)
{
return 0;
}
-/********
- * Create a new thread of execution and return its id. Return NULL if fails.
- * The new thread starts in "func" with the given argument.
- */
+/* Backend thread functions */
+
+/* Create a new thread of execution. */
objc_thread_t
-objc_thread_create(void (*func)(void *arg), void *arg)
+__objc_thread_detach(void (*func)(void *arg), void *arg)
{
- objc_thread_t thread_id = NULL;
- int sys_id;
-
- objc_mutex_lock(__objc_runtime_mutex);
- if ((sys_id = sproc((void *)func, PR_SALL, arg)) >= 0) {
- thread_id = (objc_thread_t)sys_id;
- __objc_runtime_threads_alive++;
- }
- objc_mutex_unlock(__objc_runtime_mutex);
-
- return thread_id;
+ objc_thread_t thread_id;
+ int sys_id;
+
+ if ((sys_id = sproc((void *)func, PR_SALL, arg)) >= 0)
+ thread_id = (objc_thread_t)sys_id;
+ else
+ thread_id = NULL;
+
+ return thread_id;
}
-/********
- * Set the current thread's priority.
- */
+/* Set the current thread's priority. */
int
-objc_thread_set_priority(int priority)
+__objc_thread_set_priority(int priority)
{
- int sys_priority = 0;
-
- switch (priority) {
- case OBJC_THREAD_INTERACTIVE_PRIORITY:
- break;
- default:
- case OBJC_THREAD_BACKGROUND_PRIORITY:
- break;
- case OBJC_THREAD_LOW_PRIORITY:
- break;
- }
- return -1; /* Failed. */
+ /* Not implemented yet */
+ return -1;
}
-/********
- * Return the current thread's priority.
- */
+/* Return the current thread's priority. */
int
-objc_thread_get_priority(void)
+__objc_thread_get_priority(void)
{
- return -1; /* Couldn't get priority. */
+ /* Not implemented yet */
+ return OBJC_THREAD_INTERACTIVE_PRIORITY;
}
-/********
- * Yield our process time to another thread. Any BUSY waiting that is done
- * by a thread should use this function to make sure that other threads can
- * make progress even on a lazy uniprocessor system.
- */
+/* Yield our process time to another thread. */
void
-objc_thread_yield(void)
+__objc_thread_yield(void)
{
- sginap(0); /* Yield to equal process. */
+ sginap(0);
}
-/********
- * Terminate the current tread. Doesn't return anything. Doesn't return.
- * Actually, if it failed returns -1.
- */
+/* Terminate the current thread. */
int
-objc_thread_exit(void)
+__objc_thread_exit(void)
{
- objc_mutex_lock(__objc_runtime_mutex);
- __objc_runtime_threads_alive--;
- objc_mutex_unlock(__objc_runtime_mutex);
+ /* IRIX only has exit. */
+ exit(__objc_thread_exit_status);
- exit(__objc_thread_exit_status); /* IRIX only has exit. */
- return -1;
+ /* Failed if we reached here */
+ return -1;
}
-/********
- * Returns an integer value which uniquely describes a thread. Must not be
- * NULL which is reserved as a marker for "no thread".
- */
+/* Returns an integer value which uniquely describes a thread. */
objc_thread_t
-objc_thread_id(void)
+__objc_thread_id(void)
{
- return (objc_thread_t)get_pid(); /* Threads are processes. */
+ /* Threads are processes. */
+ return (objc_thread_t)get_pid();
}
-/********
- * Sets the thread's local storage pointer. Returns 0 if successful or -1
- * if failed.
- */
+/* Sets the thread's local storage pointer. */
int
-objc_thread_set_data(void *value)
+__objc_thread_set_data(void *value)
{
- *((void **)&PRDA->usr_prda) = value; /* Set thread data ptr. */
- return 0;
+ *((void **)&PRDA->usr_prda) = value;
+ return 0;
}
-/********
- * Returns the thread's local storage pointer. Returns NULL on failure.
- */
+/* Returns the thread's local storage pointer. */
void *
-objc_thread_get_data(void)
+__objc_thread_get_data(void)
+{
+ return *((void **)&PRDA->usr_prda);
+}
+
+/* Backend mutex functions */
+
+/* Allocate a mutex. */
+int
+__objc_mutex_allocate(objc_mutex_t mutex)
+{
+ if (!( (ulock_t)(mutex->backend) = usnewlock(__objc_shared_arena_handle) ))
+ return -1;
+ else
+ return 0;
+}
+
+/* Deallocate a mutex. */
+int
+__objc_mutex_deallocate(objc_mutex_t mutex)
{
- return *((void **)&PRDA->usr_prda); /* Return thread data ptr. */
+ usfreelock((ulock_t)(mutex->backend), __objc_shared_arena_handle);
+ return 0;
}
-/********
- * Allocate a mutex.
- * Return the mutex pointer if successful or NULL if the allocation failed
- * for any reason.
- */
-objc_mutex_t
-objc_mutex_allocate(void)
+/* Grab a lock on a mutex. */
+int
+__objc_mutex_lock(objc_mutex_t mutex)
{
- objc_mutex_t mutex;
- int err = 0;
-
- if (!(mutex = (objc_mutex_t)objc_malloc(sizeof(struct objc_mutex))))
- return NULL; /* Abort if malloc failed. */
-
- if (!(mutex->lock = usnewlock(__objc_shared_arena_handle)))
- err = -1;
-
- if (err != 0) { /* System init failed? */
- objc_free(mutex); /* Yes, free local memory. */
- return NULL; /* Abort. */
- }
- mutex->owner = NULL; /* No owner. */
- mutex->depth = 0; /* No locks. */
- return mutex; /* Return mutex handle. */
+ if (ussetlock((ulock_t)(mutex->backend)) == 0)
+ return -1;
+ else
+ return 0;
}
-/********
- * Deallocate a mutex. Note that this includes an implicit mutex_lock to
- * insure that no one else is using the lock. It is legal to deallocate
- * a lock if we have a lock on it, but illegal to deallotcate a lock held
- * by anyone else.
- * Returns the number of locks on the thread. (1 for deallocate).
- */
+/* Try to grab a lock on a mutex. */
int
-objc_mutex_deallocate(objc_mutex_t mutex)
+__objc_mutex_trylock(objc_mutex_t mutex)
{
- int depth; /* # of locks on mutex. */
-
- if (!mutex) /* Is argument bad? */
- return -1; /* Yes, abort. */
- depth = objc_mutex_lock(mutex); /* Must have lock. */
-
- usfreelock(mutex->lock, __objc_shared_arena_handle); /* Free IRIX lock. */
-
- objc_free(mutex); /* Free memory. */
- return depth; /* Return last depth. */
+ if (ustestlock((ulock_t)(mutex->backend)) == 0)
+ return -1;
+ else
+ return 0;
}
-/********
- * Grab a lock on a mutex. If this thread already has a lock on this mutex
- * then we increment the lock count. If another thread has a lock on the
- * mutex we block and wait for the thread to release the lock.
- * Returns the lock count on the mutex held by this thread.
- */
+/* Unlock the mutex */
int
-objc_mutex_lock(objc_mutex_t mutex)
+__objc_mutex_unlock(objc_mutex_t mutex)
{
- objc_thread_t thread_id; /* Cache our thread id. */
-
- if (!mutex) /* Is argument bad? */
- return -1; /* Yes, abort. */
- thread_id = objc_thread_id(); /* Get this thread's id. */
- if (mutex->owner == thread_id) { /* Already own lock? */
- DEBUG_PRINTF("lock owned by: %d:%d\n", mutex->owner, mutex->depth);
- return ++mutex->depth; /* Yes, increment depth. */
- }
-
- DEBUG_PRINTF("lock owned by: %d:%d (attempt by %d)\n",
- mutex->owner, mutex->depth, thread_id);
-
- if (ussetlock(mutex->lock) == 0) /* Did lock acquire fail? */
- return -1; /* Yes, abort. */
-
- mutex->owner = thread_id; /* Mark thread as owner. */
- return mutex->depth = 1; /* Increment depth to end. */
+ usunsetlock((ulock_t)(mutex->backend));
+ return 0;
}
-/********
- * Try to grab a lock on a mutex. If this thread already has a lock on
- * this mutex then we increment the lock count and return it. If another
- * thread has a lock on the mutex returns -1.
- */
+/* Backend condition mutex functions */
+
+/* Allocate a condition. */
int
-objc_mutex_trylock(objc_mutex_t mutex)
+__objc_condition_allocate(objc_condition_t condition)
{
- objc_thread_t thread_id; /* Cache our thread id. */
-
- if (!mutex) /* Is argument bad? */
- return -1; /* Yes, abort. */
- thread_id = objc_thread_id(); /* Get this thread's id. */
- if (mutex->owner == thread_id) /* Already own lock? */
- return ++mutex->depth; /* Yes, increment depth. */
-
- if (ustestlock(mutex->lock) == 0) /* Did lock acquire fail? */
- return -1; /* Yes, abort. */
-
- mutex->owner = thread_id; /* Mark thread as owner. */
- return mutex->depth = 1; /* Increment depth to end. */
+ /* Unimplemented. */
+ return -1;
}
-/********
- * Decrements the lock count on this mutex by one. If the lock count reaches
- * zero, release the lock on the mutex. Returns the lock count on the mutex.
- * It is an error to attempt to unlock a mutex which this thread doesn't hold
- * in which case return -1 and the mutex is unaffected.
- * Will also return -1 if the mutex free fails.
- */
+/* Deallocate a condition. */
+int
+__objc_condition_deallocate(objc_condition_t condition)
+{
+ /* Unimplemented. */
+ return -1;
+}
+
+/* Wait on the condition */
+int
+__objc_condition_wait(objc_condition_t condition, objc_mutex_t mutex)
+{
+ /* Unimplemented. */
+ return -1;
+}
+
+/* Wake up all threads waiting on this condition. */
+int
+__objc_condition_broadcast(objc_condition_t condition)
+{
+ /* Unimplemented. */
+ return -1;
+}
+/* Wake up one thread waiting on this condition. */
int
-objc_mutex_unlock(objc_mutex_t mutex)
+__objc_condition_signal(objc_condition_t condition)
{
- objc_thread_t thread_id; /* Cache our thread id. */
-
- if (!mutex) /* Is argument bad? */
- return -1; /* Yes, abort. */
- thread_id = objc_thread_id(); /* Get this thread's id. */
- if (mutex->owner != thread_id) /* Does some else own lock? */
- return -1; /* Yes, abort. */
-
- DEBUG_PRINTF("unlock by: %d:%d\n", mutex->owner, mutex->depth - 1);
-
- if (mutex->depth > 1) /* Released last lock? */
- return --mutex->depth; /* No, Decrement depth, end.*/
- mutex->depth = 0; /* Yes, reset depth to 0. */
- mutex->owner = NULL; /* Set owner to "no thread".*/
-
- usunsetlock(mutex->lock); /* Free lock. */
-
- return 0; /* No, return success. */
+ /* Unimplemented. */
+ return -1;
}
/* End of File */
diff --git a/gcc/objc/thr-mach.c b/gcc/objc/thr-mach.c
index 1f43fc5..6f54ada 100644
--- a/gcc/objc/thr-mach.c
+++ b/gcc/objc/thr-mach.c
@@ -31,434 +31,282 @@ Boston, MA 02111-1307, USA. */
#include <objc/thr.h>
#include "runtime.h"
-/********
- * This structure represents a single mutual exclusion lock. Lock semantics
- * are detailed with the subsequent functions. We use whatever lock is
- * provided by the system. We augment it with depth and current owner id
- * fields to implement and re-entrant lock.
- */
-struct objc_mutex
+/*
+ Obtain the maximum thread priority that can set for t. Under the
+ mach threading model, it is possible for the developer to adjust the
+ maximum priority downward only-- cannot be raised without superuser
+ priviledges. Once lowered, it cannot be raised.
+ */
+static int __mach_get_max_thread_priority(cthread_t t, int *base)
{
- volatile objc_thread_t owner; /* Id of thread that owns. */
- volatile int depth; /* # of acquires. */
- struct mutex lock; /* cthread mutex */
-};
-
-struct objc_condition
-{
- struct condition condition; /* cthread condition */
-};
-
-/********
- * obtain the maximum thread priority that can set for t. Under the
- * mach threading model, it is possible for the developer to adjust the
- * maximum priority downward only-- cannot be raised without superuser
- * priviledges. Once lowered, it cannot be raised.
- */
-static int __mach_get_max_thread_priority(cthread_t t, int *base) {
- thread_t threadP;
- kern_return_t error;
- struct thread_sched_info info;
- unsigned int info_count=THREAD_SCHED_INFO_COUNT;
+ thread_t threadP;
+ kern_return_t error;
+ struct thread_sched_info info;
+ unsigned int info_count=THREAD_SCHED_INFO_COUNT;
- if (t == NULL)
- return -1;
+ if (t == NULL)
+ return -1;
- threadP = cthread_thread(t); /* get thread underlying */
+ threadP = cthread_thread(t); /* get thread underlying */
- error=thread_info(threadP, THREAD_SCHED_INFO,
- (thread_info_t)&info, &info_count);
+ error=thread_info(threadP, THREAD_SCHED_INFO,
+ (thread_info_t)&info, &info_count);
- if (error != KERN_SUCCESS)
- return -1;
+ if (error != KERN_SUCCESS)
+ return -1;
- if (base != NULL)
- *base = info.base_priority;
+ if (base != NULL)
+ *base = info.base_priority;
- return info.max_priority;
+ return info.max_priority;
}
-/********
- * Initialize the threads subsystem. Returns 0 if successful, or -1 if no
- * thread support is available.
- */
+/* Backend initialization functions */
+
+/* Initialize the threads subsystem. */
int
__objc_init_thread_system(void)
{
- DEBUG_PRINTF("__objc_init_thread_system\n");
- return 0; /* Succeeded. */
+ return 0;
}
-
+/* Close the threads subsystem. */
int
-__objc_fini_thread_system(void)
+__objc_close_thread_system(void)
{
return 0;
}
-/********
- * Create a new thread of execution and return its id. Return NULL if fails.
- * The new thread starts in "func" with the given argument.
- */
+/* Backend thread functions */
+
+/* Create a new thread of execution. */
objc_thread_t
-objc_thread_create(void (*func)(void *arg), void *arg)
+__objc_thread_detach(void (*func)(void *arg), void *arg)
{
- objc_thread_t thread_id = NULL; /* Detached thread id. */
- cthread_t new_thread_handle; /* cthread handle. */
+ objc_thread_t thread_id;
+ cthread_t new_thread_handle;
- objc_mutex_lock(__objc_runtime_mutex);
-
- /* create thread */
- new_thread_handle = cthread_fork((cthread_fn_t)func, arg);
+ /* create thread */
+ new_thread_handle = cthread_fork((cthread_fn_t)func, arg);
- if(new_thread_handle) {
+ if(new_thread_handle)
+ {
/* this is not terribly portable */
- thread_id = *(objc_thread_t *)&new_thread_handle;
- cthread_detach(new_thread_handle); /* fully detach thread */
- __objc_runtime_threads_alive++; /* increment thread count */
+ thread_id = *(objc_thread_t *)&new_thread_handle;
+ cthread_detach(new_thread_handle);
}
-
- objc_mutex_unlock(__objc_runtime_mutex);
- return thread_id;
+ else
+ thread_id = NULL;
+
+ return thread_id;
}
-/********
- * Set the current thread's priority.
- */
+/* Set the current thread's priority. */
int
-objc_thread_set_priority(int priority)
+__objc_thread_set_priority(int priority)
{
- objc_thread_t *t = objc_thread_id();
- cthread_t cT = (cthread_t) t;
- int maxPriority = __mach_get_max_thread_priority(cT, NULL);
- int sys_priority = 0;
+ objc_thread_t *t = objc_thread_id();
+ cthread_t cT = (cthread_t) t;
+ int maxPriority = __mach_get_max_thread_priority(cT, NULL);
+ int sys_priority = 0;
- if (maxPriority == -1)
- return -1;
+ if (maxPriority == -1)
+ return -1;
- switch (priority) {
+ switch (priority)
+ {
case OBJC_THREAD_INTERACTIVE_PRIORITY:
- sys_priority = maxPriority;
- break;
+ sys_priority = maxPriority;
+ break;
case OBJC_THREAD_BACKGROUND_PRIORITY:
- sys_priority = (maxPriority * 2) / 3;
- break;
+ sys_priority = (maxPriority * 2) / 3;
+ break;
case OBJC_THREAD_LOW_PRIORITY:
- sys_priority = maxPriority / 3;
- break;
+ sys_priority = maxPriority / 3;
+ break;
default:
- return -1;
+ return -1;
}
- if (sys_priority == 0)
- return -1;
-
- if (cthread_priority(cT, sys_priority, 0) == KERN_SUCCESS)
- return 0; /* Changed priority. End. */
-
- return -1; /* Failed. */
+ if (sys_priority == 0)
+ return -1;
+
+ /* Change the priority */
+ if (cthread_priority(cT, sys_priority, 0) == KERN_SUCCESS)
+ return 0;
+ else
+ return -1;
}
-/********
- * Return the current thread's priority [well, whatever it is closest to].
- */
+/* Return the current thread's priority. */
int
-objc_thread_get_priority(void)
+__objc_thread_get_priority(void)
{
- objc_thread_t *t = objc_thread_id();
- cthread_t cT = (cthread_t) t; /* see objc_thread_id() */
- int basePriority;
- int maxPriority;
- int sys_priority = 0;
-
- int interactiveT, backgroundT, lowT; /* threasholds */
-
- maxPriority = __mach_get_max_thread_priority(cT, &basePriority);
-
- if(maxPriority == -1)
- return -1;
-
- if (basePriority > ( (maxPriority * 2) / 3))
- return OBJC_THREAD_INTERACTIVE_PRIORITY; /* interactive priority
- */
- if (basePriority > ( maxPriority / 3))
- return OBJC_THREAD_BACKGROUND_PRIORITY; /* background priority
- */
- return OBJC_THREAD_LOW_PRIORITY; /* everything else is low */
+ objc_thread_t *t = objc_thread_id();
+ cthread_t cT = (cthread_t) t; /* see objc_thread_id() */
+ int basePriority;
+ int maxPriority;
+ int sys_priority = 0;
+
+ int interactiveT, backgroundT, lowT; /* threasholds */
+
+ maxPriority = __mach_get_max_thread_priority(cT, &basePriority);
+
+ if(maxPriority == -1)
+ return -1;
+
+ if (basePriority > ( (maxPriority * 2) / 3))
+ return OBJC_THREAD_INTERACTIVE_PRIORITY;
+
+ if (basePriority > ( maxPriority / 3))
+ return OBJC_THREAD_BACKGROUND_PRIORITY;
+
+ return OBJC_THREAD_LOW_PRIORITY;
}
-/********
- * Yield our process time to another thread. Any BUSY waiting that is done
- * by a thread should use this function to make sure that other threads can
- * make progress even on a lazy uniprocessor system.
- */
+/* Yield our process time to another thread. */
void
-objc_thread_yield(void)
+__objc_thread_yield(void)
{
- cthread_yield(); /* Yield to equal thread. */
+ cthread_yield();
}
-/********
- * Terminate the current tread. Doesn't return anything. Doesn't return.
- * Actually, if it failed returns -1.
- */
+/* Terminate the current thread. */
int
-objc_thread_exit(void)
+__objc_thread_exit(void)
{
- objc_mutex_lock(__objc_runtime_mutex);
- __objc_runtime_threads_alive--;
- objc_mutex_unlock(__objc_runtime_mutex);
-
- cthread_exit(&__objc_thread_exit_status); /* Terminate thread. */
+ /* exit the thread */
+ cthread_exit(&__objc_thread_exit_status);
+
+ /* Failed if we reached here */
return -1;
}
-/********
- * Returns an integer value which uniquely describes a thread. Must not be
- * NULL which is reserved as a marker for "no thread".
- */
+/* Returns an integer value which uniquely describes a thread. */
objc_thread_t
-objc_thread_id(void)
+__objc_thread_id(void)
{
cthread_t self = cthread_self();
- return (objc_thread_t)self;
-}
-/********
- * Sets the thread's local storage pointer. Returns 0 if successful or -1
- * if failed.
- */
+ return *(objc_thread_t *)&self;
+}
+/* Sets the thread's local storage pointer. */
int
-objc_thread_set_data(void *value)
+__objc_thread_set_data(void *value)
{
cthread_set_data(cthread_self(), (any_t) value);
return 0;
}
-/********
- * Returns the thread's local storage pointer. Returns NULL on failure.
- */
+/* Returns the thread's local storage pointer. */
void *
-objc_thread_get_data(void)
+__objc_thread_get_data(void)
{
return (void *) cthread_data(cthread_self());
}
-/********
- * Allocate a mutex. Return the mutex pointer if successful or NULL if the
- * allocation failed for any reason.
- */
-objc_mutex_t
-objc_mutex_allocate(void)
+/* Backend mutex functions */
+
+/* Allocate a mutex. */
+int
+__objc_mutex_allocate(objc_mutex_t mutex)
{
- objc_mutex_t mutex;
- int err = 0;
-
- if (!(mutex = (objc_mutex_t)objc_malloc(sizeof(struct objc_mutex))))
- return NULL; /* Abort if malloc failed. */
+ int err = 0;
+ mutex->backend = objc_malloc(sizeof(struct mutex));
- err = mutex_init(&(mutex->lock));
-
- if (err != 0) { /* System init failed? */
- objc_free(mutex); /* Yes, free local memory. */
- return NULL; /* Abort. */
+ err = mutex_init((mutex_t)(mutex->backend));
+
+ if (err != 0)
+ {
+ objc_free(mutex->backend);
+ return -1;
}
- mutex->owner = (objc_thread_t) -1; /* No owner. */
- mutex->depth = 0; /* No locks. */
- return mutex; /* Return mutex handle. */
+ else
+ return 0;
}
-/********
- * Deallocate a mutex. Note that this includes an implicit mutex_lock to
- * insure that no one else is using the lock. It is legal to deallocate
- * a lock if we have a lock on it, but illegal to deallocate a lock held
- * by anyone else.
- * Returns the number of locks on the thread. (1 for deallocate).
- */
+/* Deallocate a mutex. */
int
-objc_mutex_deallocate(objc_mutex_t mutex)
+__objc_mutex_deallocate(objc_mutex_t mutex)
{
- int depth; /* # of locks on mutex. */
+ mutex_clear((mutex_t)(mutex->backend));
- if (!mutex) /* Is argument bad? */
- return -1; /* Yes, abort. */
- depth = objc_mutex_lock(mutex); /* Must have lock. */
-
- mutex_unlock(&(mutex->lock)); /* Must unlock system mutex.*/
- mutex_clear(&(mutex->lock)); /* Free system mutex. */
-
- objc_free(mutex); /* Free memory. */
- return depth; /* Return last depth. */
+ objc_free(mutex->backend);
+ mutex->backend = NULL;
+ return 0;
}
-/********
- * Grab a lock on a mutex. If this thread already has a lock on this mutex
- * then we increment the lock count. If another thread has a lock on the
- * mutex we block and wait for the thread to release the lock.
- * Returns the lock count on the mutex held by this thread.
- */
+/* Grab a lock on a mutex. */
int
-objc_mutex_lock(objc_mutex_t mutex)
+__objc_mutex_lock(objc_mutex_t mutex)
{
- objc_thread_t thread_id; /* Cache our thread id. */
-
- if (!mutex) /* Is argument bad? */
- return -1; /* Yes, abort. */
- thread_id = objc_thread_id(); /* Get this thread's id. */
- if (mutex->owner == thread_id) /* Already own lock? */
- return ++mutex->depth; /* Yes, increment depth. */
-
- mutex_lock(&(mutex->lock)); /* Lock cthread mutex. */
-
- mutex->owner = thread_id; /* Mark thread as owner. */
- return mutex->depth = 1; /* Increment depth to end. */
+ mutex_lock((mutex_t)(mutex->backend));
+ return 0;
}
-/********
- * Try to grab a lock on a mutex. If this thread already has a lock on
- * this mutex then we increment the lock count and return it. If another
- * thread has a lock on the mutex returns -1.
- */
+/* Try to grab a lock on a mutex. */
int
-objc_mutex_trylock(objc_mutex_t mutex)
+__objc_mutex_trylock(objc_mutex_t mutex)
{
- objc_thread_t thread_id; /* Cache our thread id. */
-
- if (!mutex) /* Is argument bad? */
- return -1; /* Yes, abort. */
- thread_id = objc_thread_id(); /* Get this thread's id. */
- if (mutex->owner == thread_id) /* Already own lock? */
- return ++mutex->depth; /* Yes, increment depth. */
-
- if (mutex_try_lock(&(mutex->lock)) == 0) /* Lock cthread mutex. */
- return -1; /* Failed, abort. */
-
- mutex->owner = thread_id; /* Mark thread as owner. */
- return mutex->depth = 1; /* Increment depth to end. */
+ if (mutex_try_lock((mutex_t)(mutex->backend)) == 0)
+ return -1;
+ else
+ return 0;
}
-/********
- * Decrements the lock count on this mutex by one. If the lock count reaches
- * zero, release the lock on the mutex. Returns the lock count on the mutex.
- * It is an error to attempt to unlock a mutex which this thread doesn't hold
- * in which case return -1 and the mutex is unaffected.
- * Will also return -1 if the mutex free fails.
- */
+/* Unlock the mutex */
int
-objc_mutex_unlock(objc_mutex_t mutex)
+__objc_mutex_unlock(objc_mutex_t mutex)
{
- objc_thread_t thread_id; /* Cache our thread id. */
-
- if (!mutex) /* Is argument bad? */
- return -1; /* Yes, abort. */
- thread_id = objc_thread_id(); /* Get this thread's id. */
- if (mutex->owner != thread_id) /* Does some else own lock? */
- return -1; /* Yes, abort. */
- if (mutex->depth > 1) /* Released last lock? */
- return --mutex->depth; /* No, Decrement depth, end.*/
- mutex->depth = 0; /* Yes, reset depth to 0. */
- mutex->owner = (objc_thread_t) -1; /* Set owner to "no thread".*/
-
- mutex_unlock(&(mutex->lock)); /* unlock cthread mutex. */
-
- return 0; /* No, return success. */
+ mutex_unlock((mutex_t)(mutex->backend));
+ return 0;
}
-/********
- * Allocate a condition. Return the condition pointer if successful or NULL
- * if the allocation failed for any reason.
- */
-objc_condition_t
-objc_condition_allocate(void)
-{
- objc_condition_t condition;
-
- if (!(condition = (objc_condition_t)objc_malloc(
- sizeof(struct objc_condition))))
- return NULL; /* Abort if malloc failed. */
+/* Backend condition mutex functions */
- condition_init(&(condition->condition));
-
- return condition; /* Return mutex handle. */
+/* Allocate a condition. */
+int
+__objc_condition_allocate(objc_condition_t condition)
+{
+ condition->backend = objc_malloc(sizeof(struct condition));
+ condition_init((condition_t)(condition->backend));
+ return 0;
}
-/********
- * Deallocate a condition. Note that this includes an implicit
- * condition_broadcast to insure that waiting threads have the opportunity
- * to wake. It is legal to dealloc a condition only if no other
- * thread is/will be using it. Here we do NOT check for other threads
- * waiting but just wake them up.
- */
+/* Deallocate a condition. */
int
-objc_condition_deallocate(objc_condition_t condition)
+__objc_condition_deallocate(objc_condition_t condition)
{
- condition_broadcast(&(condition->condition));
- condition_clear(&(condition->condition));
- objc_free(condition);
- return 0;
+ condition_clear((condition_t)(condition->backend));
+ objc_free(condition->backend);
+ condition->backend = NULL;
+ return 0;
}
-/********
- * Wait on the condition unlocking the mutex until objc_condition_signal()
- * or objc_condition_broadcast() are called for the same condition. The
- * given mutex *must* have the depth set to 1 so that it can be unlocked
- * here, so that someone else can lock it and signal/broadcast the condition.
- * The mutex is used to lock access to the shared data that make up the
- * "condition" predicate.
- */
+/* Wait on the condition */
int
-objc_condition_wait(objc_condition_t condition, objc_mutex_t mutex)
+__objc_condition_wait(objc_condition_t condition, objc_mutex_t mutex)
{
- objc_thread_t thread_id; /* Cache our thread id. */
-
- if (!mutex || !condition) /* Is argument bad? */
- return -1; /* Yes, abort. */
-
- thread_id = objc_thread_id(); /* Get this thread's id. */
- if (mutex->owner != thread_id) /* Does some else own lock? */
- return -1; /* Yes, abort. */
- if (mutex->depth > 1) /* Locked more than once ? */
- return -1; /* YES, return error */
- /* mutex will be unlocked */
- mutex->depth = 0; /* Yes, reset depth to 0. */
- mutex->owner = (objc_thread_t) -1; /* Set owner to "no thread".*/
-
- condition_wait(&(condition->condition),
- &(mutex->lock)); /* unlock, wait ..., lock */
-
- mutex->owner = thread_id; /* Mark thread as owner. */
- mutex->depth = 1; /* Increment depth to end. */
- return 0; /* Return success. */
+ condition_wait((condition_t)(condition->backend),
+ (mutex_t)(mutex->backend));
+ return 0;
}
-/********
- * Wake up all threads waiting on this condition. It is recommended that
- * the called would lock the same mutex as the threads in objc_condition_wait
- * before changing the "condition predicate" and make this call and unlock it
- * right away after this call.
- */
+/* Wake up all threads waiting on this condition. */
int
-objc_condition_broadcast(objc_condition_t condition)
+__objc_condition_broadcast(objc_condition_t condition)
{
- if (!condition)
- return -1;
- condition_broadcast(&(condition->condition));
- return 0;
+ condition_broadcast((condition_t)(condition->backend));
+ return 0;
}
-/********
- * Wake up one thread waiting on this condition. It is recommended that
- * the called would lock the same mutex as the threads in objc_condition_wait
- * before changing the "condition predicate" and make this call and unlock it
- * right away after this call.
- */
+/* Wake up one thread waiting on this condition. */
int
-objc_condition_signal(objc_condition_t condition)
+__objc_condition_signal(objc_condition_t condition)
{
- if (!condition)
- return -1;
- condition_signal(&(condition->condition));
- return 0;
+ condition_signal((condition_t)(condition->backend));
+ return 0;
}
+/* End of File */
diff --git a/gcc/objc/thr-os2.c b/gcc/objc/thr-os2.c
index 422d53e..d546060 100644
--- a/gcc/objc/thr-os2.c
+++ b/gcc/objc/thr-os2.c
@@ -44,71 +44,39 @@ Boston, MA 02111-1307, USA. */
#include <stdlib.h>
-/********
- * This structure represents a single mutual exclusion lock. Lock semantics
- * are detailed with the subsequent functions. We use whatever lock is
- * provided by the system. We augment it with depth and current owner id
- * fields to implement and re-entrant lock.
- */
-struct objc_mutex
-{
- volatile objc_thread_t owner; /* Id of thread that owns. */
- volatile int depth; /* # of acquires. */
- HMTX handle; /* OS/2 mutex HANDLE. */
-};
+/* Backend initialization functions */
-/*****************************************************************************
- * Static variables.
- */
-/* none needed for OS/2 */
-
-/********
- * Initialize the threads subsystem. Returns 0 if successful, or -1 if no
- * thread support is available.
- */
+/* Initialize the threads subsystem. */
int
__objc_init_thread_system(void)
{
- DEBUG_PRINTF("__objc_init_thread_system (os2-emx)\n");
-
- /* no initialization of thread subsystem */
- return 0; /* Yes, return success. */
+ return 0;
}
+/* Close the threads subsystem. */
int
-__objc_fini_thread_system(void)
+__objc_close_thread_system(void)
{
- /* no termination code for thread subsystem */
return 0;
}
-/********
- * Create a new thread of execution and return its id. Return NULL if fails.
- * The new thread starts in "func" with the given argument.
- */
+/* Backend thread functions */
+
+/* Create a new thread of execution. */
objc_thread_t
-objc_thread_create(void (*func)(void *arg), void *arg)
+__objc_thread_detach(void (*func)(void *arg), void *arg)
{
- int thread_id = 0; /* id of the newly created thread */
+ int thread_id = 0;
- objc_mutex_lock(__objc_runtime_mutex);
-
- /* create a thread calling "func", args "arg", stack size 32768 bytes */
if ((thread_id = _beginthread (func,NULL,32768,arg)) < 0)
thread_id = 0;
- else
- __objc_runtime_threads_alive++;
-
- objc_mutex_unlock(__objc_runtime_mutex);
return (objc_thread_t)thread_id;
}
-/********
- * Set the current thread's priority.
- */
+/* Set the current thread's priority. */
int
-objc_thread_set_priority(int priority)
+__objc_thread_set_priority(int priority)
{
ULONG sys_class = 0;
ULONG sys_priority = 0;
@@ -132,210 +100,168 @@ objc_thread_set_priority(int priority)
sys_priority = 0;
break;
}
+
+ /* Change priority */
if (!DosSetPriority (PRTYS_THREAD,sys_class,sys_priority,*_threadid))
- return 0; /* Changed priority. End. */
-
- return -1; /* Failed. */
+ return 0;
+ else
+ return -1;
}
-/********
- * Return the current thread's priority.
- */
+/* Return the current thread's priority. */
int
-objc_thread_get_priority(void)
+__objc_thread_get_priority(void)
{
PTIB ptib;
PPIB ppib;
- DosGetInfoBlocks (&ptib,&ppib); /* get information about current thread */
+ /* get information about current thread */
+ DosGetInfoBlocks (&ptib,&ppib);
+
+ switch (ptib->tib_ptib2->tib2_ulpri)
+ {
+ case PRTYC_IDLETIME:
+ case PRTYC_REGULAR:
+ case PRTYC_TIMECRITICAL:
+ case PRTYC_FOREGROUNDSERVER:
+ default:
+ return OBJC_THREAD_INTERACTIVE_PRIORITY;
+ }
- switch (ptib->tib_ptib2->tib2_ulpri) {
- case PRTYC_IDLETIME:
- case PRTYC_REGULAR:
- case PRTYC_TIMECRITICAL:
- case PRTYC_FOREGROUNDSERVER:
- default:
- return OBJC_THREAD_INTERACTIVE_PRIORITY;
- }
- return -1; /* Couldn't get priority. */
+ return -1;
}
-/********
- * Yield our process time to another thread. Any BUSY waiting that is done
- * by a thread should use this function to make sure that other threads can
- * make progress even on a lazy uniprocessor system.
- */
+/* Yield our process time to another thread. */
void
-objc_thread_yield(void)
+__objc_thread_yield(void)
{
- DosSleep (0); /* Yield to equal thread. */
+ DosSleep (0);
}
-/********
- * Terminate the current tread. Doesn't return anything. Doesn't return.
- * Actually, if it failed returns -1.
- */
+/* Terminate the current thread. */
int
-objc_thread_exit(void)
+__objc_thread_exit(void)
{
- objc_mutex_lock(__objc_runtime_mutex);
- __objc_runtime_threads_alive--;
- objc_mutex_unlock(__objc_runtime_mutex);
-
- _endthread (); /* terminate the thread, NEVER use DosExit () */
+ /* terminate the thread, NEVER use DosExit () */
+ _endthread ();
+ /* Failed if we reached here */
return -1;
}
-/********
- * Returns an integer value which uniquely describes a thread. Must not be
- * -1 which is reserved as a marker for "no thread".
- */
+/* Returns an integer value which uniquely describes a thread. */
objc_thread_t
-objc_thread_id(void)
+__objc_thread_id(void)
{
- return (objc_thread_t) *_threadid; /* Return thread id. */
+ return (objc_thread_t) *_threadid;
}
-/********
- * Sets the thread's local storage pointer. Returns 0 if successful or -1
- * if failed.
- */
+/* Sets the thread's local storage pointer. */
int
-objc_thread_set_data(void *value)
+__objc_thread_set_data(void *value)
{
*_threadstore () = value;
return 0;
}
-/********
- * Returns the thread's local storage pointer. Returns NULL on failure.
- */
+/* Returns the thread's local storage pointer. */
void *
-objc_thread_get_data(void)
+__objc_thread_get_data(void)
{
return *_threadstore ();
}
-/********
- * Allocate a mutex. Return the mutex pointer if successful or NULL if
- * the allocation fails for any reason.
- */
-objc_mutex_t
-objc_mutex_allocate(void)
-{
- objc_mutex_t mutex;
- int err = 0;
-
- if (!(mutex = (objc_mutex_t)objc_malloc(sizeof(struct objc_mutex))))
- return NULL; /* Abort if malloc failed. */
-
- if (DosCreateMutexSem (NULL,&(mutex->handle),0L,0) > 0) {
- objc_free(mutex);
- return NULL;
- }
+/* Backend mutex functions */
- mutex->owner = NULL; /* No owner. */
- mutex->depth = 0; /* No locks. */
- return mutex; /* Return mutex handle. */
+/* Allocate a mutex. */
+int
+__objc_mutex_allocate(objc_mutex_t mutex)
+{
+ if (DosCreateMutexSem (NULL, (HMTX)(&(mutex->backend)),0L,0) > 0)
+ return -1;
+ else
+ return 0;
}
-/********
- * Deallocate a mutex. Note that this includes an implicit mutex_lock to
- * insure that no one else is using the lock. It is legal to deallocate
- * a lock if we have a lock on it, but illegal to deallotcate a lock held
- * by anyone else.
- * Returns the number of locks on the thread. (1 for deallocate).
- */
+/* Deallocate a mutex. */
int
-objc_mutex_deallocate(objc_mutex_t mutex)
+__objc_mutex_deallocate(objc_mutex_t mutex)
{
- int depth; /* # of locks on mutex. */
-
- if (!mutex) /* Is argument bad? */
- return -1; /* Yes, abort. */
- depth = objc_mutex_lock(mutex); /* Must have lock. */
-
- DosCloseMutexSem (mutex->handle);
-
- objc_free(mutex); /* Free memory. */
- return depth; /* Return last depth. */
+ DosCloseMutexSem ((HMTX)(mutex->backend));
+ return 0;
}
-/********
- * Grab a lock on a mutex. If this thread already has a lock on this mutex
- * then we increment the lock count. If another thread has a lock on the
- * mutex we block and wait for the thread to release the lock.
- * Returns the lock count on the mutex held by this thread.
- */
+/* Grab a lock on a mutex. */
int
-objc_mutex_lock(objc_mutex_t mutex)
+__objc_mutex_lock(objc_mutex_t mutex)
{
- objc_thread_t thread_id; /* Cache our thread id. */
-
- if (!mutex) /* Is argument bad? */
- return -1; /* Yes, abort. */
+ if (DosRequestMutexSem ((HMTX)(mutex->backend),-1L) != 0)
+ return -1;
+ else
+ return 0;
+}
- thread_id = objc_thread_id(); /* Get this thread's id. */
- if (mutex->owner == thread_id) /* Already own lock? */
- return ++mutex->depth; /* Yes, increment depth. */
+/* Try to grab a lock on a mutex. */
+int
+__objc_mutex_trylock(objc_mutex_t mutex)
+{
+ if (DosRequestMutexSem ((HMTX)(mutex->backend),0L) != 0)
+ return -1;
+ else
+ return 0;
+}
- if (DosRequestMutexSem (mutex->handle,-1L) != 0)
- return -1;
+/* Unlock the mutex */
+int
+__objc_mutex_unlock(objc_mutex_t mutex)
+{
+ if (DosReleaseMutexSem((HMTX)(mutex->backend)) != 0)
+ return -1;
+ else
+ return 0;
+}
- mutex->owner = thread_id; /* Mark thread as owner. */
+/* Backend condition mutex functions */
- return ++mutex->depth; /* Increment depth to end. */
+/* Allocate a condition. */
+int
+__objc_condition_allocate(objc_condition_t condition)
+{
+ /* Unimplemented. */
+ return -1;
}
-/********
- * Try to grab a lock on a mutex. If this thread already has a lock on
- * this mutex then we increment the lock count and return it. If another
- * thread has a lock on the mutex returns -1.
- */
+/* Deallocate a condition. */
int
-objc_mutex_trylock(objc_mutex_t mutex)
+__objc_condition_deallocate(objc_condition_t condition)
{
- objc_thread_t thread_id; /* Cache our thread id. */
-
- if (!mutex) /* Is argument bad? */
- return -1; /* Yes, abort. */
- thread_id = objc_thread_id(); /* Get this thread's id. */
- if (mutex->owner == thread_id) /* Already own lock? */
- return ++mutex->depth; /* Yes, increment depth. */
+ /* Unimplemented. */
+ return -1;
+}
- if (DosRequestMutexSem (mutex->handle,0L) != 0)
- return -1;
+/* Wait on the condition */
+int
+__objc_condition_wait(objc_condition_t condition, objc_mutex_t mutex)
+{
+ /* Unimplemented. */
+ return -1;
+}
- mutex->owner = thread_id; /* Mark thread as owner. */
- return ++mutex->depth; /* Increment depth to end. */
+/* Wake up all threads waiting on this condition. */
+int
+__objc_condition_broadcast(objc_condition_t condition)
+{
+ /* Unimplemented. */
+ return -1;
}
-/********
- * Decrements the lock count on this mutex by one. If the lock count reaches
- * zero, release the lock on the mutex. Returns the lock count on the mutex.
- * It is an error to attempt to unlock a mutex which this thread doesn't hold
- * in which case return -1 and the mutex is unaffected.
- * Will also return -1 if the mutex free fails.
- */
+/* Wake up one thread waiting on this condition. */
int
-objc_mutex_unlock(objc_mutex_t mutex)
+__objc_condition_signal(objc_condition_t condition)
{
- objc_thread_t thread_id; /* Cache our thread id. */
-
- if (!mutex) /* Is argument bad? */
- return -1; /* Yes, abort. */
- thread_id = objc_thread_id(); /* Get this thread's id. */
- if (mutex->owner != thread_id) /* Does some else own lock? */
- return -1; /* Yes, abort. */
- if (mutex->depth > 1) /* Released last lock? */
- return --mutex->depth; /* No, Decrement depth, end.*/
- mutex->depth = 0; /* Yes, reset depth to 0. */
- mutex->owner = NULL; /* Set owner to "no thread".*/
-
- if (DosReleaseMutexSem(mutex->handle) != 0)
- return -1; /* Failed, abort. */
-
- return 0; /* No, return success. */
+ /* Unimplemented. */
+ return -1;
}
+
+/* End of File */
diff --git a/gcc/objc/thr-posix.c b/gcc/objc/thr-posix.c
index 987f8a8..1b9a9e5 100644
--- a/gcc/objc/thr-posix.c
+++ b/gcc/objc/thr-posix.c
@@ -29,294 +29,182 @@ Boston, MA 02111-1307, USA. */
#include "runtime.h"
#include <pthread.h>
-/********
- * This structure represents a single mutual exclusion lock. Lock semantics
- * are detailed with the subsequent functions. We use whatever lock is
- * provided by the system. We augment it with depth and current owner id
- * fields to implement and re-entrant lock.
- */
-struct objc_mutex
-{
- volatile objc_thread_t owner; /* Id of thread that owns. */
- volatile int depth; /* # of acquires. */
- pthread_mutex_t lock; /* pthread mutex. */
-};
-
-/*****************************************************************************
- * Static variables.
- */
-static pthread_key_t __objc_thread_data_key; /* Data key for thread data.*/
+/* Key structure for maintiain thread specific storage */
+static pthread_key_t _objc_thread_storage;
+/* Backend initialization functions */
-/********
- * Initialize the threads subsystem. Returns 0 if successful, or -1 if no
- * thread support is available.
- */
+/* Initialize the threads subsystem. */
int
__objc_init_thread_system(void)
{
- if (pthread_key_create(&__objc_thread_data_key, NULL) == 0)
- return 0; /* Yes, return success. */
-
- return -1; /* Failed. */
+ /* Initialize the thread storage key */
+ return pthread_key_create(&_objc_thread_storage, NULL);
}
+/* Close the threads subsystem. */
int
-__objc_fini_thread_system(void)
+__objc_close_thread_system(void)
{
return 0;
}
-/********
- * Create a new thread of execution and return its id. Return NULL if fails.
- * The new thread starts in "func" with the given argument.
- */
+/* Backend thread functions */
+
+/* Create a new thread of execution. */
objc_thread_t
-objc_thread_create(void (*func)(void *arg), void *arg)
+__objc_thread_detach(void (*func)(void *arg), void *arg)
{
- objc_thread_t thread_id = NULL; /* Detached thread id. */
- pthread_t new_thread_handle; /* DCE thread handle. */
-
- objc_mutex_lock(__objc_runtime_mutex);
-
- if (pthread_create(&new_thread_handle, NULL,
- (void *)func, arg) == 0) {
- thread_id = (objc_thread_t) new_thread_handle;
- pthread_detach(new_thread_handle); /* Fully detach thread. */
- __objc_runtime_threads_alive++;
- }
-
- objc_mutex_unlock(__objc_runtime_mutex);
- return thread_id;
+ objc_thread_t thread_id;
+ pthread_t new_thread_handle;
+
+ 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.
- */
+/* Set the current thread's priority. */
int
-objc_thread_set_priority(int priority)
+__objc_thread_set_priority(int priority)
{
-#if 0 /* no get/set priority in Linux pthreads */
-
- int sys_priority = 0;
-
- 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;
- }
-
- if (pthread_setprio(pthread_self(), sys_priority) >= 0)
- return 0; /* Changed priority. End. */
-
-#endif
- return -1; /* Failed. */
+ /* Not implemented yet */
+ return -1;
}
-/********
- * Return the current thread's priority.
- */
+/* Return the current thread's priority. */
int
-objc_thread_get_priority(void)
+__objc_thread_get_priority(void)
{
-#if 0 /* no get/set priority in Linux pthreads */
- int sys_priority; /* DCE thread priority. */
-
- 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;
- }
-#endif
- return -1; /* Couldn't get priority. */
+ /* Not implemented yet */
+ return -1;
}
-/********
- * Yield our process time to another thread. Any BUSY waiting that is done
- * by a thread should use this function to make sure that other threads can
- * make progress even on a lazy uniprocessor system.
- */
+/* Yield our process time to another thread. */
void
-objc_thread_yield(void)
+__objc_thread_yield(void)
{
- pthread_yield(); /* Yield to equal thread. */
+ pthread_yield();
}
-/********
- * Terminate the current tread. Doesn't return anything. Doesn't return.
- * Actually, if it failed returns -1.
- */
+/* Terminate the current thread. */
int
-objc_thread_exit(void)
+__objc_thread_exit(void)
{
- objc_mutex_lock(__objc_runtime_mutex);
- __objc_runtime_threads_alive--;
- objc_mutex_unlock(__objc_runtime_mutex);
-
- pthread_exit(&__objc_thread_exit_status); /* Terminate thread. */
+ /* 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. Must not be
- * -1 which is reserved as a marker for "no thread".
- */
+/* Returns an integer value which uniquely describes a thread. */
objc_thread_t
-objc_thread_id(void)
+__objc_thread_id(void)
{
pthread_t self = pthread_self();
- return (objc_thread_t) self; /* Return thread handle. */
+ return *(objc_thread_t *)&self;
}
-/********
- * Sets the thread's local storage pointer. Returns 0 if successful or -1
- * if failed.
- */
+/* Sets the thread's local storage pointer. */
int
-objc_thread_set_data(void *value)
+__objc_thread_set_data(void *value)
{
- if (pthread_setspecific(__objc_thread_data_key, (void *)value) == 0)
- return 0; /* Return thread data. */
- return -1;
+ return pthread_setspecific(_objc_thread_storage, value);
}
-/********
- * Returns the thread's local storage pointer. Returns NULL on failure.
- */
+/* Returns the thread's local storage pointer. */
void *
-objc_thread_get_data(void)
+__objc_thread_get_data(void)
+{
+ return pthread_getspecific(_objc_thread_storage);
+}
+
+/* Backend mutex functions */
+
+/* Allocate a mutex. */
+int
+__objc_mutex_allocate(objc_mutex_t mutex)
{
- return pthread_getspecific(__objc_thread_data_key);
+ if (pthread_mutex_init((pthread_mutex_t *)(&(mutex->backend)), NULL))
+ return -1;
+ else
+ return 0;
}
-/********
- * Allocate a mutex. Return the mutex pointer if successful or NULL if
- * the allocation fails for any reason.
- */
-objc_mutex_t
-objc_mutex_allocate(void)
+/* Deallocate a mutex. */
+int
+__objc_mutex_deallocate(objc_mutex_t mutex)
{
- objc_mutex_t mutex;
- int err = 0;
-
- if (!(mutex = (objc_mutex_t)objc_malloc(sizeof(struct objc_mutex))))
- return NULL; /* Abort if malloc failed. */
-
- err = pthread_mutex_init(&mutex->lock, NULL);
-
- if (err != 0) { /* System init failed? */
- objc_free(mutex); /* Yes, free local memory. */
- return NULL; /* Abort. */
- }
- mutex->owner = NULL; /* No owner. */
- mutex->depth = 0; /* No locks. */
- return mutex; /* Return mutex handle. */
+ if (pthread_mutex_destroy((pthread_mutex_t *)(&(mutex->backend))))
+ return -1;
+ else
+ return 0;
}
-/********
- * Deallocate a mutex. Note that this includes an implicit mutex_lock to
- * insure that no one else is using the lock. It is legal to deallocate
- * a lock if we have a lock on it, but illegal to deallotcate a lock held
- * by anyone else.
- * Returns the number of locks on the thread. (1 for deallocate).
- */
+/* Grab a lock on a mutex. */
int
-objc_mutex_deallocate(objc_mutex_t mutex)
+__objc_mutex_lock(objc_mutex_t mutex)
{
- int depth; /* # of locks on mutex. */
-
- if (!mutex) /* Is argument bad? */
- return -1; /* Yes, abort. */
- depth = objc_mutex_lock(mutex); /* Must have lock. */
-
- pthread_mutex_unlock(&mutex->lock); /* Must unlock system mutex.*/
- pthread_mutex_destroy(&mutex->lock); /* Free system mutex. */
-
- objc_free(mutex); /* Free memory. */
- return depth; /* Return last depth. */
+ return pthread_mutex_lock((pthread_mutex_t *)(&(mutex->backend)));
}
-/********
- * Grab a lock on a mutex. If this thread already has a lock on this mutex
- * then we increment the lock count. If another thread has a lock on the
- * mutex we block and wait for the thread to release the lock.
- * Returns the lock count on the mutex held by this thread.
- */
+/* Try to grab a lock on a mutex. */
int
-objc_mutex_lock(objc_mutex_t mutex)
+__objc_mutex_trylock(objc_mutex_t mutex)
{
- objc_thread_t thread_id; /* Cache our thread id. */
-
- if (!mutex) /* Is argument bad? */
- return -1; /* Yes, abort. */
- thread_id = objc_thread_id(); /* Get this thread's id. */
- if (mutex->owner == thread_id) /* Already own lock? */
- return ++mutex->depth; /* Yes, increment depth. */
-
- if (pthread_mutex_lock(&mutex->lock) != 0) /* Lock DCE system mutex. */
- return -1; /* Failed, abort. */
-
- mutex->owner = thread_id; /* Mark thread as owner. */
- return mutex->depth = 1; /* Increment depth to end. */
+ return pthread_mutex_trylock((pthread_mutex_t *)(&(mutex->backend)));
}
-/********
- * Try to grab a lock on a mutex. If this thread already has a lock on
- * this mutex then we increment the lock count and return it. If another
- * thread has a lock on the mutex returns -1.
- */
+/* Unlock the mutex */
int
-objc_mutex_trylock(objc_mutex_t mutex)
+__objc_mutex_unlock(objc_mutex_t mutex)
{
- objc_thread_t thread_id; /* Cache our thread id. */
-
- if (!mutex) /* Is argument bad? */
- return -1; /* Yes, abort. */
- thread_id = objc_thread_id(); /* Get this thread's id. */
- if (mutex->owner == thread_id) /* Already own lock? */
- return ++mutex->depth; /* Yes, increment depth. */
-
- if (pthread_mutex_trylock(&mutex->lock) != 1) /* Lock DCE system mutex. */
- return -1; /* Failed, abort. */
-
- mutex->owner = thread_id; /* Mark thread as owner. */
- return mutex->depth = 1; /* Increment depth to end. */
+ return pthread_mutex_unlock((pthread_mutex_t *)(&(mutex->backend)));
}
-/********
- * Decrements the lock count on this mutex by one. If the lock count reaches
- * zero, release the lock on the mutex. Returns the lock count on the mutex.
- * It is an error to attempt to unlock a mutex which this thread doesn't hold
- * in which case return -1 and the mutex is unaffected.
- * Will also return -1 if the mutex free fails.
- */
+/* Backend condition mutex functions */
+
+/* Allocate a condition. */
int
-objc_mutex_unlock(objc_mutex_t mutex)
+__objc_condition_allocate(objc_condition_t condition)
{
- objc_thread_t thread_id; /* Cache our thread id. */
-
- if (!mutex) /* Is argument bad? */
- return -1; /* Yes, abort. */
- thread_id = objc_thread_id(); /* Get this thread's id. */
- if (mutex->owner != thread_id) /* Does some else own lock? */
- return -1; /* Yes, abort. */
- if (mutex->depth > 1) /* Released last lock? */
- return --mutex->depth; /* No, Decrement depth, end.*/
- mutex->depth = 0; /* Yes, reset depth to 0. */
- mutex->owner = NULL; /* Set owner to "no thread".*/
-
- if (pthread_mutex_unlock(&mutex->lock) != 0) /* Unlock system mutex. */
- return -1; /* Failed, abort. */
-
- return 0; /* No, return success. */
+ if (pthread_cond_init((pthread_cond_t *)(&(condition->backend)), NULL))
+ return -1;
+ else
+ return 0;
}
+
+/* Deallocate a condition. */
+int
+__objc_condition_deallocate(objc_condition_t condition)
+{
+ return pthread_cond_destroy((pthread_cond_t *)(&(condition->backend)));
+}
+
+/* Wait on the condition */
+int
+__objc_condition_wait(objc_condition_t condition, objc_mutex_t mutex)
+{
+ return pthread_cond_wait((pthread_cond_t *)(&(condition->backend)),
+ (pthread_mutex_t *)(&(mutex->backend)));
+}
+
+/* Wake up all threads waiting on this condition. */
+int
+__objc_condition_broadcast(objc_condition_t condition)
+{
+ return pthread_cond_broadcast((pthread_cond_t *)(&(condition->backend)));
+}
+
+/* Wake up one thread waiting on this condition. */
+int
+__objc_condition_signal(objc_condition_t condition)
+{
+ return pthread_cond_signal((pthread_cond_t *)(&(condition->backend)));
+}
+
+/* End of File */
diff --git a/gcc/objc/thr-pthreads.c b/gcc/objc/thr-pthreads.c
index 3e73fe0..4c4c245 100644
--- a/gcc/objc/thr-pthreads.c
+++ b/gcc/objc/thr-pthreads.c
@@ -1,6 +1,7 @@
/* GNU Objective C Runtime Thread Implementation for PCThreads under Linux.
Copyright (C) 1996, 1997 Free Software Foundation, Inc.
Contributed by Scott Christley <scottc@net-community.com>
+ Condition functions added by: Mircea Oancea <mircea@first.elcom.pub.ro>
This file is part of GNU CC.
@@ -24,35 +25,16 @@ Boston, MA 02111-1307, USA. */
however invalidate any other reasons why the executable file might be
covered by the GNU General Public License. */
-#include <pthread.h>
+#include <pcthread.h>
#include <objc/thr.h>
#include "runtime.h"
/* Key structure for maintiain thread specific storage */
static pthread_key_t _objc_thread_storage;
-/********
- * This structure represents a single mutual exclusion lock. Lock semantics
- * are detailed with the subsequent functions. We use whatever lock is
- * provided by the system. We augment it with depth and current owner id
- * fields to implement and re-entrant lock.
- */
-struct objc_mutex
-{
- volatile objc_thread_t owner; /* Id of thread that owns. */
- volatile int depth; /* # of acquires. */
- pthread_mutex_t mutex; /* PCThread mutex */
-};
-
-struct objc_condition
-{
- pthread_cond_t condition; /* cthread condition */
-};
+/* Backend initialization functions */
-/********
- * Initialize the threads subsystem. Returns 0 if successful, or -1 if no
- * thread support is available.
- */
+/* Initialize the threads subsystem. */
int
__objc_init_thread_system(void)
{
@@ -60,11 +42,9 @@ __objc_init_thread_system(void)
return pthread_key_create(&_objc_thread_storage, NULL);
}
-/********
- * Finalize the threads subsystem. Returns 0 if successful, or -1 if not
- */
+/* Close the threads subsystem. */
int
-__objc_fini_thread_system(void)
+__objc_close_thread_system(void)
{
/* Destroy the thread storage key */
/* Not implemented yet */
@@ -72,104 +52,76 @@ __objc_fini_thread_system(void)
return 0;
}
-/********
- * Create a new thread of execution and return its id. Return NULL if fails.
- * The new thread starts in "func" with the given argument.
- */
+/* Backend thread functions */
+
+/* Create a new thread of execution. */
objc_thread_t
-objc_thread_create(void (*func)(void *arg), void *arg)
+__objc_thread_detach(void (*func)(void *arg), void *arg)
{
objc_thread_t thread_id;
pthread_t new_thread_handle;
- objc_mutex_lock(__objc_runtime_mutex);
-
if ( !(pthread_create(&new_thread_handle, NULL, (void *)func, arg)) )
- {
thread_id = *(objc_thread_t *)&new_thread_handle;
- __objc_runtime_threads_alive++;
- }
else
thread_id = NULL;
- objc_mutex_unlock(__objc_runtime_mutex);
-
return thread_id;
}
-/********
- * Set the current thread's priority.
- */
+/* Set the current thread's priority. */
int
-objc_thread_set_priority(int priority)
+__objc_thread_set_priority(int priority)
{
/* Not implemented yet */
- return -1; /* Failed. */
+ return -1;
}
-/********
- * Return the current thread's priority.
- */
+/* Return the current thread's priority. */
int
-objc_thread_get_priority(void)
+__objc_thread_get_priority(void)
{
/* Not implemented yet */
- return OBJC_THREAD_INTERACTIVE_PRIORITY; /* Highest priority. */
+ return OBJC_THREAD_INTERACTIVE_PRIORITY;
}
-/********
- * Yield our process time to another thread. Any BUSY waiting that is done
- * by a thread should use this function to make sure that other threads can
- * make progress even on a lazy uniprocessor system.
- */
+/* Yield our process time to another thread. */
void
-objc_thread_yield(void)
+__objc_thread_yield(void)
{
pthread_yield(NULL);
}
-/********
- * Terminate the current tread. Doesn't return anything. Doesn't return.
- * Actually, if it failed returns -1.
- */
+/* Terminate the current thread. */
int
-objc_thread_exit(void)
+__objc_thread_exit(void)
{
- objc_mutex_lock(__objc_runtime_mutex);
- __objc_runtime_threads_alive--;
- objc_mutex_unlock(__objc_runtime_mutex);
-
- pthread_exit(&__objc_thread_exit_status); /* Terminate thread. */
+ /* 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. Must not be
- * NULL which is reserved as a marker for "no thread".
- */
+/* Returns an integer value which uniquely describes a thread. */
objc_thread_t
-objc_thread_id(void)
+__objc_thread_id(void)
{
pthread_t self = pthread_self();
- return *(objc_thread_t *)&self; /* Return thread handle. */
+ return *(objc_thread_t *)&self;
}
-/********
- * Sets the thread's local storage pointer. Returns 0 if successful or -1
- * if failed.
- */
+/* Sets the thread's local storage pointer. */
int
-objc_thread_set_data(void *value)
+__objc_thread_set_data(void *value)
{
return pthread_setspecific(_objc_thread_storage, value);
}
-/********
- * Returns the thread's local storage pointer. Returns NULL on failure.
- */
+/* Returns the thread's local storage pointer. */
void *
-objc_thread_get_data(void)
+__objc_thread_get_data(void)
{
void *value = NULL;
@@ -179,240 +131,88 @@ objc_thread_get_data(void)
return NULL;
}
-/********
- * Allocate a mutex. Return the mutex pointer if successful or NULL if the
- * allocation failed for any reason.
- */
-objc_mutex_t
-objc_mutex_allocate(void)
+/* Backend mutex functions */
+
+/* Allocate a mutex. */
+int
+__objc_mutex_allocate(objc_mutex_t mutex)
{
- objc_mutex_t mutex;
-
- if (!(mutex = (objc_mutex_t)objc_malloc(sizeof(struct objc_mutex))))
- return NULL; /* Abort if malloc failed. */
-
- /* Create PCThread mutex */
- if ( pthread_mutex_init(&(mutex->mutex), NULL) )
- {
- /* Failed */
- objc_free(mutex);
- return NULL;
- }
-
- mutex->owner = NULL; /* No owner. */
- mutex->depth = 0; /* No locks. */
- return mutex; /* Return mutex handle. */
+ if (pthread_mutex_init((pthread_mutex_t *)(&(mutex->backend)), NULL))
+ return -1;
+ else
+ return 0;
}
-/********
- * Deallocate a mutex. Note that this includes an implicit mutex_lock to
- * insure that no one else is using the lock. It is legal to deallocate
- * a lock if we have a lock on it, but illegal to deallocate a lock held
- * by anyone else.
- * Returns the number of locks on the thread. (1 for deallocate).
- */
+/* Deallocate a mutex. */
int
-objc_mutex_deallocate(objc_mutex_t mutex)
+__objc_mutex_deallocate(objc_mutex_t mutex)
{
- int depth; /* # of locks on mutex. */
-
- if (!mutex) /* Is argument bad? */
- return -1; /* Yes, abort. */
- depth = objc_mutex_lock(mutex); /* Must have lock. */
-
- /* Destroy PCThread mutex */
- pthread_mutex_destroy(&(mutex->mutex));
-
- objc_free(mutex); /* Free memory. */
- return depth; /* Return last depth. */
+ if (pthread_mutex_destroy((pthread_mutex_t *)(&(mutex->backend))))
+ return -1;
+ else
+ return 0;
}
-/********
- * Grab a lock on a mutex. If this thread already has a lock on this mutex
- * then we increment the lock count. If another thread has a lock on the
- * mutex we block and wait for the thread to release the lock.
- * Returns the lock count on the mutex held by this thread.
- */
+/* Grab a lock on a mutex. */
int
-objc_mutex_lock(objc_mutex_t mutex)
+__objc_mutex_lock(objc_mutex_t mutex)
{
- objc_thread_t thread_id; /* Cache our thread id. */
- int status;
-
- if (!mutex) /* Is argument bad? */
- return -1; /* Yes, abort. */
- thread_id = objc_thread_id(); /* Get this thread's id. */
- if (mutex->owner == thread_id) /* Already own lock? */
- {
- return ++mutex->depth; /* Yes, increment depth. */
- }
-
- /* Lock the PCThread mutex */
- status = pthread_mutex_lock(&(mutex->mutex));
- if (status)
- {
- return status; /* Failed */
- }
-
- mutex->owner = thread_id; /* Mark thread as owner. */
- return mutex->depth = 1; /* Increment depth to end. */
+ return pthread_mutex_lock((pthread_mutex_t *)(&(mutex->backend)));
}
-/********
- * Try to grab a lock on a mutex. If this thread already has a lock on
- * this mutex then we increment the lock count and return it. If another
- * thread has a lock on the mutex returns -1.
- */
+/* Try to grab a lock on a mutex. */
int
-objc_mutex_trylock(objc_mutex_t mutex)
+__objc_mutex_trylock(objc_mutex_t mutex)
{
- objc_thread_t thread_id; /* Cache our thread id. */
- int status;
-
- if (!mutex) /* Is argument bad? */
- return -1; /* Yes, abort. */
- thread_id = objc_thread_id(); /* Get this thread's id. */
- if (mutex->owner == thread_id) /* Already own lock? */
- return ++mutex->depth; /* Yes, increment depth. */
-
- /* Lock the PCThread mutex */
- status = pthread_mutex_trylock(&(mutex->mutex));
- if (status)
- return status; /* Failed */
-
- mutex->owner = thread_id; /* Mark thread as owner. */
- return mutex->depth = 1; /* Increment depth to end. */
+ return pthread_mutex_trylock((pthread_mutex_t *)(&(mutex->backend)));
}
-/********
- * Decrements the lock count on this mutex by one. If the lock count reaches
- * zero, release the lock on the mutex. Returns the lock count on the mutex.
- * It is an error to attempt to unlock a mutex which this thread doesn't hold
- * in which case return -1 and the mutex is unaffected.
- * Will also return -1 if the mutex free fails.
- */
+/* Unlock the mutex */
int
-objc_mutex_unlock(objc_mutex_t mutex)
+__objc_mutex_unlock(objc_mutex_t mutex)
{
- objc_thread_t thread_id; /* Cache our thread id. */
- int status;
-
- if (!mutex) /* Is argument bad? */
- return -1; /* Yes, abort. */
- thread_id = objc_thread_id(); /* Get this thread's id. */
- if (mutex->owner != thread_id) /* Does some else own lock? */
- return -1; /* Yes, abort. */
- if (mutex->depth > 1) /* Released last lock? */
- return --mutex->depth; /* No, Decrement depth, end.*/
- mutex->depth = 0; /* Yes, reset depth to 0. */
- mutex->owner = NULL; /* Set owner to "no thread".*/
-
- /* Unlock the PCThread mutex */
- status = pthread_mutex_unlock(&(mutex->mutex));
- if (status)
- return status; /* Failed */
-
- return 0; /* No, return success. */
+ return pthread_mutex_unlock((pthread_mutex_t *)(&(mutex->backend)));
}
-/********
- * Allocate a condition. Return the condition pointer if successful or NULL
- * if the allocation failed for any reason.
- */
-objc_condition_t
-objc_condition_allocate(void)
+/* Backend condition mutex functions */
+
+/* Allocate a condition. */
+int
+__objc_condition_allocate(objc_condition_t condition)
{
- objc_condition_t condition;
-
- if (!(condition = (objc_condition_t)objc_malloc(
- sizeof(struct objc_condition))))
- return NULL; /* Abort if malloc failed. */
-
- if ( pthread_cond_init(&(condition->condition), NULL) ) {
- objc_free(condition);
- return NULL;
- }
-
- return condition; /* Return condition handle. */
+ if (pthread_cond_init((pthread_cond_t *)(&(condition->backend)), NULL))
+ return -1;
+ else
+ return 0;
}
-/********
- * Deallocate a condition. Note that this includes an implicit
- * condition_broadcast to insure that waiting threads have the opportunity
- * to wake. It is legal to dealloc a condition only if no other
- * thread is/will be using it. Here we do NOT check for other threads
- * waiting but just wake them up.
- */
+/* Deallocate a condition. */
int
-objc_condition_deallocate(objc_condition_t condition)
+__objc_condition_deallocate(objc_condition_t condition)
{
- pthread_cond_broadcast(&(condition->condition));
- pthread_cond_destroy(&(condition->condition));
- objc_free(condition);
- return 0;
+ return pthread_cond_destroy((pthread_cond_t *)(&(condition->backend)));
}
-/********
- * Wait on the condition unlocking the mutex until objc_condition_signal()
- * or objc_condition_broadcast() are called for the same condition. The
- * given mutex *must* have the depth set to 1 so that it can be unlocked
- * here, so that someone else can lock it and signal/broadcast the condition.
- * The mutex is used to lock access to the shared data that make up the
- * "condition" predicate.
- */
+/* Wait on the condition */
int
-objc_condition_wait(objc_condition_t condition, objc_mutex_t mutex)
+__objc_condition_wait(objc_condition_t condition, objc_mutex_t mutex)
{
- objc_thread_t thread_id; /* Cache our thread id. */
-
- if (!mutex || !condition) /* Is argument bad? */
- return -1; /* Yes, abort. */
-
- thread_id = objc_thread_id(); /* Get this thread's id. */
- if (mutex->owner != thread_id) /* Does some else own lock? */
- return -1; /* Yes, abort. */
- if (mutex->depth > 1) /* Locked more than once ? */
- return -1; /* YES, return error */
- /* mutex will be unlocked */
- mutex->depth = 0; /* Yes, reset depth to 0. */
- mutex->owner = (objc_thread_t) -1; /* Set owner to "no thread".*/
-
- pthread_cond_wait(&(condition->condition),
- &(mutex->mutex)); /* unlock, wait ..., lock */
-
- mutex->owner = thread_id; /* Mark thread as owner. */
- mutex->depth = 1; /* Increment depth to end. */
- return 0; /* Return success. */
+ return pthread_cond_wait((pthread_cond_t *)(&(condition->backend)),
+ (pthread_mutex_t *)(&(mutex->backend)));
}
-/********
- * Wake up all threads waiting on this condition. It is recommended that
- * the called would lock the same mutex as the threads in objc_condition_wait
- * before changing the "condition predicate" and make this call and unlock it
- * right away after this call.
- */
+/* Wake up all threads waiting on this condition. */
int
-objc_condition_broadcast(objc_condition_t condition)
+__objc_condition_broadcast(objc_condition_t condition)
{
- if (!condition)
- return -1;
- pthread_cond_broadcast(&(condition->condition));
- return 0;
+ return pthread_cond_broadcast((pthread_cond_t *)(&(condition->backend)));
}
-/********
- * Wake up one thread waiting on this condition. It is recommended that
- * the called would lock the same mutex as the threads in objc_condition_wait
- * before changing the "condition predicate" and make this call and unlock it
- * right away after this call.
- */
+/* Wake up one thread waiting on this condition. */
int
-objc_condition_signal(objc_condition_t condition)
+__objc_condition_signal(objc_condition_t condition)
{
- if (!condition)
- return -1;
- pthread_cond_signal(&(condition->condition));
- return 0;
+ return pthread_cond_signal((pthread_cond_t *)(&(condition->backend)));
}
/* End of File */
diff --git a/gcc/objc/thr-single.c b/gcc/objc/thr-single.c
index 45b7b73..b196677 100644
--- a/gcc/objc/thr-single.c
+++ b/gcc/objc/thr-single.c
@@ -27,214 +27,166 @@ Boston, MA 02111-1307, USA. */
#include <objc/thr.h>
#include "runtime.h"
-/********
- * This structure represents a single mutual exclusion lock. Lock semantics
- * are detailed with the subsequent functions. We use whatever lock is
- * provided by the system. We augment it with depth and current owner id
- * fields to implement and re-entrant lock.
- */
-struct objc_mutex
-{
- volatile objc_thread_t owner; /* Id of thread that owns. */
- volatile int depth; /* # of acquires. */
-};
-
-/********
- * Initialize the threads subsystem. Returns 0 if successful, or -1 if no
- * thread support is available.
- */
+/* Thread local storage for a single thread */
+static void *thread_local_storage = NULL;
+
+/* Backend initialization functions */
+
+/* Initialize the threads subsystem. */
int
__objc_init_thread_system(void)
{
- DEBUG_PRINTF("__objc_init_thread_system\n");
- return -1; /* Failed. */
+ /* No thread support available */
+ return -1;
+}
+
+/* Close the threads subsystem. */
+int
+__objc_close_thread_system(void)
+{
+ /* No thread support available */
+ return -1;
}
-/********
- * Create a new thread of execution and return its id. Return NULL if fails.
- * The new thread starts in "func" with the given argument.
- */
+/* Backend thread functions */
+
+/* Create a new thread of execution. */
objc_thread_t
-objc_thread_create(void (*func)(void *arg), void *arg)
+__objc_thread_detach(void (*func)(void *arg), void *arg)
{
- return NULL; /* We can't start threads. */
+ /* No thread support available */
+ return NULL;
}
-/********
- * Set the current thread's priority.
- */
+/* Set the current thread's priority. */
int
-objc_thread_set_priority(int priority)
+__objc_thread_set_priority(int priority)
{
- return -1; /* Failed. */
+ /* No thread support available */
+ return -1;
}
-/********
- * Return the current thread's priority.
- */
+/* Return the current thread's priority. */
int
-objc_thread_get_priority(void)
+__objc_thread_get_priority(void)
{
- return OBJC_THREAD_INTERACTIVE_PRIORITY; /* Highest priority. */
+ return OBJC_THREAD_INTERACTIVE_PRIORITY;
}
-/********
- * Yield our process time to another thread. Any BUSY waiting that is done
- * by a thread should use this function to make sure that other threads can
- * make progress even on a lazy uniprocessor system.
- */
+/* Yield our process time to another thread. */
void
-objc_thread_yield(void)
+__objc_thread_yield(void)
{
return;
}
-/********
- * Terminate the current tread. Doesn't return anything. Doesn't return.
- * Actually, if it failed returns -1.
- */
+/* Terminate the current thread. */
int
-objc_thread_exit(void)
+__objc_thread_exit(void)
{
- exit(__objc_thread_exit_status);
+ /* 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. Must not be
- * NULL which is reserved as a marker for "no thread".
- */
+/* Returns an integer value which uniquely describes a thread. */
objc_thread_t
-objc_thread_id(void)
+__objc_thread_id(void)
{
- return (objc_thread_t)1; /* No thread support, use 1.*/
+ /* No thread support, use 1. */
+ return (objc_thread_t)1;
}
-/********
- * Sets the thread's local storage pointer. Returns 0 if successful or -1
- * if failed.
- */
-
-static void *thread_local_storage = NULL;
-
+/* Sets the thread's local storage pointer. */
int
-objc_thread_set_data(void *value)
+__objc_thread_set_data(void *value)
{
thread_local_storage = value;
return 0;
}
-/********
- * Returns the thread's local storage pointer. Returns NULL on failure.
- */
+/* Returns the thread's local storage pointer. */
void *
-objc_thread_get_data(void)
+__objc_thread_get_data(void)
{
return thread_local_storage;
}
-/********
- * Allocate a mutex. Return the mutex pointer if successful or NULL if the
- * allocation failed for any reason.
- */
-objc_mutex_t
-objc_mutex_allocate(void)
-{
- objc_mutex_t mutex;
-
- if (!(mutex = (objc_mutex_t)objc_malloc(sizeof(struct objc_mutex))))
- return NULL; /* Abort if malloc failed. */
-
- mutex->owner = NULL; /* No owner. */
- mutex->depth = 0; /* No locks. */
- return mutex; /* Return mutex handle. */
-}
-
-/********
- * Deallocate a mutex. Note that this includes an implicit mutex_lock to
- * insure that no one else is using the lock. It is legal to deallocate
- * a lock if we have a lock on it, but illegal to deallocate a lock held
- * by anyone else.
- * Returns the number of locks on the thread. (1 for deallocate).
- */
-int
-objc_mutex_deallocate(objc_mutex_t mutex)
-{
- int depth; /* # of locks on mutex. */
-
- if (!mutex) /* Is argument bad? */
- return -1; /* Yes, abort. */
- depth = objc_mutex_lock(mutex); /* Must have lock. */
-
- objc_free(mutex); /* Free memory. */
- return depth; /* Return last depth. */
-}
-
-/********
- * Grab a lock on a mutex. If this thread already has a lock on this mutex
- * then we increment the lock count. If another thread has a lock on the
- * mutex we block and wait for the thread to release the lock.
- * Returns the lock count on the mutex held by this thread.
- */
-int
-objc_mutex_lock(objc_mutex_t mutex)
-{
- objc_thread_t thread_id; /* Cache our thread id. */
-
- if (!mutex) /* Is argument bad? */
- return -1; /* Yes, abort. */
- thread_id = objc_thread_id(); /* Get this thread's id. */
- if (mutex->owner == thread_id) /* Already own lock? */
- return ++mutex->depth; /* Yes, increment depth. */
-
- mutex->owner = thread_id; /* Mark thread as owner. */
-
- return mutex->depth = 1; /* Increment depth to end. */
-}
-
-/********
- * Try to grab a lock on a mutex. If this thread already has a lock on
- * this mutex then we increment the lock count and return it. If another
- * thread has a lock on the mutex returns -1.
- */
-int
-objc_mutex_trylock(objc_mutex_t mutex)
-{
- objc_thread_t thread_id; /* Cache our thread id. */
-
- if (!mutex) /* Is argument bad? */
- return -1; /* Yes, abort. */
- thread_id = objc_thread_id(); /* Get this thread's id. */
- if (mutex->owner == thread_id) /* Already own lock? */
- return ++mutex->depth; /* Yes, increment depth. */
-
- mutex->owner = thread_id; /* Mark thread as owner. */
- return mutex->depth = 1; /* Increment depth to end. */
-}
-
-/********
- * Decrements the lock count on this mutex by one. If the lock count reaches
- * zero, release the lock on the mutex. Returns the lock count on the mutex.
- * It is an error to attempt to unlock a mutex which this thread doesn't hold
- * in which case return -1 and the mutex is unaffected.
- * Will also return -1 if the mutex free fails.
- */
-int
-objc_mutex_unlock(objc_mutex_t mutex)
-{
- objc_thread_t thread_id; /* Cache our thread id. */
-
- if (!mutex) /* Is argument bad? */
- return -1; /* Yes, abort. */
- thread_id = objc_thread_id(); /* Get this thread's id. */
- if (mutex->owner != thread_id) /* Does some else own lock? */
- return -1; /* Yes, abort. */
- if (mutex->depth > 1) /* Released last lock? */
- return --mutex->depth; /* No, Decrement depth, end.*/
- mutex->depth = 0; /* Yes, reset depth to 0. */
- mutex->owner = NULL; /* Set owner to "no thread".*/
-
- return 0; /* No, return success. */
+/* Backend mutex functions */
+
+/* Allocate a mutex. */
+int
+__objc_mutex_allocate(objc_mutex_t mutex)
+{
+ return 0;
+}
+
+/* Deallocate a mutex. */
+int
+__objc_mutex_deallocate(objc_mutex_t mutex)
+{
+ return 0;
+}
+
+/* Grab a lock on a mutex. */
+int
+__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
+__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
+__objc_mutex_unlock(objc_mutex_t mutex)
+{
+ return 0;
+}
+
+/* Backend condition mutex functions */
+
+/* Allocate a condition. */
+int
+__objc_condition_allocate(objc_condition_t condition)
+{
+ return 0;
+}
+
+/* Deallocate a condition. */
+int
+__objc_condition_deallocate(objc_condition_t condition)
+{
+ return 0;
+}
+
+/* Wait on the condition */
+int
+__objc_condition_wait(objc_condition_t condition, objc_mutex_t mutex)
+{
+ return 0;
+}
+
+/* Wake up all threads waiting on this condition. */
+int
+__objc_condition_broadcast(objc_condition_t condition)
+{
+ return 0;
+}
+
+/* Wake up one thread waiting on this condition. */
+int
+__objc_condition_signal(objc_condition_t condition)
+{
+ return 0;
}
/* End of File */
diff --git a/gcc/objc/thr-solaris.c b/gcc/objc/thr-solaris.c
index f1084bc..0b5227a 100644
--- a/gcc/objc/thr-solaris.c
+++ b/gcc/objc/thr-solaris.c
@@ -32,400 +32,228 @@ Boston, MA 02111-1307, USA. */
#include <synch.h>
#include <errno.h>
-/********
- * This structure represents a single mutual exclusion lock. Lock semantics
- * are detailed with the subsequent functions. We use whatever lock is
- * provided by the system. We augment it with depth and current owner id
- * fields to implement and re-entrant lock.
- */
-struct objc_mutex
-{
- volatile objc_thread_t owner; /* Id of thread that owns. */
- volatile int depth; /* # of acquires. */
- mutex_t lock; /* System mutex. */
-};
+/* Key structure for maintiain thread specific storage */
+static thread_key_t __objc_thread_data_key;
-struct objc_condition
-{
- cond_t condition; /* solaris condition */
-};
-
-/*****************************************************************************
- * Static variables.
- */
-static thread_key_t __objc_thread_data_key; /* Data key for thread data.*/
-
-/********
- * Initialize the threads subsystem. Returns 0 if successful, or -1 if no
- * thread support is available.
- */
+/* Backend initialization functions */
+
+/* Initialize the threads subsystem. */
int
__objc_init_thread_system(void)
{
- DEBUG_PRINTF("__objc_init_thread_system\n");
-
- if (thr_keycreate(&__objc_thread_data_key, NULL) == 0)
- return 0; /* Yes, return success. */
-
- return -1; /* Failed. */
+ /* Initialize the thread storage key */
+ if (thr_keycreate(&__objc_thread_data_key, NULL) == 0)
+ return 0;
+ else
+ return -1;
}
+/* Close the threads subsystem. */
int
-__objc_fini_thread_system(void)
+__objc_close_thread_system(void)
{
return 0;
}
-/********
- * Create a new thread of execution and return its id. Return -1 if fails.
- * The new thread starts in "func" with the given argument.
- */
+/* Backend thread functions */
+
+/* Create a new thread of execution. */
objc_thread_t
-objc_thread_create(void (*func)(void *arg), void *arg)
+__objc_thread_detach(void (*func)(void *arg), void *arg)
{
- objc_thread_t thread_id = NULL; /* Detached thread id. */
- thread_t new_thread_id = 0; /* Solaris thread id type. */
- int errn;
-
- objc_mutex_lock(__objc_runtime_mutex);
+ objc_thread_t thread_id;
+ thread_t new_thread_id = 0;
if (thr_create(NULL, 0, (void *)func, arg,
THR_DETACHED | THR_NEW_LWP,
- &new_thread_id) == 0) { /* Created new thread? */
- thread_id = (objc_thread_t)new_thread_id; /* Yes, remember its id. */
- __objc_runtime_threads_alive++;
- }
+ &new_thread_id) == 0)
+ thread_id = *(objc_thread_t *)&new_thread_id;
+ else
+ thread_id = NULL;
- objc_mutex_unlock(__objc_runtime_mutex);
-
return thread_id;
}
-/********
- * Set the current thread's priority.
- */
+/* Set the current thread's priority. */
int
-objc_thread_set_priority(int priority)
+__objc_thread_set_priority(int priority)
{
- int sys_priority = 0;
+ int sys_priority = 0;
- switch (priority) {
+ switch (priority)
+ {
case OBJC_THREAD_INTERACTIVE_PRIORITY:
- sys_priority = 300;
- break;
+ sys_priority = 300;
+ break;
default:
case OBJC_THREAD_BACKGROUND_PRIORITY:
- sys_priority = 200;
- break;
+ sys_priority = 200;
+ break;
case OBJC_THREAD_LOW_PRIORITY:
- sys_priority = 1000;
- break;
+ sys_priority = 1000;
+ break;
}
-
- if (thr_setprio(thr_self(), sys_priority) == 0)
- return 0; /* Changed priority. End. */
-
- return -1; /* Failed. */
+
+ /* Change priority */
+ if (thr_setprio(thr_self(), sys_priority) == 0)
+ return 0;
+ else
+ return -1;
}
-/********
- * Return the current thread's priority.
- */
+/* Return the current thread's priority. */
int
-objc_thread_get_priority(void)
+__objc_thread_get_priority(void)
{
- int sys_priority; /* Solaris thread priority. */
+ int sys_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;
+ 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;
}
-
- return -1; /* Couldn't get priority. */
+
+ /* Couldn't get priority. */
+ return -1;
}
-/********
- * Yield our process time to another thread. Any BUSY waiting that is done
- * by a thread should use this function to make sure that other threads can
- * make progress even on a lazy uniprocessor system.
- */
+/* Yield our process time to another thread. */
void
-objc_thread_yield(void)
+__objc_thread_yield(void)
{
- thr_yield(); /* Yield to equal thread. */
+ thr_yield();
}
-/********
- * Terminate the current tread. Doesn't return anything. Doesn't return.
- * Actually, if it failed returns -1.
- */
+/* Terminate the current thread. */
int
-objc_thread_exit(void)
+__objc_thread_exit(void)
{
- objc_mutex_lock(__objc_runtime_mutex);
- __objc_runtime_threads_alive++;
- objc_mutex_unlock(__objc_runtime_mutex);
-
- thr_exit(&__objc_thread_exit_status); /* Terminate thread. */
+ /* 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. Must not be
- * NULL which is reserved as a marker for "no thread".
- */
+/* Returns an integer value which uniquely describes a thread. */
objc_thread_t
-objc_thread_id(void)
+__objc_thread_id(void)
{
- return (objc_thread_t)thr_self();
+ return (objc_thread_t)thr_self();
}
-/********
- * Sets the thread's local storage pointer. Returns 0 if successful or -1
- * if failed.
- */
+/* Sets the thread's local storage pointer. */
int
-objc_thread_set_data(void *value)
+__objc_thread_set_data(void *value)
{
- if (thr_setspecific(__objc_thread_data_key, value) == 0)
- return 0;
+ if (thr_setspecific(__objc_thread_data_key, value) == 0)
+ return 0;
+ else
return -1;
}
-/********
- * Returns the thread's local storage pointer. Returns NULL on failure.
- */
+/* Returns the thread's local storage pointer. */
void *
-objc_thread_get_data(void)
+__objc_thread_get_data(void)
{
- void * value = NULL;
-
- if (thr_getspecific(__objc_thread_data_key, &value) == 0)
- return value; /* Return thread data. */
-
- return NULL;
-}
+ void *value = NULL;
-/********
- * Allocate a mutex. Return the mutex pointer if successful or NULL if
- * the allocation fails for any reason.
- */
-objc_mutex_t
-objc_mutex_allocate(void)
-{
- struct objc_mutex *mutex;
- int err = 0;
-
- if (!(mutex = (objc_mutex_t)objc_malloc(sizeof(struct objc_mutex))))
- return NULL; /* Abort if malloc failed. */
-
- err = mutex_init(&mutex->lock, USYNC_THREAD, 0);
-
- if (err != 0) { /* System init failed? */
- objc_free(mutex); /* Yes, free local memory. */
- return NULL; /* Abort. */
- }
- mutex->owner = NULL; /* No owner. */
- mutex->depth = 0; /* No locks. */
- return mutex; /* Return mutex handle. */
+ if (thr_getspecific(__objc_thread_data_key, &value) == 0)
+ return value;
+
+ return NULL;
}
-/********
- * Deallocate a mutex. Note that this includes an implicit mutex_lock to
- * insure that no one else is using the lock. It is legal to deallocate
- * a lock if we have a lock on it, but illegal to deallotcate a lock held
- * by anyone else.
- * Returns the number of locks on the thread. (1 for deallocate).
- */
+/* Backend mutex functions */
+
+/* Allocate a mutex. */
int
-objc_mutex_deallocate(objc_mutex_t mutex)
+__objc_mutex_allocate(objc_mutex_t mutex)
{
- int depth; /* # of locks on mutex. */
-
- if (!mutex) /* Is argument bad? */
- return -1; /* Yes, abort. */
- depth = objc_mutex_lock(mutex); /* Must have lock. */
-
- mutex_destroy(&mutex->lock); /* System deallocate. */
-
- objc_free(mutex); /* Free memory. */
- return depth; /* Return last depth. */
+ if (mutex_init( (mutex_t *)(&(mutex->backend)), USYNC_THREAD, 0))
+ return -1;
+ else
+ return 0;
}
-/********
- * Grab a lock on a mutex. If this thread already has a lock on this mutex
- * then we increment the lock count. If another thread has a lock on the
- * mutex we block and wait for the thread to release the lock.
- * Returns the lock count on the mutex held by this thread.
- */
+
+/* Deallocate a mutex. */
int
-objc_mutex_lock(objc_mutex_t mutex)
+__objc_mutex_deallocate(objc_mutex_t mutex)
{
- objc_thread_t thread_id; /* Cache our thread id. */
-
- if (!mutex) /* Is argument bad? */
- return -1; /* Yes, abort. */
- thread_id = objc_thread_id(); /* Get this thread's id. */
- if (mutex->owner == thread_id) /* Already own lock? */
- return ++mutex->depth; /* Yes, increment depth. */
-
- if (mutex_lock(&mutex->lock) != 0) /* Did lock acquire fail? */
- return -1; /* Yes, abort. */
-
- mutex->owner = thread_id; /* Mark thread as owner. */
- return mutex->depth = 1; /* Increment depth to end. */
+ mutex_destroy((mutex_t *)(&(mutex->backend)));
+ return 0;
}
-/********
- * Try to grab a lock on a mutex. If this thread already has a lock on
- * this mutex then we increment the lock count and return it. If another
- * thread has a lock on the mutex returns -1.
- */
+/* Grab a lock on a mutex. */
int
-objc_mutex_trylock(objc_mutex_t mutex)
+__objc_mutex_lock(objc_mutex_t mutex)
{
- objc_thread_t thread_id; /* Cache our thread id. */
-
- if (!mutex) /* Is argument bad? */
- return -1; /* Yes, abort. */
- thread_id = objc_thread_id(); /* Get this thread's id. */
- if (mutex->owner == thread_id) /* Already own lock? */
- return ++mutex->depth; /* Yes, increment depth. */
-
- if (mutex_trylock(&mutex->lock) != 0) /* Did lock acquire fail? */
- return -1; /* Yes, abort. */
-
- mutex->owner = thread_id; /* Mark thread as owner. */
- return mutex->depth = 1; /* Increment depth to end. */
+ if (mutex_lock((mutex_t *)(&(mutex->backend))) != 0)
+ return -1;
+ else
+ return 0;
}
-/********
- * Decrements the lock count on this mutex by one. If the lock count reaches
- * zero, release the lock on the mutex. Returns the lock count on the mutex.
- * It is an error to attempt to unlock a mutex which this thread doesn't hold
- * in which case return -1 and the mutex is unaffected.
- * Will also return -1 if the mutex free fails.
- */
+/* Try to grab a lock on a mutex. */
int
-objc_mutex_unlock(objc_mutex_t mutex)
+__objc_mutex_trylock(objc_mutex_t mutex)
{
- objc_thread_t thread_id; /* Cache our thread id. */
-
- if (!mutex) /* Is argument bad? */
- return -1; /* Yes, abort. */
- thread_id = objc_thread_id(); /* Get this thread's id. */
- if (mutex->owner != thread_id) /* Does some else own lock? */
- return -1; /* Yes, abort. */
- if (mutex->depth > 1) /* Released last lock? */
- return --mutex->depth; /* No, Decrement depth, end.*/
- mutex->depth = 0; /* Yes, reset depth to 0. */
- mutex->owner = NULL; /* Set owner to "no thread".*/
-
- if (mutex_unlock(&mutex->lock) != 0) /* Did lock release fail? */
- return -1; /* Yes, return error value. */
-
- return 0; /* No, return success. */
+ if (mutex_trylock((mutex_t *)(&(mutex->backend))) != 0)
+ return -1;
+ else
+ return 0;
}
-/********
- * Allocate a condition. Return the condition pointer if successful or NULL
- * if the allocation failed for any reason.
- */
-objc_condition_t
-objc_condition_allocate(void)
+/* Unlock the mutex */
+int
+__objc_mutex_unlock(objc_mutex_t mutex)
{
- objc_condition_t condition;
-
- if (!(condition = (objc_condition_t)objc_malloc(
- sizeof(struct objc_condition))))
- return NULL; /* Abort if malloc failed. */
+ if (mutex_unlock((mutex_t *)(&(mutex->backend))) != 0)
+ return -1;
+ else
+ return 0;
+}
- cond_init(&(condition->condition), USYNC_THREAD, NULL);
+/* Backend condition mutex functions */
- return condition; /* Return new condition */
+/* Allocate a condition. */
+int
+__objc_condition_allocate(objc_condition_t condition)
+{
+ return cond_init((cond_t *)(&(condition->backend)), USYNC_THREAD, NULL);
}
-/********
- * Deallocate a condition. Note that this includes an implicit
- * condition_broadcast to insure that waiting threads have the opportunity
- * to wake. It is legal to dealloc a condition only if no other
- * thread is/will be using it. Here we do NOT check for other threads
- * waiting but just wake them up.
- */
+/* Deallocate a condition. */
int
-objc_condition_deallocate(objc_condition_t condition)
+__objc_condition_deallocate(objc_condition_t condition)
{
- cond_broadcast(&(condition->condition)); /* Wakeup waiting threads */
- cond_destroy(&(condition->condition)); /* Kill condition */
- objc_free(condition); /* Release struct memory */
- return 0;
+ return cond_destroy((cond_t *)(&(condition->backend)));
}
-/********
- * Wait on the condition unlocking the mutex until objc_condition_signal()
- * or objc_condition_broadcast() are called for the same condition. The
- * given mutex *must* have the depth set to 1 so that it can be unlocked
- * here, so that someone else can lock it and signal/broadcast the condition.
- * The mutex is used to lock access to the shared data that make up the
- * "condition" predicate.
- */
+/* Wait on the condition */
int
-objc_condition_wait(objc_condition_t condition, objc_mutex_t mutex)
+__objc_condition_wait(objc_condition_t condition, objc_mutex_t mutex)
{
- objc_thread_t thread_id; /* Cache our thread id. */
-
- if (!mutex || !condition) /* Is argument bad? */
- return -1; /* Yes, abort. */
-
- thread_id = objc_thread_id(); /* Get this thread's id. */
- if (mutex->owner != thread_id) /* Does some else own lock? */
- return -1; /* Yes, abort. */
- if (mutex->depth > 1) /* Locked more than once ? */
- return -1; /* YES, return error */
- /* mutex will be unlocked */
- mutex->depth = 0; /* Yes, reset depth to 0. */
- mutex->owner = (objc_thread_t) -1; /* Set owner to "no thread".*/
-
- cond_wait(&(condition->condition),
- &(mutex->lock)); /* unlock, wait ..., lock */
-
- mutex->owner = thread_id; /* Mark thread as owner. */
- mutex->depth = 1; /* Must be here ! */
-
- return 0; /* Return success. */
+ return cond_wait((cond_t *)(&(condition->backend)),
+ (mutex_t *)(&(mutex->backend)));
}
-/********
- * Wake up all threads waiting on this condition. It is recommended that
- * the called would lock the same mutex as the threads in objc_condition_wait
- * before changing the "condition predicate" and make this call and unlock it
- * right away after this call.
- */
+/* Wake up all threads waiting on this condition. */
int
-objc_condition_broadcast(objc_condition_t condition)
+__objc_condition_broadcast(objc_condition_t condition)
{
- if (!condition)
- return -1;
- cond_broadcast(&(condition->condition));
- return 0;
+ return cond_broadcast((cond_t *)(&(condition->backend)));
}
-/********
- * Wake up one thread waiting on this condition. It is recommended that
- * the called would lock the same mutex as the threads in objc_condition_wait
- * before changing the "condition predicate" and make this call and unlock it
- * right away after this call.
- */
+/* Wake up one thread waiting on this condition. */
int
-objc_condition_signal(objc_condition_t condition)
+__objc_condition_signal(objc_condition_t condition)
{
- if (!condition)
- return -1;
- cond_signal(&(condition->condition));
- return 0;
+ return cond_signal((cond_t *)(&(condition->backend)));
}
/* End of File */
diff --git a/gcc/objc/thr-win32.c b/gcc/objc/thr-win32.c
index 520a91d..159e3e3 100644
--- a/gcc/objc/thr-win32.c
+++ b/gcc/objc/thr-win32.c
@@ -32,306 +32,241 @@ Boston, MA 02111-1307, USA. */
#endif
#include <windows.h>
-/********
- * This structure represents a single mutual exclusion lock. Lock semantics
- * are detailed with the subsequent functions. We use whatever lock is
- * provided by the system. We augment it with depth and current owner id
- * fields to implement and re-entrant lock.
- */
-struct objc_mutex
-{
- volatile objc_thread_t owner; /* Id of thread that owns. */
- volatile int depth; /* # of acquires. */
- HANDLE handle; /* Win32 mutex HANDLE. */
-};
-
-/*****************************************************************************
- * Static variables.
- */
-static DWORD __objc_data_tls = (DWORD)-1; /* Win32 Thread Local Index.*/
-
-/********
- * Initialize the threads subsystem. Returns 0 if successful, or -1 if no
- * thread support is available.
- */
+/* Key structure for maintiain thread specific storage */
+static DWORD __objc_data_tls = (DWORD)-1;
+
+/* Backend initialization functions */
+
+/* Initialize the threads subsystem. */
int
__objc_init_thread_system(void)
{
- DEBUG_PRINTF("__objc_init_thread_system\n");
-
+ /* Initialize the thread storage key */
if ((__objc_data_tls = TlsAlloc()) != (DWORD)-1)
- return 0; /* Yes, return success. */
-
- return -1; /* Failed. */
+ return 0;
+ else
+ return -1;
}
+/* Close the threads subsystem. */
int
-__objc_fini_thread_system(void)
+__objc_close_thread_system(void)
{
- if (__objc_data_tls != (DWORD)-1) {
+ if (__objc_data_tls != (DWORD)-1)
TlsFree(__objc_data_tls);
- return 0;
- }
- return -1;
+ return 0;
}
-/********
- * Create a new thread of execution and return its id. Return NULL if fails.
- * The new thread starts in "func" with the given argument.
- */
+/* Backend thread functions */
+
+/* Create a new thread of execution. */
objc_thread_t
-objc_thread_create(void (*func)(void *arg), void *arg)
+__objc_thread_detach(void (*func)(void *arg), void *arg)
{
- DWORD thread_id = 0; /* Detached thread id. */
- HANDLE win32_handle; /* Win32 thread handle. */
+ DWORD thread_id = 0;
+ HANDLE win32_handle;
- objc_mutex_lock(__objc_runtime_mutex);
-
- if ((win32_handle = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)func,
- arg, 0, &thread_id))) {
- __objc_runtime_threads_alive++;
- }
- else
- thread_id = 0;
-
- objc_mutex_unlock(__objc_runtime_mutex);
+ 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.
- */
+/* Set the current thread's priority. */
int
-objc_thread_set_priority(int priority)
+__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;
- }
+ 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; /* Changed priority. End. */
-
- return -1; /* Failed. */
+ return 0;
+ else
+ return -1;
}
-/********
- * Return the current thread's priority.
- */
+/* Return the current thread's priority. */
int
-objc_thread_get_priority(void)
+__objc_thread_get_priority(void)
{
- int sys_priority;
+ 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;
+ 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;
- }
- return -1; /* Couldn't get 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. Any BUSY waiting that is done
- * by a thread should use this function to make sure that other threads can
- * make progress even on a lazy uniprocessor system.
- */
+/* Yield our process time to another thread. */
void
-objc_thread_yield(void)
+__objc_thread_yield(void)
{
- Sleep(0); /* Yield to equal thread. */
+ Sleep(0);
}
-/********
- * Terminate the current tread. Doesn't return anything. Doesn't return.
- * Actually, if it failed returns -1.
- */
+/* Terminate the current thread. */
int
-objc_thread_exit(void)
+__objc_thread_exit(void)
{
- objc_mutex_lock(__objc_runtime_mutex);
- __objc_runtime_threads_alive--;
- objc_mutex_unlock(__objc_runtime_mutex);
-
- ExitThread(__objc_thread_exit_status); /* Terminate thread. */
+ /* exit the thread */
+ ExitThread(__objc_thread_exit_status);
+
+ /* Failed if we reached here */
return -1;
}
-/********
- * Returns an integer value which uniquely describes a thread. Must not be
- * -1 which is reserved as a marker for "no thread".
- */
+/* Returns an integer value which uniquely describes a thread. */
objc_thread_t
-objc_thread_id(void)
+__objc_thread_id(void)
{
- return (objc_thread_t)GetCurrentThreadId(); /* Return thread id. */
+ return (objc_thread_t)GetCurrentThreadId();
}
-/********
- * Sets the thread's local storage pointer. Returns 0 if successful or -1
- * if failed.
- */
+/* Sets the thread's local storage pointer. */
int
-objc_thread_set_data(void *value)
+__objc_thread_set_data(void *value)
{
if (TlsSetValue(__objc_data_tls, value))
- return 0; /* Return thread data. */
- return -1;
+ return 0;
+ else
+ return -1;
}
-/********
- * Returns the thread's local storage pointer. Returns NULL on failure.
- */
+/* Returns the thread's local storage pointer. */
void *
-objc_thread_get_data(void)
+__objc_thread_get_data(void)
{
return TlsGetValue(__objc_data_tls); /* Return thread data. */
}
-/********
- * Allocate a mutex. Return the mutex pointer if successful or NULL if
- * the allocation fails for any reason.
- */
-objc_mutex_t
-objc_mutex_allocate(void)
+/* Backend mutex functions */
+
+/* Allocate a mutex. */
+int
+__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
+__objc_mutex_deallocate(objc_mutex_t mutex)
{
- objc_mutex_t mutex;
- int err = 0;
+ CloseHandle((HANDLE)(mutex->backend));
+ return 0;
+}
- if (!(mutex = (objc_mutex_t)objc_malloc(sizeof(struct objc_mutex))))
- return NULL; /* Abort if malloc failed. */
+/* Grab a lock on a mutex. */
+int
+__objc_mutex_lock(objc_mutex_t mutex)
+{
+ int status;
- if ((mutex->handle = CreateMutex(NULL, 0, NULL)) == NULL) {
- objc_free(mutex); /* Failed, free memory. */
- return NULL; /* Abort. */
- }
- mutex->owner = NULL; /* No owner. */
- mutex->depth = 0; /* No locks. */
- return mutex; /* Return mutex handle. */
+ status = WaitForSingleObject((HANDLE)(mutex->backend), INFINITE);
+ if (status != WAIT_OBJECT_0 && status != WAIT_ABANDONED)
+ return -1;
+ else
+ return 0;
}
-/********
- * Deallocate a mutex. Note that this includes an implicit mutex_lock to
- * insure that no one else is using the lock. It is legal to deallocate
- * a lock if we have a lock on it, but illegal to deallotcate a lock held
- * by anyone else.
- * Returns the number of locks on the thread. (1 for deallocate).
- */
+/* Try to grab a lock on a mutex. */
int
-objc_mutex_deallocate(objc_mutex_t mutex)
+__objc_mutex_trylock(objc_mutex_t mutex)
{
- int depth; /* # of locks on mutex. */
+ int status;
- if (!mutex) /* Is argument bad? */
- return -1; /* Yes, abort. */
- depth = objc_mutex_lock(mutex); /* Must have lock. */
+ status = WaitForSingleObject((HANDLE)(mutex->backend), 0);
+ if (status != WAIT_OBJECT_0 && status != WAIT_ABANDONED)
+ return -1;
+ else
+ return 0;
+}
- CloseHandle(mutex->handle); /* Close Win32 handle. */
-
- objc_free(mutex); /* Free memory. */
- return depth; /* Return last depth. */
+/* Unlock the mutex */
+int
+__objc_mutex_unlock(objc_mutex_t mutex)
+{
+ if (ReleaseMutex((HANDLE)(mutex->backend)) == 0)
+ return -1;
+ else
+ return 0;
}
-/********
- * Grab a lock on a mutex. If this thread already has a lock on this mutex
- * then we increment the lock count. If another thread has a lock on the
- * mutex we block and wait for the thread to release the lock.
- * Returns the lock count on the mutex held by this thread.
- */
+/* Backend condition mutex functions */
+
+/* Allocate a condition. */
int
-objc_mutex_lock(objc_mutex_t mutex)
+__objc_condition_allocate(objc_condition_t condition)
{
- objc_thread_t thread_id; /* Cache our thread id. */
- int status;
-
- if (!mutex) /* Is argument bad? */
- return -1; /* Yes, abort. */
- thread_id = objc_thread_id(); /* Get this thread's id. */
- if (mutex->owner == thread_id) /* Already own lock? */
- return ++mutex->depth; /* Yes, increment depth. */
-
- status = WaitForSingleObject(mutex->handle, INFINITE);
- if (status != WAIT_OBJECT_0 && status != WAIT_ABANDONED)
- return -1; /* Failed, abort. */
-
- mutex->owner = thread_id; /* Mark thread as owner. */
+ /* Unimplemented. */
+ return -1;
+}
- return ++mutex->depth; /* Increment depth to end. */
+/* Deallocate a condition. */
+int
+__objc_condition_deallocate(objc_condition_t condition)
+{
+ /* Unimplemented. */
+ return -1;
}
-/********
- * Try to grab a lock on a mutex. If this thread already has a lock on
- * this mutex then we increment the lock count and return it. If another
- * thread has a lock on the mutex returns -1.
- */
+/* Wait on the condition */
int
-objc_mutex_trylock(objc_mutex_t mutex)
+__objc_condition_wait(objc_condition_t condition, objc_mutex_t mutex)
{
- objc_thread_t thread_id; /* Cache our thread id. */
- DWORD status; /* Return status from Win32.*/
-
- if (!mutex) /* Is argument bad? */
- return -1; /* Yes, abort. */
- thread_id = objc_thread_id(); /* Get this thread's id. */
- if (mutex->owner == thread_id) /* Already own lock? */
- return ++mutex->depth; /* Yes, increment depth. */
-
- status = WaitForSingleObject(mutex->handle, 0);
- if (status != WAIT_OBJECT_0 && status != WAIT_ABANDONED)
- return -1; /* Failed, abort. */
-
- mutex->owner = thread_id; /* Mark thread as owner. */
- return ++mutex->depth; /* Increment depth to end. */
+ /* Unimplemented. */
+ return -1;
}
-/********
- * Decrements the lock count on this mutex by one. If the lock count reaches
- * zero, release the lock on the mutex. Returns the lock count on the mutex.
- * It is an error to attempt to unlock a mutex which this thread doesn't hold
- * in which case return -1 and the mutex is unaffected.
- * Will also return -1 if the mutex free fails.
- */
+/* Wake up all threads waiting on this condition. */
int
-objc_mutex_unlock(objc_mutex_t mutex)
+__objc_condition_broadcast(objc_condition_t condition)
{
- objc_thread_t thread_id; /* Cache our thread id. */
-
- if (!mutex) /* Is argument bad? */
- return -1; /* Yes, abort. */
- thread_id = objc_thread_id(); /* Get this thread's id. */
- if (mutex->owner != thread_id) /* Does some else own lock? */
- return -1; /* Yes, abort. */
- if (mutex->depth > 1) /* Released last lock? */
- return --mutex->depth; /* No, Decrement depth, end.*/
- mutex->depth = 0; /* Yes, reset depth to 0. */
- mutex->owner = NULL; /* Set owner to "no thread".*/
-
- if (ReleaseMutex(mutex->handle) == 0)
- return -1; /* Failed, abort. */
-
- return 0; /* No, return success. */
+ /* Unimplemented. */
+ return -1;
+}
+
+/* Wake up one thread waiting on this condition. */
+int
+__objc_condition_signal(objc_condition_t condition)
+{
+ /* Unimplemented. */
+ return -1;
}
/* End of File */
diff --git a/gcc/objc/thr.c b/gcc/objc/thr.c
index 2770b7d..f1c957a 100644
--- a/gcc/objc/thr.c
+++ b/gcc/objc/thr.c
@@ -27,20 +27,15 @@ Boston, MA 02111-1307, USA. */
#include <stdlib.h>
#include "runtime.h"
-/*************************************************************************
- * Universal static variables:
- */
-int __objc_thread_exit_status = 0; /* Global exit status. */
+/* Global exit status. */
+int __objc_thread_exit_status = 0;
/* Flag which lets us know if we ever became multi threaded */
int __objc_is_multi_threaded = 0;
+
/* The hook function called when the runtime becomes multi threaded */
objc_thread_callback _objc_became_multi_threaded = NULL;
-/*****************************************************************************
- * Universal Functionality
- */
-
/*
Use this to set the hook function that will be called when the
runtime initially becomes multi threaded.
@@ -60,94 +55,480 @@ objc_thread_callback objc_set_thread_callback(objc_thread_callback func)
return temp;
}
-/********
- * First function called in a thread, starts everything else.
+/*
+ Private functions
+
+ These functions are utilized by the frontend, but they are not
+ considered part of the public interface.
+ */
+
+/*
+ First function called in a thread, starts everything else.
+
+ This function is passed to the backend by objc_thread_detach
+ as the starting function for a new thread.
*/
struct __objc_thread_start_state
{
- SEL selector;
- id object;
- id argument;
+ SEL selector;
+ id object;
+ id argument;
};
static volatile void
__objc_thread_detach_function(struct __objc_thread_start_state *istate)
{
- if (istate) { /* Is state valid? */
- id (*imp)(id,SEL,id);
- SEL selector = istate->selector;
- id object = istate->object;
- id argument = istate->argument;
+ /* Valid state? */
+ if (istate) {
+ id (*imp)(id,SEL,id);
+ SEL selector = istate->selector;
+ id object = istate->object;
+ id argument = istate->argument;
- objc_free(istate);
+ /* Don't need anymore so free it */
+ objc_free(istate);
- /* Clear out the thread local storage */
- objc_thread_set_data(NULL);
+ /* Clear out the thread local storage */
+ objc_thread_set_data(NULL);
- /* Check to see if we just became multi threaded */
- if (!__objc_is_multi_threaded) {
- __objc_is_multi_threaded = 1;
+ /* Check to see if we just became multi threaded */
+ if (!__objc_is_multi_threaded)
+ {
+ __objc_is_multi_threaded = 1;
- /* Call the hook function */
- if (_objc_became_multi_threaded != NULL)
- (*_objc_became_multi_threaded)();
- }
+ /* Call the hook function */
+ if (_objc_became_multi_threaded != NULL)
+ (*_objc_became_multi_threaded)();
+ }
- if ((imp = (id(*)(id, SEL, id))objc_msg_lookup(object, selector))) {
- (*imp)(object, selector, argument);
- }
- else
- fprintf(stderr, "__objc_thread_start called with bad selector.\n");
- }
- else {
- fprintf(stderr, "__objc_thread_start called with NULL state.\n");
- }
- objc_thread_exit();
+ /* Call the method */
+ if ((imp = (id(*)(id, SEL, id))objc_msg_lookup(object, selector)))
+ (*imp)(object, selector, argument);
+ else
+ objc_error(object, OBJC_ERR_UNIMPLEMENTED,
+ "objc_thread_detach called with bad selector.\n");
+ }
+ else
+ objc_error(nil, OBJC_ERR_BAD_STATE,
+ "objc_thread_detach called with NULL state.\n");
+
+ /* Exit the thread */
+ objc_thread_exit();
}
-/********
- * Detach a new thread of execution and return its id. Returns NULL if fails.
- * Thread is started by sending message with selector to object. Message
- * takes a single argument.
- */
+/*
+ Frontend functions
+
+ These functions constitute the public interface to the Objective-C thread
+ and mutex functionality.
+ */
+
+/* Frontend thread functions */
+
+/*
+ Detach a new thread of execution and return its id. Returns NULL if fails.
+ Thread is started by sending message with selector to object. Message
+ takes a single argument.
+ */
objc_thread_t
objc_thread_detach(SEL selector, id object, id argument)
{
- struct __objc_thread_start_state *istate; /* Initialial thread state. */
- objc_thread_t thread_id = NULL; /* Detached thread id. */
+ struct __objc_thread_start_state *istate;
+ objc_thread_t thread_id = NULL;
+ /* Allocate the state structure */
if (!(istate = (struct __objc_thread_start_state *)
- objc_malloc(sizeof(*istate)))) /* Can we allocate state? */
- return NULL; /* No, abort. */
+ objc_malloc(sizeof(*istate))))
+ return NULL;
- istate->selector = selector; /* Initialize the thread's */
- istate->object = object; /* state structure. */
+ /* Initialize the state structure */
+ istate->selector = selector;
+ istate->object = object;
istate->argument = argument;
- if ((thread_id = objc_thread_create((void *)__objc_thread_detach_function,
- istate)) == NULL) {
- objc_free(istate); /* Release state if failed. */
- return thread_id;
- }
+ /* lock access */
+ objc_mutex_lock(__objc_runtime_mutex);
+
+ /* Call the backend to spawn the thread */
+ if ((thread_id = __objc_thread_detach((void *)__objc_thread_detach_function,
+ istate)) == NULL)
+ {
+ /* failed! */
+ objc_mutex_unlock(__objc_runtime_mutex);
+ objc_free(istate);
+ return NULL;
+ }
+
+ /* Increment our thread counter */
+ __objc_runtime_threads_alive++;
+ objc_mutex_unlock(__objc_runtime_mutex);
return thread_id;
}
-#undef objc_mutex_lock()
-#undef objc_mutex_unlock()
+/* Set the current thread's priority. */
+int
+objc_thread_set_priority(int priority)
+{
+ /* Call the backend */
+ return __objc_thread_set_priority(priority);
+}
+/* Return the current thread's priority. */
int
-objc_mutex_unlock_x(objc_mutex_t mutex, const char *f, int l)
+objc_thread_get_priority(void)
{
- printf("%16.16s#%4d < unlock", f, l);
- return objc_mutex_unlock(mutex);
+ /* Call the backend */
+ return __objc_thread_get_priority();
}
+/*
+ Yield our process time to another thread. Any BUSY waiting that is done
+ by a thread should use this function to make sure that other threads can
+ make progress even on a lazy uniprocessor system.
+ */
+void
+objc_thread_yield(void)
+{
+ /* Call the backend */
+ __objc_thread_yield();
+}
+
+/*
+ Terminate the current tread. Doesn't return.
+ Actually, if it failed returns -1.
+ */
int
-objc_mutex_lock_x(objc_mutex_t mutex, const char *f, int l)
+objc_thread_exit(void)
{
- printf("%16.16s#%4d < lock", f, l);
- return objc_mutex_lock(mutex);
+ /* Decrement our counter of the number of threads alive */
+ objc_mutex_lock(__objc_runtime_mutex);
+ __objc_runtime_threads_alive--;
+ objc_mutex_unlock(__objc_runtime_mutex);
+
+ /* Call the backend to terminate the thread */
+ return __objc_thread_exit();
+}
+
+/*
+ Returns an integer value which uniquely describes a thread. Must not be
+ NULL which is reserved as a marker for "no thread".
+ */
+objc_thread_t
+objc_thread_id(void)
+{
+ /* Call the backend */
+ return __objc_thread_id();
+}
+
+/*
+ Sets the thread's local storage pointer.
+ Returns 0 if successful or -1 if failed.
+ */
+int
+objc_thread_set_data(void *value)
+{
+ /* Call the backend */
+ return __objc_thread_set_data(value);
+}
+
+/*
+ Returns the thread's local storage pointer. Returns NULL on failure.
+ */
+void *
+objc_thread_get_data(void)
+{
+ /* Call the backend */
+ return __objc_thread_get_data();
+}
+
+/* Frontend mutex functions */
+
+/*
+ Allocate a mutex. Return the mutex pointer if successful or NULL if the
+ allocation failed for any reason.
+ */
+objc_mutex_t
+objc_mutex_allocate(void)
+{
+ objc_mutex_t mutex;
+
+ /* Allocate the mutex structure */
+ if (!(mutex = (objc_mutex_t)objc_malloc(sizeof(struct objc_mutex))))
+ return NULL;
+
+ /* Call backend to create the mutex */
+ if (__objc_mutex_allocate(mutex))
+ {
+ /* failed! */
+ objc_free(mutex);
+ return NULL;
+ }
+
+ /* Initialize mutex */
+ mutex->owner = NULL;
+ mutex->depth = 0;
+ return mutex;
+}
+
+/*
+ Deallocate a mutex. Note that this includes an implicit mutex_lock to
+ insure that no one else is using the lock. It is legal to deallocate
+ a lock if we have a lock on it, but illegal to deallocate a lock held
+ by anyone else.
+ Returns the number of locks on the thread. (1 for deallocate).
+ */
+int
+objc_mutex_deallocate(objc_mutex_t mutex)
+{
+ int depth;
+
+ /* Valid mutex? */
+ if (!mutex)
+ return -1;
+
+ /* Acquire lock on mutex */
+ depth = objc_mutex_lock(mutex);
+
+ /* Call backend to destroy mutex */
+ if (__objc_mutex_deallocate(mutex))
+ return -1;
+
+ /* Free the mutex structure */
+ objc_free(mutex);
+
+ /* Return last depth */
+ return depth;
+}
+
+/*
+ Grab a lock on a mutex. If this thread already has a lock on this mutex
+ then we increment the lock count. If another thread has a lock on the
+ mutex we block and wait for the thread to release the lock.
+ Returns the lock count on the mutex held by this thread.
+ */
+int
+objc_mutex_lock(objc_mutex_t mutex)
+{
+ objc_thread_t thread_id;
+ int status;
+
+ /* Valid mutex? */
+ if (!mutex)
+ return -1;
+
+ /* If we already own the lock then increment depth */
+ thread_id = objc_thread_id();
+ if (mutex->owner == thread_id)
+ return ++mutex->depth;
+
+ /* Call the backend to lock the mutex */
+ status = __objc_mutex_lock(mutex);
+
+ /* Failed? */
+ if (status)
+ return status;
+
+ /* Successfully locked the thread */
+ mutex->owner = thread_id;
+ return mutex->depth = 1;
+}
+
+/*
+ Try to grab a lock on a mutex. If this thread already has a lock on
+ this mutex then we increment the lock count and return it. If another
+ thread has a lock on the mutex returns -1.
+ */
+int
+objc_mutex_trylock(objc_mutex_t mutex)
+{
+ objc_thread_t thread_id;
+ int status;
+
+ /* Valid mutex? */
+ if (!mutex)
+ return -1;
+
+ /* If we already own the lock then increment depth */
+ thread_id = objc_thread_id();
+ if (mutex->owner == thread_id)
+ return ++mutex->depth;
+
+ /* Call the backend to try to lock the mutex */
+ status = __objc_mutex_trylock(mutex);
+
+ /* Failed? */
+ if (status)
+ return status;
+
+ /* Successfully locked the thread */
+ mutex->owner = thread_id;
+ return mutex->depth = 1;
+}
+
+/*
+ Unlocks the mutex by one level.
+ Decrements the lock count on this mutex by one.
+ If the lock count reaches zero, release the lock on the mutex.
+ Returns the lock count on the mutex.
+ It is an error to attempt to unlock a mutex which this thread
+ doesn't hold in which case return -1 and the mutex is unaffected.
+ */
+int
+objc_mutex_unlock(objc_mutex_t mutex)
+{
+ objc_thread_t thread_id;
+ int status;
+
+ /* Valid mutex? */
+ if (!mutex)
+ return -1;
+
+ /* If another thread owns the lock then abort */
+ thread_id = objc_thread_id();
+ if (mutex->owner != thread_id)
+ return -1;
+
+ /* Decrement depth and return */
+ if (mutex->depth > 1)
+ return --mutex->depth;
+
+ /* Depth down to zero so we are no longer the owner */
+ mutex->depth = 0;
+ mutex->owner = NULL;
+
+ /* Have the backend unlock the mutex */
+ status = __objc_mutex_unlock(mutex);
+
+ /* Failed? */
+ if (status)
+ return status;
+
+ return 0;
+}
+
+/* Frontend condition mutex functions */
+
+/*
+ Allocate a condition. Return the condition pointer if successful or NULL
+ if the allocation failed for any reason.
+ */
+objc_condition_t
+objc_condition_allocate(void)
+{
+ objc_condition_t condition;
+
+ /* Allocate the condition mutex structure */
+ if (!(condition =
+ (objc_condition_t)objc_malloc(sizeof(struct objc_condition))))
+ return NULL;
+
+ /* Call the backend to create the condition mutex */
+ if (__objc_condition_allocate(condition))
+ {
+ /* failed! */
+ objc_free(condition);
+ return NULL;
+ }
+
+ /* Success! */
+ return condition;
+}
+
+/*
+ Deallocate a condition. Note that this includes an implicit
+ condition_broadcast to insure that waiting threads have the opportunity
+ to wake. It is legal to dealloc a condition only if no other
+ thread is/will be using it. Here we do NOT check for other threads
+ waiting but just wake them up.
+ */
+int
+objc_condition_deallocate(objc_condition_t condition)
+{
+ /* Broadcast the condition */
+ if (objc_condition_broadcast(condition))
+ return -1;
+
+ /* Call the backend to destroy */
+ if (__objc_condition_deallocate(condition))
+ return -1;
+
+ /* Free the condition mutex structure */
+ objc_free(condition);
+
+ return 0;
+}
+
+/*
+ Wait on the condition unlocking the mutex until objc_condition_signal()
+ or objc_condition_broadcast() are called for the same condition. The
+ given mutex *must* have the depth set to 1 so that it can be unlocked
+ here, so that someone else can lock it and signal/broadcast the condition.
+ The mutex is used to lock access to the shared data that make up the
+ "condition" predicate.
+ */
+int
+objc_condition_wait(objc_condition_t condition, objc_mutex_t mutex)
+{
+ objc_thread_t thread_id;
+
+ /* Valid arguments? */
+ if (!mutex || !condition)
+ return -1;
+
+ /* Make sure we are owner of mutex */
+ thread_id = objc_thread_id();
+ if (mutex->owner != thread_id)
+ return -1;
+
+ /* Cannot be locked more than once */
+ if (mutex->depth > 1)
+ return -1;
+
+ /* Virtually unlock the mutex */
+ mutex->depth = 0;
+ mutex->owner = (objc_thread_t)NULL;
+
+ /* Call the backend to wait */
+ __objc_condition_wait(condition, mutex);
+
+ /* Make ourselves owner of the mutex */
+ mutex->owner = thread_id;
+ mutex->depth = 1;
+
+ return 0;
+}
+
+/*
+ Wake up all threads waiting on this condition. It is recommended that
+ the called would lock the same mutex as the threads in objc_condition_wait
+ before changing the "condition predicate" and make this call and unlock it
+ right away after this call.
+ */
+int
+objc_condition_broadcast(objc_condition_t condition)
+{
+ /* Valid condition mutex? */
+ if (!condition)
+ return -1;
+
+ return __objc_condition_broadcast(condition);
+}
+
+/*
+ Wake up one thread waiting on this condition. It is recommended that
+ the called would lock the same mutex as the threads in objc_condition_wait
+ before changing the "condition predicate" and make this call and unlock it
+ right away after this call.
+ */
+int
+objc_condition_signal(objc_condition_t condition)
+{
+ /* Valid condition mutex? */
+ if (!condition)
+ return -1;
+
+ return __objc_condition_signal(condition);
}
/* End of File */