/* GNU Objective C Runtime Thread Interface
- Copyright (C) 1996, 1997 Free Software Foundation, Inc.
+ 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 2, or (at your option) any later version.
+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.
-You should have received a copy of the GNU General Public License along with
-GCC; 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. */
+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/runtime.h"
+#include "objc-private/runtime.h"
+#include <gthr.h>
#include <stdlib.h>
-#include "objc/runtime.h"
/* Global exit status. */
int __objc_thread_exit_status = 0;
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.
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");
+ {
+ /* FIXME: Should we abort here ? */
+ _objc_abort ("objc_thread_detach called with bad selector.\n");
+ }
}
else
- objc_error (nil, OBJC_ERR_BAD_STATE,
- "objc_thread_detach called with NULL state.\n");
+ {
+ /* 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 ();
}
/*
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)
+ if ((thread_id = __gthread_objc_thread_detach ((void *)__objc_thread_detach_function,
+ istate)) == NULL)
{
/* failed! */
objc_mutex_unlock (__objc_runtime_mutex);
objc_thread_set_priority (int priority)
{
/* Call the backend */
- return __objc_thread_set_priority (priority);
+ return __gthread_objc_thread_set_priority (priority);
}
/* Return the current thread's priority. */
objc_thread_get_priority (void)
{
/* Call the backend */
- return __objc_thread_get_priority ();
+ return __gthread_objc_thread_get_priority ();
}
/*
objc_thread_yield (void)
{
/* Call the backend */
- __objc_thread_yield ();
+ __gthread_objc_thread_yield ();
}
/*
objc_mutex_unlock (__objc_runtime_mutex);
/* Call the backend to terminate the thread */
- return __objc_thread_exit ();
+ return __gthread_objc_thread_exit ();
}
/*
objc_thread_id (void)
{
/* Call the backend */
- return __objc_thread_id ();
+ return __gthread_objc_thread_id ();
}
/*
objc_thread_set_data (void *value)
{
/* Call the backend */
- return __objc_thread_set_data (value);
+ return __gthread_objc_thread_set_data (value);
}
/*
objc_thread_get_data (void)
{
/* Call the backend */
- return __objc_thread_get_data ();
+ return __gthread_objc_thread_get_data ();
}
/* Frontend mutex functions */
return NULL;
/* Call backend to create the mutex */
- if (__objc_mutex_allocate (mutex))
+ if (__gthread_objc_mutex_allocate (mutex))
{
/* failed! */
objc_free (mutex);
depth = objc_mutex_lock (mutex);
/* Call backend to destroy mutex */
- if (__objc_mutex_deallocate (mutex))
+ if (__gthread_objc_mutex_deallocate (mutex))
return -1;
/* Free the mutex structure */
return -1;
/* If we already own the lock then increment depth */
- thread_id = __objc_thread_id ();
+ thread_id = __gthread_objc_thread_id ();
if (mutex->owner == thread_id)
return ++mutex->depth;
/* Call the backend to lock the mutex */
- status = __objc_mutex_lock (mutex);
+ status = __gthread_objc_mutex_lock (mutex);
/* Failed? */
if (status)
return -1;
/* If we already own the lock then increment depth */
- thread_id = __objc_thread_id ();
+ thread_id = __gthread_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);
+ status = __gthread_objc_mutex_trylock (mutex);
/* Failed? */
if (status)
return -1;
/* If another thread owns the lock then abort */
- thread_id = __objc_thread_id ();
+ thread_id = __gthread_objc_thread_id ();
if (mutex->owner != thread_id)
return -1;
mutex->owner = NULL;
/* Have the backend unlock the mutex */
- status = __objc_mutex_unlock (mutex);
+ status = __gthread_objc_mutex_unlock (mutex);
/* Failed? */
if (status)
return NULL;
/* Call the backend to create the condition mutex */
- if (__objc_condition_allocate (condition))
+ if (__gthread_objc_condition_allocate (condition))
{
/* failed! */
objc_free (condition);
return -1;
/* Call the backend to destroy */
- if (__objc_condition_deallocate (condition))
+ if (__gthread_objc_condition_deallocate (condition))
return -1;
/* Free the condition mutex structure */
return -1;
/* Make sure we are owner of mutex */
- thread_id = __objc_thread_id ();
+ thread_id = __gthread_objc_thread_id ();
if (mutex->owner != thread_id)
return -1;
mutex->owner = (objc_thread_t)NULL;
/* Call the backend to wait */
- __objc_condition_wait (condition, mutex);
+ __gthread_objc_condition_wait (condition, mutex);
/* Make ourselves owner of the mutex */
mutex->owner = thread_id;
if (! condition)
return -1;
- return __objc_condition_broadcast (condition);
+ return __gthread_objc_condition_broadcast (condition);
}
/*
if (! condition)
return -1;
- return __objc_condition_signal (condition);
+ return __gthread_objc_condition_signal (condition);
}
/* Make the objc thread system aware that a thread which is managed