]> git.ipfire.org Git - thirdparty/gcc.git/blame - libobjc/THREADS
Move documentation files from egcs/gcc/objc.
[thirdparty/gcc.git] / libobjc / THREADS
CommitLineData
005dda25
BE
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. Objective-C programs should use these structures and
100functions for their thread and mutex work if they wish to maintain a
101high degree of portability across platforms.
102
103The backend is composed of a file with the necessary code to map the ObjC
104thread and mutex to a platform specific implementation. For example, the
105file thr-solaris.c contains the implementation for Solaris. When you
106configure GCC, it attempts to pick an appropriate backend file for the
107target platform; however, you can override this choice by assign the
108OBJC_THREAD_FILE make variable to the basename of the backend file. This
109is especially useful on platforms which have multiple thread libraries.
110For example:
111
112 make OBJC_THREAD_FILE=thr-posix
113
114would indicate that the generic posix backend file, thr-posix.c, should be
115compiled with the ObjC runtime library. If your platform does not support
116threads then you should specify the OBJC_THREAD_FILE=thr-single backend file
117to compile the ObjC runtime library without thread or mutex support; note
118that programs which rely upon the ObjC thread and mutex functions will
119compile and link correctly but attempting to create a thread or mutex will
120result in an error.
121
122It is questionable whether it is really necessary to have both a
123frontend and backend function for all available functionality. On the
124one hand, it provides a clear, consistent differentiation between what
125is public and what is private with the downside of having the overhead
126of multiple functions calls. For example, the function to have a thread
127yield the processor is objc_thread_yield; in the current implementation
128this produces a function call set:
129
130objc_thread_yield() -> __objc_thread_yield() -> system yield function
131
132This has two extra function calls over calling the platform specific function
133explicitly, but the issue is whether only the overhead of a single function
134is necessary.
135
136objc_thread_yield() -> system yield function
137
138This breaks the public/private dichotomy between the frontend/backend
139for the sake of efficiency. It is possible to just use a preprocessor
140define so as to eliminate the extra function call:
141
142#define objc_thread_yield() __objc_thread_yield()
143
144This has the undesirable effect that if objc_thread_yield is actually
145turned into a function based upon future need; then ObjC programs which
146access the thread functions would need to be recompiled versus just
147being relinked.
148
149******************************************************************************
150* Threads:
151
152The thread system attempts to create multiple threads using whatever
153operating system or library thread support is available. It does
154assume that all system functions are thread safe. Notably this means
155that the system implementation of malloc and free must be thread safe.
156If a system has multiple processors, the threads are configured for
157full parallel processing.
158
159* Backend initialization functions
160
161__objc_init_thread_system(void), int
162 Initialize the thread subsystem. Called once by __objc_exec_class.
163 Return -1 if error otherwise return 0.
164
165__objc_close_thread_system(void), int
166 Closes the thread subsystem, not currently guaranteed to be called.
167 Return -1 if error otherwise return 0.
168
169*****
170* Frontend thread functions
171* User programs should use these functions.
172
173objc_thread_detach(SEL selector, id object, id argument), objc_thread_t
174 Creates and detaches a new thread. The new thread starts by
175 sending the given selector with a single argument to the
176 given object.
177
178objc_thread_set_priority(int priority), int
179 Sets a thread's relative priority within the program. Valid
180 options are:
181
182 OBJC_THREAD_INTERACTIVE_PRIORITY
183 OBJC_THREAD_BACKGROUND_PRIORITY
184 OBJC_THREAD_LOW_PRIORITY
185
186objc_thread_get_priority(void), int
187 Query a thread's priority.
188
189objc_thread_yield(void), void
190 Yields processor to another thread with equal or higher
191 priority. It is up to the system scheduler to determine if
192 the processor is taken or not.
193
194objc_thread_exit(void), int
195 Terminates a thread. If this is the last thread executing
196 then the program will terminate.
197
198objc_thread_id(void), int
199 Returns the current thread's id.
200
201objc_thread_set_data(void *value), int
202 Set a pointer to the thread's local storage. Local storage is
203 thread specific.
204
205objc_thread_get_data(void), void *
206 Returns the pointer to the thread's local storage.
207
208*****
209* Backend thread functions
210* User programs should *NOT* directly call these functions.
211
212__objc_thread_detach(void (*func)(void *arg), void *arg), objc_thread_t
213 Spawns a new thread executing func, called by objc_thread_detach.
214 Return NULL if error otherwise return thread id.
215
216__objc_thread_set_priority(int priority), int
217 Set the thread's priority, called by objc_thread_set_priority.
218 Return -1 if error otherwise return 0.
219
220__objc_thread_get_priority(void), int
221 Query a thread's priority, called by objc_thread_get_priority.
222 Return -1 if error otherwise return the priority.
223
224__objc_thread_yield(void), void
225 Yields the processor, called by objc_thread_yield.
226
227__objc_thread_exit(void), int
228 Terminates the thread, called by objc_thread_exit.
229 Return -1 if error otherwise function does not return.
230
231__objc_thread_id(void), objc_thread_t
232 Returns the current thread's id, called by objc_thread_id.
233 Return -1 if error otherwise return thread id.
234
235__objc_thread_set_data(void *value), int
236 Set pointer for thread local storage, called by objc_thread_set_data.
237 Returns -1 if error otherwise return 0.
238
239__objc_thread_get_data(void), void *
240 Returns the pointer to the thread's local storage.
241 Returns NULL if error, called by objc_thread_get_data.
242
243
244******************************************************************************
245* Mutexes:
246
247Mutexes can be locked recursively. Each locked mutex remembers
248its owner (by thread id) and how many times it has been locked. The
249last unlock on a mutex removes the system lock and allows other
250threads to access the mutex.
251
252*****
253* Frontend mutex functions
254* User programs should use these functions.
255
256objc_mutex_allocate(void), objc_mutex_t
257 Allocates a new mutex. Mutex is initially unlocked.
258 Return NULL if error otherwise return mutex pointer.
259
260objc_mutex_deallocate(objc_mutex_t mutex), int
261 Free a mutex. Before freeing the mutex, makes sure that no
262 one else is using it.
263 Return -1 if error otherwise return 0.
264
265objc_mutex_lock(objc_mutex_t mutex), int
266 Locks a mutex. As mentioned earlier, the same thread may call
267 this routine repeatedly.
268 Return -1 if error otherwise return 0.
269
270objc_mutex_trylock(objc_mutex_t mutex), int
271 Attempts to lock a mutex. If lock on mutex can be acquired
272 then function operates exactly as objc_mutex_lock.
273 Return -1 if failed to acquire lock otherwise return 0.
274
275objc_mutex_unlock(objc_mutex_t mutex), int
276 Unlocks the mutex by one level. Other threads may not acquire
277 the mutex until this thread has released all locks on it.
278 Return -1 if error otherwise return 0.
279
280*****
281* Backend mutex functions
282* User programs should *NOT* directly call these functions.
283
284__objc_mutex_allocate(objc_mutex_t mutex), int
285 Allocates a new mutex, called by objc_mutex_allocate.
286 Return -1 if error otherwise return 0.
287
288__objc_mutex_deallocate(objc_mutex_t mutex), int
289 Free a mutex, called by objc_mutex_deallocate.
290 Return -1 if error otherwise return 0.
291
292__objc_mutex_lock(objc_mutex_t mutex), int
293 Locks a mutex, called by objc_mutex_lock.
294 Return -1 if error otherwise return 0.
295
296__objc_mutex_trylock(objc_mutex_t mutex), int
297 Attempts to lock a mutex, called by objc_mutex_trylock.
298 Return -1 if failed to acquire lock or error otherwise return 0.
299
300__objc_mutex_unlock(objc_mutex_t mutex), int
301 Unlocks the mutex, called by objc_mutex_unlock.
302 Return -1 if error otherwise return 0.
303
304******************************************************************************
305* Condition Mutexes:
306
307Mutexes can be locked recursively. Each locked mutex remembers
308its owner (by thread id) and how many times it has been locked. The
309last unlock on a mutex removes the system lock and allows other
310threads to access the mutex.
311
312*
313* Frontend condition mutex functions
314* User programs should use these functions.
315*
316
317objc_condition_allocate(void), objc_condition_t
318 Allocate a condition mutex.
319 Return NULL if error otherwise return condition pointer.
320
321objc_condition_deallocate(objc_condition_t condition), int
322 Deallocate a condition. Note that this includes an implicit
323 condition_broadcast to insure that waiting threads have the
324 opportunity to wake. It is legal to dealloc a condition only
325 if no other thread is/will be using it. Does NOT check for
326 other threads waiting but just wakes them up.
327 Return -1 if error otherwise return 0.
328
329objc_condition_wait(objc_condition_t condition, objc_mutex_t mutex), int
330 Wait on the condition unlocking the mutex until objc_condition_signal()
331 or objc_condition_broadcast() are called for the same condition. The
332 given mutex *must* have the depth 1 so that it can be unlocked
333 here, for someone else can lock it and signal/broadcast the condition.
334 The mutex is used to lock access to the shared data that make up the
335 "condition" predicate.
336 Return -1 if error otherwise return 0.
337
338objc_condition_broadcast(objc_condition_t condition), int
339 Wake up all threads waiting on this condition. It is recommended that
340 the called would lock the same mutex as the threads in
341 objc_condition_wait before changing the "condition predicate"
342 and make this call and unlock it right away after this call.
343 Return -1 if error otherwise return 0.
344
345objc_condition_signal(objc_condition_t condition), int
346 Wake up one thread waiting on this condition.
347 Return -1 if error otherwise return 0.
348
349*
350* Backend condition mutex functions
351* User programs should *NOT* directly call these functions.
352*
353
354__objc_condition_allocate(objc_condition_t condition), int
355 Allocate a condition mutex, called by objc_condition_allocate.
356 Return -1 if error otherwise return 0.
357
358__objc_condition_deallocate(objc_condition_t condition), int
359 Deallocate a condition, called by objc_condition_deallocate.
360 Return -1 if error otherwise return 0.
361
362__objc_condition_wait(objc_condition_t condition, objc_mutex_t mutex), int
363 Wait on the condition, called by objc_condition_wait.
364 Return -1 if error otherwise return 0 when condition is met.
365
366__objc_condition_broadcast(objc_condition_t condition), int
367 Wake up all threads waiting on this condition.
368 Called by objc_condition_broadcast.
369 Return -1 if error otherwise return 0.
370
371__objc_condition_signal(objc_condition_t condition), int
372 Wake up one thread waiting on this condition.
373 Called by objc_condition_signal.
374 Return -1 if error otherwise return 0.