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