xref: /netbsd-src/external/gpl3/gcc/dist/libobjc/THREADS (revision f9a78e0e885f664fa1b5fd1637673b39c1aa53b3)
14fee23f9SmrgThis file describes in little detail the modifications to the
24fee23f9SmrgObjective-C runtime needed to make it thread safe.
34fee23f9Smrg
44fee23f9SmrgFirst off, kudos to Galen Hunt who is the author of this great work.
54fee23f9Smrg
64fee23f9SmrgIf you have an comments or just want to know where to
74fee23f9Smrgsend me money to express your undying gratitude for threading the
84fee23f9SmrgObjective-C runtime you can reach Galen at:
94fee23f9Smrg
104fee23f9Smrg	gchunt@cs.rochester.edu
114fee23f9Smrg
124fee23f9SmrgAny questions, comments, bug reports, etc. should send email either to the
134fee23f9SmrgGCC bug account or to:
144fee23f9Smrg
154fee23f9Smrg	Scott Christley <scottc@net-community.com>
164fee23f9Smrg
174fee23f9Smrg* Sarray Threading:
184fee23f9Smrg
194fee23f9SmrgThe most critical component of the Objective-C runtime is the sparse array
204fee23f9Smrgstructure (sarray).  Sarrays store object selectors and implementations.
214fee23f9SmrgFollowing in the tradition of the Objective-C runtime, my threading
224fee23f9Smrgsupport assumes that fast message dispatching is far more important
234fee23f9Smrgthan *ANY* and *ALL* other operations.  The message dispatching thus
244fee23f9Smrguses *NO* locks on any kind.  In fact, if you look in sarray.h, you
254fee23f9Smrgwill notice that the message dispatching has not been modified.
264fee23f9SmrgInstead, I have modified the sarray management functions so that all
274fee23f9Smrgupdates to the sarray data structure can be made in parallel will
284fee23f9Smrgmessage dispatching.
294fee23f9Smrg
304fee23f9SmrgTo support concurrent message dispatching, no dynamically allocated
314fee23f9Smrgsarray data structures are freed while more than one thread is
324fee23f9Smrgoperational.  Sarray data structures that are no longer in use are
334fee23f9Smrgkept in a linked list of garbage and are released whenever the program
344fee23f9Smrgis operating with a single thread.  The programmer can also flush the
354fee23f9Smrggarbage list by calling sarray_remove_garbage when the programmer can
364fee23f9Smrgensure that no message dispatching is taking place concurrently.  The
374fee23f9Smrgamount of un-reclaimed sarray garbage should normally be extremely
384fee23f9Smrgsmall in a real program as sarray structures are freed only when using
394fee23f9Smrgthe "poseAs" functionality and early in program initialization, which
404fee23f9Smrgnormally occurs while the program is single threaded.
414fee23f9Smrg
424fee23f9Smrg******************************************************************************
434fee23f9Smrg* Static Variables:
444fee23f9Smrg
454fee23f9SmrgThe following variables are either statically or globally defined. This list
464fee23f9Smrgdoes not include variables which are internal to implementation dependent
474fee23f9Smrgversions of thread-*.c.
484fee23f9Smrg
494fee23f9SmrgThe following threading designations are used:
504fee23f9Smrg	SAFE   : Implicitly thread safe.
514fee23f9Smrg	SINGLE : Must only be used in single thread mode.
524fee23f9Smrg	MUTEX  : Protected by single global mutex objc_runtime_mutex.
534fee23f9Smrg	UNUSED : Not used in the runtime.
544fee23f9Smrg
554fee23f9SmrgVariable Name:			Usage:  Defined:	Also used in:
564fee23f9Smrg===========================	======	============	=====================
574fee23f9Smrg__objc_class_hash		MUTEX	class.c
584fee23f9Smrg__objc_class_links_resolved	UNUSED	class.c		runtime.h
594fee23f9Smrg__objc_class_number		MUTEX	class.c
604fee23f9Smrg__objc_dangling_categories	UNUSED	init.c
614fee23f9Smrg__objc_module_list		MUTEX	init.c
624fee23f9Smrg__objc_selector_array		MUTEX	selector.c
634fee23f9Smrg__objc_selector_hash		MUTEX	selector.c
644fee23f9Smrg__objc_selector_max_index	MUTEX	selector.c	sendmsg.c runtime.h
654fee23f9Smrg__objc_selector_names		MUTEX	selector.c
664fee23f9Smrg__objc_thread_exit_status	SAFE	thread.c
674fee23f9Smrg__objc_uninstalled_dtable	MUTEX	sendmsg.c	selector.c
684fee23f9Smrg_objc_load_callback		SAFE	init.c		objc-api.h
694fee23f9Smrg_objc_lookup_class		SAFE	class.c		objc-api.h
704fee23f9Smrg_objc_object_alloc		SINGLE	objects.c	objc-api.h
714fee23f9Smrg_objc_object_copy		SINGLE	objects.c	objc-api.h
724fee23f9Smrg_objc_object_dispose		SINGLE	objects.c	objc-api.h
734fee23f9Smrgfrwd_sel			SAFE2	sendmsg.c
744fee23f9Smrgidxsize				MUTEX	sarray.c	sendmsg.c sarray.h
754fee23f9Smrginitialize_sel			SAFE2	sendmsg.c
764fee23f9Smrgnarrays				MUTEX	sarray.c	sendmsg.c sarray.h
774fee23f9Smrgnbuckets			MUTEX	sarray.c	sendmsg.c sarray.h
784fee23f9Smrgnindices			MUTEX	sarray.c	sarray.h
794fee23f9Smrgprevious_constructors		SAFE1	init.c
804fee23f9Smrgproto_class			SAFE1	init.c
814fee23f9Smrgunclaimed_categories		MUTEX	init.c
824fee23f9Smrgunclaimed_proto_list		MUTEX	init.c
834fee23f9Smrguninitialized_statics		MUTEX	init.c
844fee23f9Smrg
854fee23f9SmrgNotes:
864fee23f9Smrg1) Initialized once in unithread mode.
874fee23f9Smrg2) Initialized value will always be same, guaranteed by lock on selector
884fee23f9Smrg   hash table.
894fee23f9Smrg
904fee23f9Smrg
914fee23f9Smrg******************************************************************************
924fee23f9Smrg* Frontend/Backend design:
934fee23f9Smrg
944fee23f9SmrgThe design of the Objective-C runtime thread and mutex functions utilizes a
954fee23f9Smrgfrontend/backend implementation.
964fee23f9Smrg
974fee23f9SmrgThe frontend, as characterized by the files thr.h and thr.c, is a set
984fee23f9Smrgof platform independent structures and functions which represent the
9948fb7bfaSmrguser interface.  For example, objc_mutex_lock().  Objective-C programs
10048fb7bfaSmrgshould use these structures and functions for their thread and mutex
10148fb7bfaSmrgwork if they wish to maintain a high degree of portability across
10248fb7bfaSmrgplatforms.
1034fee23f9Smrg
10448fb7bfaSmrgThe backend is currently GCC's gthread code (gthr.h and related).  For
10548fb7bfaSmrgexample, __gthread_objc_mutex_lock().  The thread system is
10648fb7bfaSmrgautomatically configured when GCC is configured.  On most platforms
10748fb7bfaSmrgthis thread backend is able to automatically switch to non-multi-threaded
10848fb7bfaSmrgmode if the threading library is not linked in.
1094fee23f9Smrg
11048fb7bfaSmrgIf you want to compile libobjc standalone, then you would need to modify
111*f9a78e0eSmrgthe configure.ac and makefiles for it and you need to import the
11248fb7bfaSmrggthread code from GCC.
1134fee23f9Smrg
1144fee23f9Smrg******************************************************************************
1154fee23f9Smrg* Threads:
1164fee23f9Smrg
1174fee23f9SmrgThe thread system attempts to create multiple threads using whatever
1184fee23f9Smrgoperating system or library thread support is available.  It does
1194fee23f9Smrgassume that all system functions are thread safe.  Notably this means
1204fee23f9Smrgthat the system implementation of malloc and free must be thread safe.
1214fee23f9SmrgIf a system has multiple processors, the threads are configured for
1224fee23f9Smrgfull parallel processing.
1234fee23f9Smrg
1244fee23f9Smrg* Backend initialization functions
1254fee23f9Smrg
1264fee23f9Smrg__objc_init_thread_system(void), int
1274fee23f9Smrg	Initialize the thread subsystem.  Called once by __objc_exec_class.
1284fee23f9Smrg	Return -1 if error otherwise return 0.
1294fee23f9Smrg
1304fee23f9Smrg__objc_close_thread_system(void), int
1314fee23f9Smrg	Closes the thread subsystem, not currently guaranteed to be called.
1324fee23f9Smrg	Return -1 if error otherwise return 0.
1334fee23f9Smrg
1344fee23f9Smrg*****
1354fee23f9Smrg* Frontend thread functions
1364fee23f9Smrg* User programs should use these functions.
1374fee23f9Smrg
1384fee23f9Smrgobjc_thread_detach(SEL selector, id object, id argument), objc_thread_t
1394fee23f9Smrg	Creates and detaches a new thread.  The new thread starts by
1404fee23f9Smrg	sending the given selector with a single argument to the
1414fee23f9Smrg	given object.
1424fee23f9Smrg
1434fee23f9Smrgobjc_thread_set_priority(int priority), int
1444fee23f9Smrg	Sets a thread's relative priority within the program.  Valid
1454fee23f9Smrg	options are:
1464fee23f9Smrg
1474fee23f9Smrg	OBJC_THREAD_INTERACTIVE_PRIORITY
1484fee23f9Smrg	OBJC_THREAD_BACKGROUND_PRIORITY
1494fee23f9Smrg	OBJC_THREAD_LOW_PRIORITY
1504fee23f9Smrg
1514fee23f9Smrgobjc_thread_get_priority(void), int
1524fee23f9Smrg	Query a thread's priority.
1534fee23f9Smrg
1544fee23f9Smrgobjc_thread_yield(void), void
1554fee23f9Smrg	Yields processor to another thread with equal or higher
1564fee23f9Smrg	priority.  It is up to the system scheduler to determine if
1574fee23f9Smrg	the processor is taken or not.
1584fee23f9Smrg
1594fee23f9Smrgobjc_thread_exit(void), int
1604fee23f9Smrg	Terminates a thread.  If this is the last thread executing
1614fee23f9Smrg	then the program will terminate.
1624fee23f9Smrg
1634fee23f9Smrgobjc_thread_id(void), int
1644fee23f9Smrg	Returns the current thread's id.
1654fee23f9Smrg
1664fee23f9Smrgobjc_thread_set_data(void *value), int
1674fee23f9Smrg	Set a pointer to the thread's local storage.  Local storage is
1684fee23f9Smrg	thread specific.
1694fee23f9Smrg
1704fee23f9Smrgobjc_thread_get_data(void), void *
1714fee23f9Smrg	Returns the pointer to the thread's local storage.
1724fee23f9Smrg
1734fee23f9Smrg*****
1744fee23f9Smrg* Backend thread functions
1754fee23f9Smrg* User programs should *NOT* directly call these functions.
1764fee23f9Smrg
17748fb7bfaSmrg__gthr_objc_thread_detach(void (*func)(void *arg), void *arg), objc_thread_t
1784fee23f9Smrg	Spawns a new thread executing func, called by objc_thread_detach.
1794fee23f9Smrg	Return NULL if error otherwise return thread id.
1804fee23f9Smrg
18148fb7bfaSmrg__gthr_objc_thread_set_priority(int priority), int
1824fee23f9Smrg	Set the thread's priority, called by objc_thread_set_priority.
1834fee23f9Smrg	Return -1 if error otherwise return 0.
1844fee23f9Smrg
18548fb7bfaSmrg__gthr_objc_thread_get_priority(void), int
1864fee23f9Smrg	Query a thread's priority, called by objc_thread_get_priority.
1874fee23f9Smrg	Return -1 if error otherwise return the priority.
1884fee23f9Smrg
18948fb7bfaSmrg__gthr_objc_thread_yield(void), void
1904fee23f9Smrg	Yields the processor, called by objc_thread_yield.
1914fee23f9Smrg
19248fb7bfaSmrg__gthr_objc_thread_exit(void), int
1934fee23f9Smrg	Terminates the thread, called by objc_thread_exit.
1944fee23f9Smrg	Return -1 if error otherwise function does not return.
1954fee23f9Smrg
19648fb7bfaSmrg__gthr_objc_thread_id(void), objc_thread_t
1974fee23f9Smrg	Returns the current thread's id, called by objc_thread_id.
1984fee23f9Smrg	Return -1 if error otherwise return thread id.
1994fee23f9Smrg
20048fb7bfaSmrg__gthr_objc_thread_set_data(void *value), int
2014fee23f9Smrg	Set pointer for thread local storage, called by objc_thread_set_data.
2024fee23f9Smrg	Returns -1 if error otherwise return 0.
2034fee23f9Smrg
20448fb7bfaSmrg__gthr_objc_thread_get_data(void), void *
2054fee23f9Smrg	Returns the pointer to the thread's local storage.
2064fee23f9Smrg	Returns NULL if error, called by objc_thread_get_data.
2074fee23f9Smrg
2084fee23f9Smrg
2094fee23f9Smrg******************************************************************************
2104fee23f9Smrg* Mutexes:
2114fee23f9Smrg
2124fee23f9SmrgMutexes can be locked recursively.  Each locked mutex remembers
2134fee23f9Smrgits owner (by thread id) and how many times it has been locked.  The
2144fee23f9Smrglast unlock on a mutex removes the system lock and allows other
2154fee23f9Smrgthreads to access the mutex.
2164fee23f9Smrg
2174fee23f9Smrg*****
2184fee23f9Smrg* Frontend mutex functions
2194fee23f9Smrg* User programs should use these functions.
2204fee23f9Smrg
2214fee23f9Smrgobjc_mutex_allocate(void), objc_mutex_t
2224fee23f9Smrg	Allocates a new mutex.  Mutex is initially unlocked.
2234fee23f9Smrg	Return NULL if error otherwise return mutex pointer.
2244fee23f9Smrg
2254fee23f9Smrgobjc_mutex_deallocate(objc_mutex_t mutex), int
2264fee23f9Smrg	Free a mutex.  Before freeing the mutex, makes sure that no
2274fee23f9Smrg	one else is using it.
2284fee23f9Smrg	Return -1 if error otherwise return 0.
2294fee23f9Smrg
2304fee23f9Smrgobjc_mutex_lock(objc_mutex_t mutex), int
2314fee23f9Smrg	Locks a mutex.  As mentioned earlier, the same thread may call
2324fee23f9Smrg	this routine repeatedly.
2334fee23f9Smrg	Return -1 if error otherwise return 0.
2344fee23f9Smrg
2354fee23f9Smrgobjc_mutex_trylock(objc_mutex_t mutex), int
2364fee23f9Smrg	Attempts to lock a mutex.  If lock on mutex can be acquired
2374fee23f9Smrg	then function operates exactly as objc_mutex_lock.
2384fee23f9Smrg	Return -1 if failed to acquire lock otherwise return 0.
2394fee23f9Smrg
2404fee23f9Smrgobjc_mutex_unlock(objc_mutex_t mutex), int
2414fee23f9Smrg	Unlocks the mutex by one level.  Other threads may not acquire
2424fee23f9Smrg	the mutex until this thread has released all locks on it.
2434fee23f9Smrg	Return -1 if error otherwise return 0.
2444fee23f9Smrg
2454fee23f9Smrg*****
2464fee23f9Smrg* Backend mutex functions
2474fee23f9Smrg* User programs should *NOT* directly call these functions.
2484fee23f9Smrg
24948fb7bfaSmrg__gthr_objc_mutex_allocate(objc_mutex_t mutex), int
2504fee23f9Smrg	Allocates a new mutex, called by objc_mutex_allocate.
2514fee23f9Smrg	Return -1 if error otherwise return 0.
2524fee23f9Smrg
25348fb7bfaSmrg__gthr_objc_mutex_deallocate(objc_mutex_t mutex), int
2544fee23f9Smrg	Free a mutex, called by objc_mutex_deallocate.
2554fee23f9Smrg	Return -1 if error otherwise return 0.
2564fee23f9Smrg
25748fb7bfaSmrg__gthr_objc_mutex_lock(objc_mutex_t mutex), int
2584fee23f9Smrg	Locks a mutex, called by objc_mutex_lock.
2594fee23f9Smrg	Return -1 if error otherwise return 0.
2604fee23f9Smrg
26148fb7bfaSmrg__gthr_objc_mutex_trylock(objc_mutex_t mutex), int
2624fee23f9Smrg	Attempts to lock a mutex, called by objc_mutex_trylock.
2634fee23f9Smrg	Return -1 if failed to acquire lock or error otherwise return 0.
2644fee23f9Smrg
26548fb7bfaSmrg__gthr_objc_mutex_unlock(objc_mutex_t mutex), int
2664fee23f9Smrg	Unlocks the mutex, called by objc_mutex_unlock.
2674fee23f9Smrg	Return -1 if error otherwise return 0.
2684fee23f9Smrg
2694fee23f9Smrg******************************************************************************
2704fee23f9Smrg* Condition Mutexes:
2714fee23f9Smrg
2724fee23f9SmrgMutexes can be locked recursively.  Each locked mutex remembers
2734fee23f9Smrgits owner (by thread id) and how many times it has been locked.  The
2744fee23f9Smrglast unlock on a mutex removes the system lock and allows other
2754fee23f9Smrgthreads to access the mutex.
2764fee23f9Smrg
2774fee23f9Smrg*
2784fee23f9Smrg* Frontend condition mutex functions
2794fee23f9Smrg* User programs should use these functions.
2804fee23f9Smrg*
2814fee23f9Smrg
2824fee23f9Smrgobjc_condition_allocate(void), objc_condition_t
2834fee23f9Smrg	Allocate a condition mutex.
2844fee23f9Smrg	Return NULL if error otherwise return condition pointer.
2854fee23f9Smrg
2864fee23f9Smrgobjc_condition_deallocate(objc_condition_t condition), int
2874fee23f9Smrg	Deallocate a condition. Note that this includes an implicit
2884fee23f9Smrg	condition_broadcast to insure that waiting threads have the
2894fee23f9Smrg	opportunity to wake.  It is legal to dealloc a condition only
2904fee23f9Smrg	if no other thread is/will be using it. Does NOT check for
2914fee23f9Smrg	other threads waiting but just wakes them up.
2924fee23f9Smrg	Return -1 if error otherwise return 0.
2934fee23f9Smrg
2944fee23f9Smrgobjc_condition_wait(objc_condition_t condition, objc_mutex_t mutex), int
2954fee23f9Smrg	Wait on the condition unlocking the mutex until objc_condition_signal()
2964fee23f9Smrg	or objc_condition_broadcast() are called for the same condition. The
2974fee23f9Smrg	given mutex *must* have the depth 1 so that it can be unlocked
2984fee23f9Smrg	here, for someone else can lock it and signal/broadcast the condition.
2994fee23f9Smrg	The mutex is used to lock access to the shared data that make up the
3004fee23f9Smrg	"condition" predicate.
3014fee23f9Smrg	Return -1 if error otherwise return 0.
3024fee23f9Smrg
3034fee23f9Smrgobjc_condition_broadcast(objc_condition_t condition), int
3044fee23f9Smrg	Wake up all threads waiting on this condition. It is recommended that
3054fee23f9Smrg	the called would lock the same mutex as the threads in
3064fee23f9Smrg	objc_condition_wait before changing the "condition predicate"
3074fee23f9Smrg	and make this call and unlock it right away after this call.
3084fee23f9Smrg	Return -1 if error otherwise return 0.
3094fee23f9Smrg
3104fee23f9Smrgobjc_condition_signal(objc_condition_t condition), int
3114fee23f9Smrg	Wake up one thread waiting on this condition.
3124fee23f9Smrg	Return -1 if error otherwise return 0.
3134fee23f9Smrg
3144fee23f9Smrg*
3154fee23f9Smrg* Backend condition mutex functions
3164fee23f9Smrg* User programs should *NOT* directly call these functions.
3174fee23f9Smrg*
3184fee23f9Smrg
31948fb7bfaSmrg__gthr_objc_condition_allocate(objc_condition_t condition), int
3204fee23f9Smrg	Allocate a condition mutex, called by objc_condition_allocate.
3214fee23f9Smrg	Return -1 if error otherwise return 0.
3224fee23f9Smrg
32348fb7bfaSmrg__gthr_objc_condition_deallocate(objc_condition_t condition), int
3244fee23f9Smrg	Deallocate a condition, called by objc_condition_deallocate.
3254fee23f9Smrg	Return -1 if error otherwise return 0.
3264fee23f9Smrg
32748fb7bfaSmrg__gthr_objc_condition_wait(objc_condition_t condition, objc_mutex_t mutex), int
3284fee23f9Smrg	Wait on the condition, called by objc_condition_wait.
3294fee23f9Smrg	Return -1 if error otherwise return 0 when condition is met.
3304fee23f9Smrg
33148fb7bfaSmrg__gthr_objc_condition_broadcast(objc_condition_t condition), int
3324fee23f9Smrg	Wake up all threads waiting on this condition.
3334fee23f9Smrg	Called by objc_condition_broadcast.
3344fee23f9Smrg	Return -1 if error otherwise return 0.
3354fee23f9Smrg
33648fb7bfaSmrg__gthr_objc_condition_signal(objc_condition_t condition), int
3374fee23f9Smrg	Wake up one thread waiting on this condition.
3384fee23f9Smrg	Called by objc_condition_signal.
3394fee23f9Smrg	Return -1 if error otherwise return 0.
340