Home | History | Annotate | Line # | Download | only in libobjc
      1 This file describes in little detail the modifications to the
      2 Objective-C runtime needed to make it thread safe. 
      3 
      4 First off, kudos to Galen Hunt who is the author of this great work.
      5 
      6 If you have an comments or just want to know where to
      7 send me money to express your undying gratitude for threading the
      8 Objective-C runtime you can reach Galen at:
      9 
     10 	gchunt (a] cs.rochester.edu
     11 
     12 Any questions, comments, bug reports, etc. should send email either to the
     13 GCC bug account or to:
     14 
     15 	Scott Christley <scottc (a] net-community.com>
     16 
     17 * Sarray Threading:
     18 
     19 The most critical component of the Objective-C runtime is the sparse array
     20 structure (sarray).  Sarrays store object selectors and implementations.  
     21 Following in the tradition of the Objective-C runtime, my threading
     22 support assumes that fast message dispatching is far more important
     23 than *ANY* and *ALL* other operations.  The message dispatching thus
     24 uses *NO* locks on any kind.  In fact, if you look in sarray.h, you
     25 will notice that the message dispatching has not been modified.
     26 Instead, I have modified the sarray management functions so that all
     27 updates to the sarray data structure can be made in parallel will
     28 message dispatching.  
     29 
     30 To support concurrent message dispatching, no dynamically allocated
     31 sarray data structures are freed while more than one thread is
     32 operational.  Sarray data structures that are no longer in use are
     33 kept in a linked list of garbage and are released whenever the program
     34 is operating with a single thread.  The programmer can also flush the 
     35 garbage list by calling sarray_remove_garbage when the programmer can
     36 ensure that no message dispatching is taking place concurrently.  The
     37 amount of un-reclaimed sarray garbage should normally be extremely
     38 small in a real program as sarray structures are freed only when using
     39 the "poseAs" functionality and early in program initialization, which
     40 normally occurs while the program is single threaded.
     41 
     42 ******************************************************************************
     43 * Static Variables:
     44 
     45 The following variables are either statically or globally defined. This list 
     46 does not include variables which are internal to implementation dependent 
     47 versions of thread-*.c.
     48 
     49 The following threading designations are used:
     50 	SAFE   : Implicitly thread safe.
     51 	SINGLE : Must only be used in single thread mode.
     52 	MUTEX  : Protected by single global mutex objc_runtime_mutex.
     53 	UNUSED : Not used in the runtime.
     54 
     55 Variable Name:			Usage:  Defined:	Also used in:
     56 ===========================	======	============	=====================
     57 __objc_class_hash		MUTEX	class.c
     58 __objc_class_links_resolved	UNUSED	class.c		runtime.h
     59 __objc_class_number		MUTEX	class.c
     60 __objc_dangling_categories	UNUSED	init.c
     61 __objc_module_list		MUTEX	init.c
     62 __objc_selector_array		MUTEX	selector.c
     63 __objc_selector_hash		MUTEX	selector.c
     64 __objc_selector_max_index	MUTEX	selector.c	sendmsg.c runtime.h
     65 __objc_selector_names		MUTEX	selector.c
     66 __objc_thread_exit_status	SAFE	thread.c
     67 __objc_uninstalled_dtable	MUTEX	sendmsg.c	selector.c
     68 _objc_load_callback		SAFE	init.c		objc-api.h
     69 _objc_lookup_class		SAFE	class.c		objc-api.h
     70 _objc_object_alloc		SINGLE	objects.c	objc-api.h
     71 _objc_object_copy		SINGLE	objects.c	objc-api.h
     72 _objc_object_dispose		SINGLE	objects.c	objc-api.h
     73 frwd_sel			SAFE2	sendmsg.c
     74 idxsize				MUTEX	sarray.c	sendmsg.c sarray.h
     75 initialize_sel			SAFE2	sendmsg.c
     76 narrays				MUTEX	sarray.c	sendmsg.c sarray.h
     77 nbuckets			MUTEX	sarray.c	sendmsg.c sarray.h
     78 nindices			MUTEX	sarray.c	sarray.h
     79 previous_constructors		SAFE1	init.c
     80 proto_class			SAFE1	init.c
     81 unclaimed_categories		MUTEX	init.c
     82 unclaimed_proto_list		MUTEX	init.c
     83 uninitialized_statics		MUTEX	init.c
     84 
     85 Notes:
     86 1) Initialized once in unithread mode.
     87 2) Initialized value will always be same, guaranteed by lock on selector 
     88    hash table.
     89 
     90 
     91 ******************************************************************************
     92 * Frontend/Backend design:
     93 
     94 The design of the Objective-C runtime thread and mutex functions utilizes a
     95 frontend/backend implementation.
     96 
     97 The frontend, as characterized by the files thr.h and thr.c, is a set
     98 of platform independent structures and functions which represent the
     99 user interface.  For example, objc_mutex_lock().  Objective-C programs
    100 should use these structures and functions for their thread and mutex
    101 work if they wish to maintain a high degree of portability across
    102 platforms.
    103 
    104 The backend is currently GCC's gthread code (gthr.h and related).  For
    105 example, __gthread_objc_mutex_lock().  The thread system is
    106 automatically configured when GCC is configured.  On most platforms
    107 this thread backend is able to automatically switch to non-multi-threaded
    108 mode if the threading library is not linked in.
    109 
    110 If you want to compile libobjc standalone, then you would need to modify
    111 the configure.ac and makefiles for it and you need to import the
    112 gthread code from GCC.
    113 
    114 ******************************************************************************
    115 * Threads:
    116 
    117 The thread system attempts to create multiple threads using whatever
    118 operating system or library thread support is available.  It does
    119 assume that all system functions are thread safe.  Notably this means
    120 that the system implementation of malloc and free must be thread safe.
    121 If a system has multiple processors, the threads are configured for
    122 full parallel processing.
    123 
    124 * Backend initialization functions
    125 
    126 __objc_init_thread_system(void), int
    127 	Initialize the thread subsystem.  Called once by __objc_exec_class.
    128 	Return -1 if error otherwise return 0.
    129 
    130 __objc_close_thread_system(void), int
    131 	Closes the thread subsystem, not currently guaranteed to be called.
    132 	Return -1 if error otherwise return 0.
    133 
    134 *****
    135 * Frontend thread functions
    136 * User programs should use these functions.
    137 
    138 objc_thread_detach(SEL selector, id object, id argument), objc_thread_t
    139 	Creates and detaches a new thread.  The new thread starts by
    140 	sending the given selector with a single argument to the
    141 	given object.
    142 
    143 objc_thread_set_priority(int priority), int
    144 	Sets a thread's relative priority within the program.  Valid
    145 	options are:
    146 	
    147 	OBJC_THREAD_INTERACTIVE_PRIORITY
    148 	OBJC_THREAD_BACKGROUND_PRIORITY
    149 	OBJC_THREAD_LOW_PRIORITY
    150 
    151 objc_thread_get_priority(void), int
    152 	Query a thread's priority.
    153 
    154 objc_thread_yield(void), void
    155 	Yields processor to another thread with equal or higher
    156 	priority.  It is up to the system scheduler to determine if
    157 	the processor is taken or not.
    158 
    159 objc_thread_exit(void), int
    160 	Terminates a thread.  If this is the last thread executing
    161 	then the program will terminate.
    162 
    163 objc_thread_id(void), int
    164 	Returns the current thread's id.
    165 
    166 objc_thread_set_data(void *value), int
    167 	Set a pointer to the thread's local storage.  Local storage is
    168 	thread specific.
    169 
    170 objc_thread_get_data(void), void *
    171 	Returns the pointer to the thread's local storage.
    172 
    173 *****
    174 * Backend thread functions
    175 * User programs should *NOT* directly call these functions.
    176 
    177 __gthr_objc_thread_detach(void (*func)(void *arg), void *arg), objc_thread_t
    178 	Spawns a new thread executing func, called by objc_thread_detach.
    179 	Return NULL if error otherwise return thread id.
    180 
    181 __gthr_objc_thread_set_priority(int priority), int
    182 	Set the thread's priority, called by objc_thread_set_priority.
    183 	Return -1 if error otherwise return 0.
    184 
    185 __gthr_objc_thread_get_priority(void), int
    186 	Query a thread's priority, called by objc_thread_get_priority.
    187 	Return -1 if error otherwise return the priority.
    188 
    189 __gthr_objc_thread_yield(void), void
    190 	Yields the processor, called by objc_thread_yield.
    191 
    192 __gthr_objc_thread_exit(void), int
    193 	Terminates the thread, called by objc_thread_exit.
    194 	Return -1 if error otherwise function does not return.
    195 
    196 __gthr_objc_thread_id(void), objc_thread_t
    197 	Returns the current thread's id, called by objc_thread_id.
    198 	Return -1 if error otherwise return thread id.
    199 
    200 __gthr_objc_thread_set_data(void *value), int
    201 	Set pointer for thread local storage, called by objc_thread_set_data.
    202 	Returns -1 if error otherwise return 0.
    203 
    204 __gthr_objc_thread_get_data(void), void *
    205 	Returns the pointer to the thread's local storage.
    206 	Returns NULL if error, called by objc_thread_get_data.
    207 
    208 
    209 ******************************************************************************
    210 * Mutexes:
    211 
    212 Mutexes can be locked recursively.  Each locked mutex remembers
    213 its owner (by thread id) and how many times it has been locked.  The
    214 last unlock on a mutex removes the system lock and allows other
    215 threads to access the mutex.
    216 
    217 *****
    218 * Frontend mutex functions
    219 * User programs should use these functions.
    220 
    221 objc_mutex_allocate(void), objc_mutex_t
    222 	Allocates a new mutex.  Mutex is initially unlocked.
    223 	Return NULL if error otherwise return mutex pointer.
    224 
    225 objc_mutex_deallocate(objc_mutex_t mutex), int
    226 	Free a mutex.  Before freeing the mutex, makes sure that no
    227 	one else is using it.
    228 	Return -1 if error otherwise return 0.
    229 
    230 objc_mutex_lock(objc_mutex_t mutex), int
    231 	Locks a mutex.  As mentioned earlier, the same thread may call
    232 	this routine repeatedly.
    233 	Return -1 if error otherwise return 0.
    234 	
    235 objc_mutex_trylock(objc_mutex_t mutex), int
    236 	Attempts to lock a mutex.  If lock on mutex can be acquired 
    237 	then function operates exactly as objc_mutex_lock.
    238 	Return -1 if failed to acquire lock otherwise return 0.
    239 
    240 objc_mutex_unlock(objc_mutex_t mutex), int
    241 	Unlocks the mutex by one level.  Other threads may not acquire
    242 	the mutex until this thread has released all locks on it.
    243 	Return -1 if error otherwise return 0.
    244 
    245 *****
    246 * Backend mutex functions
    247 * User programs should *NOT* directly call these functions.
    248 
    249 __gthr_objc_mutex_allocate(objc_mutex_t mutex), int
    250 	Allocates a new mutex, called by objc_mutex_allocate.
    251 	Return -1 if error otherwise return 0.
    252 
    253 __gthr_objc_mutex_deallocate(objc_mutex_t mutex), int
    254 	Free a mutex, called by objc_mutex_deallocate.
    255 	Return -1 if error otherwise return 0.
    256 
    257 __gthr_objc_mutex_lock(objc_mutex_t mutex), int
    258 	Locks a mutex, called by objc_mutex_lock.
    259 	Return -1 if error otherwise return 0.
    260 	
    261 __gthr_objc_mutex_trylock(objc_mutex_t mutex), int
    262 	Attempts to lock a mutex, called by objc_mutex_trylock.
    263 	Return -1 if failed to acquire lock or error otherwise return 0.
    264 
    265 __gthr_objc_mutex_unlock(objc_mutex_t mutex), int
    266 	Unlocks the mutex, called by objc_mutex_unlock.
    267 	Return -1 if error otherwise return 0.
    268 
    269 ******************************************************************************
    270 * Condition Mutexes:
    271 
    272 Mutexes can be locked recursively.  Each locked mutex remembers
    273 its owner (by thread id) and how many times it has been locked.  The
    274 last unlock on a mutex removes the system lock and allows other
    275 threads to access the mutex.
    276 
    277 *
    278 * Frontend condition mutex functions
    279 * User programs should use these functions.
    280 *
    281 
    282 objc_condition_allocate(void), objc_condition_t 
    283 	Allocate a condition mutex.
    284 	Return NULL if error otherwise return condition pointer.
    285 
    286 objc_condition_deallocate(objc_condition_t condition), int
    287 	Deallocate a condition. Note that this includes an implicit
    288 	condition_broadcast to insure that waiting threads have the 
    289 	opportunity to wake.  It is legal to dealloc a condition only
    290 	if no other thread is/will be using it. Does NOT check for
    291 	other threads waiting but just wakes them up.
    292 	Return -1 if error otherwise return 0.
    293 
    294 objc_condition_wait(objc_condition_t condition, objc_mutex_t mutex), int
    295 	Wait on the condition unlocking the mutex until objc_condition_signal()
    296 	or objc_condition_broadcast() are called for the same condition. The
    297 	given mutex *must* have the depth 1 so that it can be unlocked
    298 	here, for someone else can lock it and signal/broadcast the condition.
    299 	The mutex is used to lock access to the shared data that make up the
    300 	"condition" predicate.
    301 	Return -1 if error otherwise return 0.
    302 	
    303 objc_condition_broadcast(objc_condition_t condition), int
    304 	Wake up all threads waiting on this condition. It is recommended that 
    305 	the called would lock the same mutex as the threads in
    306 	objc_condition_wait before changing the "condition predicate"
    307 	and make this call and unlock it right away after this call.
    308 	Return -1 if error otherwise return 0.
    309 
    310 objc_condition_signal(objc_condition_t condition), int
    311 	Wake up one thread waiting on this condition.
    312 	Return -1 if error otherwise return 0.
    313 
    314 *
    315 * Backend condition mutex functions
    316 * User programs should *NOT* directly call these functions.
    317 *
    318 
    319 __gthr_objc_condition_allocate(objc_condition_t condition), int
    320 	Allocate a condition mutex, called by objc_condition_allocate.
    321 	Return -1 if error otherwise return 0.
    322 
    323 __gthr_objc_condition_deallocate(objc_condition_t condition), int
    324 	Deallocate a condition, called by objc_condition_deallocate.
    325 	Return -1 if error otherwise return 0.
    326 
    327 __gthr_objc_condition_wait(objc_condition_t condition, objc_mutex_t mutex), int
    328 	Wait on the condition, called by objc_condition_wait.
    329 	Return -1 if error otherwise return 0 when condition is met.
    330 	
    331 __gthr_objc_condition_broadcast(objc_condition_t condition), int
    332 	Wake up all threads waiting on this condition.
    333 	Called by objc_condition_broadcast.
    334 	Return -1 if error otherwise return 0.
    335 
    336 __gthr_objc_condition_signal(objc_condition_t condition), int
    337 	Wake up one thread waiting on this condition.
    338 	Called by objc_condition_signal.
    339 	Return -1 if error otherwise return 0.
    340