(objc_condition_{,de}allocate): New functions.
authorRichard Kenner <kenner@gcc.gnu.org>
Mon, 3 Feb 1997 00:53:23 +0000 (19:53 -0500)
committerRichard Kenner <kenner@gcc.gnu.org>
Mon, 3 Feb 1997 00:53:23 +0000 (19:53 -0500)
(objc_condition_{wait,broadcast,signal}): New functions.
(__objc_runtime_mutex): Eliminate leading underscore
from name of objc mutex and thread structures.

From-SVN: r13596

gcc/objc/thr-solaris.c

index 1a843be1c1279e68f411435337a461b613a101e2..f1084bc79138e62f1e3c02c0f8f20bfc70a0cabb 100644 (file)
@@ -1,7 +1,8 @@
 /* GNU Objective C Runtime Thread Interface
-   Copyright (C) 1996 Free Software Foundation, Inc.
+   Copyright (C) 1996, 1997 Free Software Foundation, Inc.
    Contributed by Galen C. Hunt (gchunt@cs.rochester.edu)
-
+   Conditions added by Mircea Oancea (mircea@first.elcom.pub.ro)
+      
 This file is part of GNU CC.
 
 GNU CC is free software; you can redistribute it and/or modify it under the
@@ -37,13 +38,18 @@ Boston, MA 02111-1307, USA.  */
  *  provided by the system.  We augment it with depth and current owner id
  *  fields to implement and re-entrant lock.
  */
-struct _objc_mutex 
+struct objc_mutex 
 {
-    volatile _objc_thread_t     owner;          /* Id of thread that owns.  */
+    volatile objc_thread_t     owner;          /* Id of thread that owns.  */
     volatile int                depth;          /* # of acquires.           */
     mutex_t                     lock;           /* System mutex.            */
 };
 
+struct objc_condition
+{
+    cond_t                     condition;      /* solaris condition        */
+};
+
 /*****************************************************************************
  *  Static variables.
  */
@@ -74,10 +80,10 @@ __objc_fini_thread_system(void)
  *  Create a new thread of execution and return its id.  Return -1 if fails.
  *  The new thread starts in "func" with the given argument.
  */
-_objc_thread_t
+objc_thread_t
 objc_thread_create(void (*func)(void *arg), void *arg)
 {
-  _objc_thread_t        thread_id = NULL;       /* Detached thread id.      */
+  objc_thread_t        thread_id = NULL;       /* Detached thread id.      */
   thread_t              new_thread_id = 0;      /* Solaris thread id type.  */
   int                   errn;
 
@@ -86,7 +92,7 @@ objc_thread_create(void (*func)(void *arg), void *arg)
   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.    */
+    thread_id = (objc_thread_t)new_thread_id;  /* Yes, remember its id.    */
     __objc_runtime_threads_alive++;
   }
   
@@ -171,10 +177,10 @@ objc_thread_exit(void)
  *  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_t
 objc_thread_id(void)
 {
-    return (_objc_thread_t)thr_self();
+    return (objc_thread_t)thr_self();
 }
 
 /********
@@ -207,13 +213,13 @@ objc_thread_get_data(void)
  *  Allocate a mutex.  Return the mutex pointer if successful or NULL if
  *  the allocation fails for any reason.
  */
-_objc_mutex_t
+objc_mutex_t
 objc_mutex_allocate(void)
 {
-    struct _objc_mutex *mutex;
+    struct objc_mutex *mutex;
     int         err = 0;
     
-    if (!(mutex = (_objc_mutex_t) objc_malloc(sizeof(struct _objc_mutex))))
+    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);
@@ -235,7 +241,7 @@ objc_mutex_allocate(void)
  *  Returns the number of locks on the thread.  (1 for deallocate).
  */
 int
-objc_mutex_deallocate(_objc_mutex_t mutex)
+objc_mutex_deallocate(objc_mutex_t mutex)
 {
     int         depth;                          /* # of locks on mutex.     */
 
@@ -256,9 +262,9 @@ objc_mutex_deallocate(_objc_mutex_t mutex)
  *  Returns the lock count on the mutex held by this thread.
  */
 int
-objc_mutex_lock(_objc_mutex_t mutex)
+objc_mutex_lock(objc_mutex_t mutex)
 {
-    _objc_thread_t      thread_id;              /* Cache our thread id.     */
+    objc_thread_t      thread_id;              /* Cache our thread id.     */
 
     if (!mutex)                                 /* Is argument bad?         */
         return -1;                              /* Yes, abort.              */
@@ -279,9 +285,9 @@ objc_mutex_lock(_objc_mutex_t mutex)
  *  thread has a lock on the mutex returns -1.
  */
 int
-objc_mutex_trylock(_objc_mutex_t mutex)
+objc_mutex_trylock(objc_mutex_t mutex)
 {
-    _objc_thread_t      thread_id;              /* Cache our thread id.     */
+    objc_thread_t      thread_id;              /* Cache our thread id.     */
 
     if (!mutex)                                 /* Is argument bad?         */
         return -1;                              /* Yes, abort.              */
@@ -304,9 +310,9 @@ objc_mutex_trylock(_objc_mutex_t mutex)
  *  Will also return -1 if the mutex free fails.
  */
 int
-objc_mutex_unlock(_objc_mutex_t mutex)
+objc_mutex_unlock(objc_mutex_t mutex)
 {
-    _objc_thread_t      thread_id;              /* Cache our thread id.     */
+    objc_thread_t      thread_id;              /* Cache our thread id.     */
     
     if (!mutex)                                 /* Is argument bad?         */
         return -1;                              /* Yes, abort.              */
@@ -324,4 +330,102 @@ objc_mutex_unlock(_objc_mutex_t mutex)
     return 0;                                   /* No, return success.      */
 }
 
+/********
+ *  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.  */
+
+    cond_init(&(condition->condition), USYNC_THREAD, NULL);
+
+    return condition;                           /* Return new 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)
+{
+    cond_broadcast(&(condition->condition));    /* Wakeup waiting threads   */
+    cond_destroy(&(condition->condition));      /* Kill condition           */
+    objc_free(condition);                       /* Release struct memory    */
+    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;                /* 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.          */
+}
+
+/********
+ *  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)
+{
+    if (!condition)
+        return -1;
+    cond_broadcast(&(condition->condition));
+    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.
+ */
+int
+objc_condition_signal(objc_condition_t condition)
+{
+    if (!condition)
+        return -1;
+    cond_signal(&(condition->condition));
+    return 0;
+}
+
 /* End of File */