]> oss.titaniummirror.com Git - msp430-gcc.git/blobdiff - libobjc/thr.c
Imported gcc-4.4.3
[msp430-gcc.git] / libobjc / thr.c
diff --git a/libobjc/thr.c b/libobjc/thr.c
deleted file mode 100644 (file)
index 13a22a5..0000000
+++ /dev/null
@@ -1,563 +0,0 @@
-/* GNU Objective C Runtime Thread Interface
-   Copyright (C) 1996, 1997 Free Software Foundation, Inc.
-   Contributed by Galen C. Hunt (gchunt@cs.rochester.edu)
-
-This file is part of GNU CC.
-
-GNU CC is free software; you can redistribute it and/or modify it under the
-terms of the GNU General Public License as published by the Free Software
-Foundation; either version 2, or (at your option) any later version.
-
-GNU CC is distributed in the hope that it will be useful, but WITHOUT ANY
-WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
-details.
-
-You should have received a copy of the GNU General Public License along with
-GNU CC; see the file COPYING.  If not, write to the Free Software
-Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA.  */
-
-/* As a special exception, if you link this library with files compiled with
-   GCC to produce an executable, this does not cause the resulting executable
-   to be covered by the GNU General Public License. This exception does not
-   however invalidate any other reasons why the executable file might be
-   covered by the GNU General Public License.  */
-
-#include <stdlib.h>
-#include "runtime.h"
-
-/* 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;
-
-/*
-  Use this to set the hook function that will be called when the 
-  runtime initially becomes multi threaded.
-  The hook function is only called once, meaning only when the 
-  2nd thread is spawned, not for each and every thread.
-
-  It returns the previous hook function or NULL if there is none.
-
-  A program outside of the runtime could set this to some function so
-  it can be informed; for example, the GNUstep Base Library sets it 
-  so it can implement the NSBecomingMultiThreaded notification.
-  */
-objc_thread_callback objc_set_thread_callback(objc_thread_callback func)
-{
-  objc_thread_callback temp = _objc_became_multi_threaded;
-  _objc_became_multi_threaded = func;
-  return temp;
-}
-
-/*
-  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;
-};
-
-static volatile void
-__objc_thread_detach_function(struct __objc_thread_start_state *istate)
-{
-  /* Valid state? */
-  if (istate) {
-    id (*imp)(id,SEL,id);
-    SEL selector = istate->selector;
-    id object   = istate->object;
-    id argument = istate->argument;
-
-    /* Don't need anymore so free it */
-    objc_free(istate);
-
-    /* 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;
-
-       /* Call the hook function */
-       if (_objc_became_multi_threaded != NULL)
-         (*_objc_became_multi_threaded)();
-      }
-
-    /* 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();
-}
-
-/*
-  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;
-  objc_thread_t        thread_id = NULL;
-
-  /* Allocate the state structure */
-  if (!(istate = (struct __objc_thread_start_state *)
-       objc_malloc(sizeof(*istate))))
-    return NULL;
-
-  /* Initialize the state structure */
-  istate->selector = selector;
-  istate->object = object;
-  istate->argument = argument;
-
-  /* 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;
-}
-
-/* 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_thread_get_priority(void)
-{
-  /* 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_thread_exit(void)
-{
-  /* 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);
-}
-
-/* Make the objc thread system aware that a thread which is managed
-   (started, stopped) by external code could access objc facilities
-   from now on.  This is used when you are interfacing with some
-   external non-objc-based environment/system - you must call
-   objc_thread_add() before an alien thread makes any calls to
-   Objective-C.  Do not cause the _objc_became_multi_threaded hook to
-   be executed. */
-void 
-objc_thread_add(void)
-{
-  objc_mutex_lock(__objc_runtime_mutex);
-  __objc_is_multi_threaded = 1;
-  __objc_runtime_threads_alive++;
-  objc_mutex_unlock(__objc_runtime_mutex);  
-}
-
-/* Make the objc thread system aware that a thread managed (started,
-   stopped) by some external code will no longer access objc and thus
-   can be forgotten by the objc thread system.  Call
-   objc_thread_remove() when your alien thread is done with making
-   calls to Objective-C. */
-void
-objc_thread_remove(void)
-{
-  objc_mutex_lock(__objc_runtime_mutex);
-  __objc_runtime_threads_alive--;
-  objc_mutex_unlock(__objc_runtime_mutex);  
-}
-
-/* End of File */