1This file describes in little detail the modifications to the
2Objective-C runtime needed to make it thread safe.
3
4First off, kudos to Galen Hunt who is the author of this great work.
5
6If you have an comments or just want to know where to
7send me money to express your undying gratitude for threading the
8Objective-C runtime you can reach Galen at:
9
10          gchunt@cs.rochester.edu
11
12Any questions, comments, bug reports, etc. should send email either to the
13GCC bug account or to:
14
15          Scott Christley <scottc@net-community.com>
16
17* Sarray Threading:
18
19The most critical component of the Objective-C runtime is the sparse array
20structure (sarray).  Sarrays store object selectors and implementations.
21Following in the tradition of the Objective-C runtime, my threading
22support assumes that fast message dispatching is far more important
23than *ANY* and *ALL* other operations.  The message dispatching thus
24uses *NO* locks on any kind.  In fact, if you look in sarray.h, you
25will notice that the message dispatching has not been modified.
26Instead, I have modified the sarray management functions so that all
27updates to the sarray data structure can be made in parallel will
28message dispatching.
29
30To support concurrent message dispatching, no dynamically allocated
31sarray data structures are freed while more than one thread is
32operational.  Sarray data structures that are no longer in use are
33kept in a linked list of garbage and are released whenever the program
34is operating with a single thread.  The programmer can also flush the
35garbage list by calling sarray_remove_garbage when the programmer can
36ensure that no message dispatching is taking place concurrently.  The
37amount of un-reclaimed sarray garbage should normally be extremely
38small in a real program as sarray structures are freed only when using
39the "poseAs" functionality and early in program initialization, which
40normally occurs while the program is single threaded.
41
42******************************************************************************
43* Static Variables:
44
45The following variables are either statically or globally defined. This list
46does not include variables which are internal to implementation dependent
47versions of thread-*.c.
48
49The 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
55Variable 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
73frwd_sel                      SAFE2     sendmsg.c
74idxsize                                 MUTEX     sarray.c  sendmsg.c sarray.h
75initialize_sel                          SAFE2     sendmsg.c
76narrays                                 MUTEX     sarray.c  sendmsg.c sarray.h
77nbuckets                      MUTEX     sarray.c  sendmsg.c sarray.h
78nindices                      MUTEX     sarray.c  sarray.h
79previous_constructors                   SAFE1     init.c
80proto_class                             SAFE1     init.c
81unclaimed_categories                    MUTEX     init.c
82unclaimed_proto_list                    MUTEX     init.c
83uninitialized_statics                   MUTEX     init.c
84
85Notes:
861) Initialized once in unithread mode.
872) Initialized value will always be same, guaranteed by lock on selector
88   hash table.
89
90
91******************************************************************************
92* Frontend/Backend design:
93
94The design of the Objective-C runtime thread and mutex functions utilizes a
95frontend/backend implementation.
96
97The frontend, as characterized by the files thr.h and thr.c, is a set
98of platform independent structures and functions which represent the
99user interface.  For example, objc_mutex_lock().  Objective-C programs
100should use these structures and functions for their thread and mutex
101work if they wish to maintain a high degree of portability across
102platforms.
103
104The backend is currently GCC's gthread code (gthr.h and related).  For
105example, __gthread_objc_mutex_lock().  The thread system is
106automatically configured when GCC is configured.  On most platforms
107this thread backend is able to automatically switch to non-multi-threaded
108mode if the threading library is not linked in.
109
110If you want to compile libobjc standalone, then you would need to modify
111the configure.ac and makefiles for it and you need to import the
112gthread code from GCC.
113
114******************************************************************************
115* Threads:
116
117The thread system attempts to create multiple threads using whatever
118operating system or library thread support is available.  It does
119assume that all system functions are thread safe.  Notably this means
120that the system implementation of malloc and free must be thread safe.
121If a system has multiple processors, the threads are configured for
122full 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
138objc_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
143objc_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
151objc_thread_get_priority(void), int
152          Query a thread's priority.
153
154objc_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
159objc_thread_exit(void), int
160          Terminates a thread.  If this is the last thread executing
161          then the program will terminate.
162
163objc_thread_id(void), int
164          Returns the current thread's id.
165
166objc_thread_set_data(void *value), int
167          Set a pointer to the thread's local storage.  Local storage is
168          thread specific.
169
170objc_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
212Mutexes can be locked recursively.  Each locked mutex remembers
213its owner (by thread id) and how many times it has been locked.  The
214last unlock on a mutex removes the system lock and allows other
215threads to access the mutex.
216
217*****
218* Frontend mutex functions
219* User programs should use these functions.
220
221objc_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
225objc_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
230objc_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
235objc_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
240objc_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
272Mutexes can be locked recursively.  Each locked mutex remembers
273its owner (by thread id) and how many times it has been locked.  The
274last unlock on a mutex removes the system lock and allows other
275threads to access the mutex.
276
277*
278* Frontend condition mutex functions
279* User programs should use these functions.
280*
281
282objc_condition_allocate(void), objc_condition_t
283          Allocate a condition mutex.
284          Return NULL if error otherwise return condition pointer.
285
286objc_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
294objc_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
303objc_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
310objc_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