X-Git-Url: http://git.sourceforge.jp/view?a=blobdiff_plain;f=libobjc%2Fthr.c;h=a12aa2da010e6e393b4fcfc14deef5f13ef57b5f;hb=3ba0ce4759c71b0e9a0e516072a0cadcfe098765;hp=13a22a5685f2c18bba33480985ce974542eb61e3;hpb=6b3f2a74d740bdda4aa4f2f1b83408288a4b03c4;p=pf3gnuchains%2Fgcc-fork.git diff --git a/libobjc/thr.c b/libobjc/thr.c index 13a22a5685f..a12aa2da010 100644 --- a/libobjc/thr.c +++ b/libobjc/thr.c @@ -1,31 +1,30 @@ /* GNU Objective C Runtime Thread Interface - Copyright (C) 1996, 1997 Free Software Foundation, Inc. + Copyright (C) 1996, 1997, 2009 Free Software Foundation, Inc. Contributed by Galen C. Hunt (gchunt@cs.rochester.edu) -This file is part of GNU CC. +This file is part of GCC. -GNU CC is free software; you can redistribute it and/or modify it under the +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. -GNU CC is distributed in the hope that it will be useful, but WITHOUT ANY +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 -GNU CC; see the file COPYING. If not, write to the Free Software -Foundation, 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ +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 +. */ -/* 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 -#include "runtime.h" +#include "objc/runtime.h" /* Global exit status. */ int __objc_thread_exit_status = 0; @@ -48,7 +47,7 @@ objc_thread_callback _objc_became_multi_threaded = NULL; 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 objc_set_thread_callback (objc_thread_callback func) { objc_thread_callback temp = _objc_became_multi_threaded; _objc_became_multi_threaded = func; @@ -75,45 +74,48 @@ struct __objc_thread_start_state id argument; }; -static volatile void -__objc_thread_detach_function(struct __objc_thread_start_state *istate) +static void __attribute__((noreturn)) +__objc_thread_detach_function (struct __objc_thread_start_state *istate) { /* Valid state? */ if (istate) { - id (*imp)(id,SEL,id); + 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); + objc_free (istate); /* Clear out the thread local storage */ - objc_thread_set_data(NULL); + objc_thread_set_data (NULL); /* Check to see if we just became multi threaded */ - if (!__objc_is_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)(); + (*_objc_became_multi_threaded) (); } /* Call the method */ - if ((imp = (id(*)(id, SEL, id))objc_msg_lookup(object, selector))) - (*imp)(object, selector, argument); + 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"); + 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"); + objc_error (nil, OBJC_ERR_BAD_STATE, + "objc_thread_detach called with NULL state.\n"); /* Exit the thread */ - objc_thread_exit(); + objc_thread_exit (); + + /* Make sure compiler detects no return. */ + __builtin_trap (); } /* @@ -131,14 +133,14 @@ __objc_thread_detach_function(struct __objc_thread_start_state *istate) takes a single argument. */ objc_thread_t -objc_thread_detach(SEL selector, id object, id argument) +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)))) + if (! (istate = (struct __objc_thread_start_state *) + objc_malloc (sizeof (*istate)))) return NULL; /* Initialize the state structure */ @@ -147,39 +149,39 @@ objc_thread_detach(SEL selector, id object, id argument) istate->argument = argument; /* lock access */ - objc_mutex_lock(__objc_runtime_mutex); + 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 = __objc_thread_detach ((void *)__objc_thread_detach_function, + istate)) == NULL) { /* failed! */ - objc_mutex_unlock(__objc_runtime_mutex); - objc_free(istate); + 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); + objc_mutex_unlock (__objc_runtime_mutex); return thread_id; } /* Set the current thread's priority. */ int -objc_thread_set_priority(int priority) +objc_thread_set_priority (int priority) { /* Call the backend */ - return __objc_thread_set_priority(priority); + return __objc_thread_set_priority (priority); } /* Return the current thread's priority. */ int -objc_thread_get_priority(void) +objc_thread_get_priority (void) { /* Call the backend */ - return __objc_thread_get_priority(); + return __objc_thread_get_priority (); } /* @@ -188,10 +190,10 @@ objc_thread_get_priority(void) make progress even on a lazy uniprocessor system. */ void -objc_thread_yield(void) +objc_thread_yield (void) { /* Call the backend */ - __objc_thread_yield(); + __objc_thread_yield (); } /* @@ -199,15 +201,15 @@ objc_thread_yield(void) Actually, if it failed returns -1. */ int -objc_thread_exit(void) +objc_thread_exit (void) { /* Decrement our counter of the number of threads alive */ - objc_mutex_lock(__objc_runtime_mutex); + objc_mutex_lock (__objc_runtime_mutex); __objc_runtime_threads_alive--; - objc_mutex_unlock(__objc_runtime_mutex); + objc_mutex_unlock (__objc_runtime_mutex); /* Call the backend to terminate the thread */ - return __objc_thread_exit(); + return __objc_thread_exit (); } /* @@ -215,10 +217,10 @@ objc_thread_exit(void) NULL which is reserved as a marker for "no thread". */ objc_thread_t -objc_thread_id(void) +objc_thread_id (void) { /* Call the backend */ - return __objc_thread_id(); + return __objc_thread_id (); } /* @@ -226,20 +228,20 @@ objc_thread_id(void) Returns 0 if successful or -1 if failed. */ int -objc_thread_set_data(void *value) +objc_thread_set_data (void *value) { /* Call the backend */ - return __objc_thread_set_data(value); + return __objc_thread_set_data (value); } /* Returns the thread's local storage pointer. Returns NULL on failure. */ void * -objc_thread_get_data(void) +objc_thread_get_data (void) { /* Call the backend */ - return __objc_thread_get_data(); + return __objc_thread_get_data (); } /* Frontend mutex functions */ @@ -249,19 +251,19 @@ objc_thread_get_data(void) allocation failed for any reason. */ objc_mutex_t -objc_mutex_allocate(void) +objc_mutex_allocate (void) { objc_mutex_t mutex; /* Allocate the mutex structure */ - if (!(mutex = (objc_mutex_t)objc_malloc(sizeof(struct objc_mutex)))) + if (! (mutex = (objc_mutex_t)objc_malloc (sizeof (struct objc_mutex)))) return NULL; /* Call backend to create the mutex */ - if (__objc_mutex_allocate(mutex)) + if (__objc_mutex_allocate (mutex)) { /* failed! */ - objc_free(mutex); + objc_free (mutex); return NULL; } @@ -279,23 +281,23 @@ 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; /* Valid mutex? */ - if (!mutex) + if (! mutex) return -1; /* Acquire lock on mutex */ - depth = objc_mutex_lock(mutex); + depth = objc_mutex_lock (mutex); /* Call backend to destroy mutex */ - if (__objc_mutex_deallocate(mutex)) + if (__objc_mutex_deallocate (mutex)) return -1; /* Free the mutex structure */ - objc_free(mutex); + objc_free (mutex); /* Return last depth */ return depth; @@ -308,22 +310,22 @@ 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; int status; /* Valid mutex? */ - if (!mutex) + if (! mutex) return -1; /* If we already own the lock then increment depth */ - thread_id = __objc_thread_id(); + 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); + status = __objc_mutex_lock (mutex); /* Failed? */ if (status) @@ -340,22 +342,22 @@ 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; int status; /* Valid mutex? */ - if (!mutex) + if (! mutex) return -1; /* If we already own the lock then increment depth */ - thread_id = __objc_thread_id(); + 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); + status = __objc_mutex_trylock (mutex); /* Failed? */ if (status) @@ -375,17 +377,17 @@ objc_mutex_trylock(objc_mutex_t mutex) doesn't hold in which case return -1 and the mutex is unaffected. */ int -objc_mutex_unlock(objc_mutex_t mutex) +objc_mutex_unlock (objc_mutex_t mutex) { objc_thread_t thread_id; int status; /* Valid mutex? */ - if (!mutex) + if (! mutex) return -1; /* If another thread owns the lock then abort */ - thread_id = __objc_thread_id(); + thread_id = __objc_thread_id (); if (mutex->owner != thread_id) return -1; @@ -398,7 +400,7 @@ objc_mutex_unlock(objc_mutex_t mutex) mutex->owner = NULL; /* Have the backend unlock the mutex */ - status = __objc_mutex_unlock(mutex); + status = __objc_mutex_unlock (mutex); /* Failed? */ if (status) @@ -414,20 +416,20 @@ objc_mutex_unlock(objc_mutex_t mutex) if the allocation failed for any reason. */ objc_condition_t -objc_condition_allocate(void) +objc_condition_allocate (void) { objc_condition_t condition; /* Allocate the condition mutex structure */ - if (!(condition = - (objc_condition_t)objc_malloc(sizeof(struct objc_condition)))) + 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)) + if (__objc_condition_allocate (condition)) { /* failed! */ - objc_free(condition); + objc_free (condition); return NULL; } @@ -443,41 +445,41 @@ objc_condition_allocate(void) waiting but just wake them up. */ int -objc_condition_deallocate(objc_condition_t condition) +objc_condition_deallocate (objc_condition_t condition) { /* Broadcast the condition */ - if (objc_condition_broadcast(condition)) + if (objc_condition_broadcast (condition)) return -1; /* Call the backend to destroy */ - if (__objc_condition_deallocate(condition)) + if (__objc_condition_deallocate (condition)) return -1; /* Free the condition mutex structure */ - objc_free(condition); + 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 + 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_condition_wait (objc_condition_t condition, objc_mutex_t mutex) { objc_thread_t thread_id; /* Valid arguments? */ - if (!mutex || !condition) + if (! mutex || ! condition) return -1; /* Make sure we are owner of mutex */ - thread_id = __objc_thread_id(); + thread_id = __objc_thread_id (); if (mutex->owner != thread_id) return -1; @@ -490,7 +492,7 @@ objc_condition_wait(objc_condition_t condition, objc_mutex_t mutex) mutex->owner = (objc_thread_t)NULL; /* Call the backend to wait */ - __objc_condition_wait(condition, mutex); + __objc_condition_wait (condition, mutex); /* Make ourselves owner of the mutex */ mutex->owner = thread_id; @@ -506,13 +508,13 @@ objc_condition_wait(objc_condition_t condition, objc_mutex_t mutex) right away after this call. */ int -objc_condition_broadcast(objc_condition_t condition) +objc_condition_broadcast (objc_condition_t condition) { /* Valid condition mutex? */ - if (!condition) + if (! condition) return -1; - return __objc_condition_broadcast(condition); + return __objc_condition_broadcast (condition); } /* @@ -522,42 +524,42 @@ objc_condition_broadcast(objc_condition_t condition) right away after this call. */ int -objc_condition_signal(objc_condition_t condition) +objc_condition_signal (objc_condition_t condition) { /* Valid condition mutex? */ - if (!condition) + if (! condition) return -1; - return __objc_condition_signal(condition); + 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 + 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_thread_add (void) { - objc_mutex_lock(__objc_runtime_mutex); + objc_mutex_lock (__objc_runtime_mutex); __objc_is_multi_threaded = 1; __objc_runtime_threads_alive++; - objc_mutex_unlock(__objc_runtime_mutex); + 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 + objc_thread_remove () when your alien thread is done with making calls to Objective-C. */ void -objc_thread_remove(void) +objc_thread_remove (void) { - objc_mutex_lock(__objc_runtime_mutex); + objc_mutex_lock (__objc_runtime_mutex); __objc_runtime_threads_alive--; - objc_mutex_unlock(__objc_runtime_mutex); + objc_mutex_unlock (__objc_runtime_mutex); } /* End of File */