aboutsummaryrefslogtreecommitdiffstats
path: root/gcc-4.7/libobjc/thr.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc-4.7/libobjc/thr.c')
-rw-r--r--gcc-4.7/libobjc/thr.c550
1 files changed, 0 insertions, 550 deletions
diff --git a/gcc-4.7/libobjc/thr.c b/gcc-4.7/libobjc/thr.c
deleted file mode 100644
index 095b9403a..000000000
--- a/gcc-4.7/libobjc/thr.c
+++ /dev/null
@@ -1,550 +0,0 @@
-/* GNU Objective C Runtime Thread Interface
- Copyright (C) 1996, 1997, 2009, 2010 Free Software Foundation, Inc.
- Contributed by Galen C. Hunt (gchunt@cs.rochester.edu)
-
-This file is part of GCC.
-
-GCC 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 3, or (at your option) any later version.
-
-GCC 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.
-
-Under Section 7 of GPL version 3, you are granted additional
-permissions described in the GCC Runtime Library Exception, version
-3.1, as published by the Free Software Foundation.
-
-You should have received a copy of the GNU General Public License and
-a copy of the GCC Runtime Library Exception along with this program;
-see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
-<http://www.gnu.org/licenses/>. */
-
-#include "objc-private/common.h"
-#include "objc-private/error.h"
-#define _LIBOBJC
-/* The line below is needed for declarations of functions such as
- pthread_mutexattr_settype, without which gthr-posix.h may fail to
- compile within libobjc. Unfortunately, this breaks compilation on
- Tru64 UNIX V4.0F, so disable it there. */
-#ifndef __osf__
-#define _XOPEN_SOURCE 500
-#endif
-#include "config.h"
-#include "tconfig.h"
-#include "coretypes.h"
-#include "tm.h"
-#include "defaults.h"
-#include "objc/thr.h"
-#include "objc/message.h" /* For objc_msg_lookup(). */
-#include "objc/runtime.h"
-#include "objc-private/module-abi-8.h"
-#include "objc-private/runtime.h"
-#include <gthr.h>
-
-#include <stdlib.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 runtime, but they are not
- considered part of the public interface. */
-
-/* Initialize the threads subsystem. */
-int
-__objc_init_thread_system(void)
-{
- return __gthread_objc_init_thread_system ();
-}
-
-/* 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 void __attribute__((noreturn))
-__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
- {
- /* FIXME: Should we abort here ? */
- _objc_abort ("objc_thread_detach called with bad selector.\n");
- }
- }
- else
- {
- /* FIXME: Should we abort here ? */
- _objc_abort ("objc_thread_detach called with NULL state.\n");
- }
-
- /* Exit the thread. */
- objc_thread_exit ();
-
- /* Make sure compiler detects no return. */
- __builtin_trap ();
-}
-
-/* Public functions.
-
- These functions constitute the public interface to the Objective-C
- thread and mutex functionality. */
-
-/* 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 = __gthread_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)
-{
- return __gthread_objc_thread_set_priority (priority);
-}
-
-/* Return the current thread's priority. */
-int
-objc_thread_get_priority (void)
-{
- return __gthread_objc_thread_get_priority ();
-}
-
-/* Yield our process time to another thread. 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)
-{
- __gthread_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 __gthread_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)
-{
- return __gthread_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)
-{
- return __gthread_objc_thread_set_data (value);
-}
-
-/* Returns the thread's local storage pointer. Returns NULL on
- failure. */
-void *
-objc_thread_get_data (void)
-{
- return __gthread_objc_thread_get_data ();
-}
-
-/* Public 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 (__gthread_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 (__gthread_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 = __gthread_objc_thread_id ();
- if (mutex->owner == thread_id)
- return ++mutex->depth;
-
- /* Call the backend to lock the mutex. */
- status = __gthread_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 = __gthread_objc_thread_id ();
- if (mutex->owner == thread_id)
- return ++mutex->depth;
-
- /* Call the backend to try to lock the mutex. */
- status = __gthread_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 = __gthread_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 = __gthread_objc_mutex_unlock (mutex);
-
- /* Failed? */
- if (status)
- return status;
-
- return 0;
-}
-
-/* Public 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 (__gthread_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 (__gthread_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 = __gthread_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. */
- __gthread_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 __gthread_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 __gthread_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);
-}
-