source: trunk/third/gcc/libobjc/THREADS @ 16960

Revision 16960, 14.7 KB checked in by ghudson, 23 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r16959, which included commits to RCS files with non-trunk default branches.
Line 
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.
106
107If you are compiling libobjc as part of GCC, the thr-objc.c backend is
108always used; this backend uses GCC's gthread code.  The thread system
109is automatically configured when GCC is configured.  Important: make
110sure you configure GCC using `--enable-threads' if you want threads !
111 
112If you want to compile libobjc standalone, then you would need to
113modify the configure.in and makefiles for it; and you need to pick an
114appropriate backend file for the target platform; you make this choice
115by assigning the OBJC_THREAD_FILE make variable to the basename of the
116backend file.  For example, OBJC_THREAD_FILE=thr-posix would indicate
117that the generic posix backend file, thr-posix.c, should be compiled
118with the ObjC runtime library.  If your platform does not support
119threads then you should specify the OBJC_THREAD_FILE=thr-single
120backend file to compile the ObjC runtime library without thread or
121mutex support; note that programs which rely upon the ObjC thread and
122mutex functions will compile and link correctly but attempting to
123create a thread or mutex will result in an error.
124 
125It is questionable whether it is really necessary to have both a
126frontend and backend function for all available functionality.  On the
127one hand, it provides a clear, consistent differentiation between what
128is public and what is private with the downside of having the overhead
129of multiple functions calls.  For example, the function to have a
130thread yield the processor is objc_thread_yield; in the current
131implementation this produces a function call set:
132
133objc_thread_yield()  ->  __objc_thread_yield()  ->  system yield function
134
135This has two extra function calls over calling the platform specific function
136explicitly, but the issue is whether only the overhead of a single function
137is necessary.
138
139objc_thread_yield()  ->  system yield function
140
141This breaks the public/private dichotomy between the frontend/backend
142for the sake of efficiency.  It is possible to just use a preprocessor
143define so as to eliminate the extra function call:
144
145#define objc_thread_yield() __objc_thread_yield()
146
147This has the undesirable effect that if objc_thread_yield is actually
148turned into a function based upon future need; then ObjC programs which
149access the thread functions would need to be recompiled versus just
150being relinked.
151 
152******************************************************************************
153* Threads:
154
155The thread system attempts to create multiple threads using whatever
156operating system or library thread support is available.  It does
157assume that all system functions are thread safe.  Notably this means
158that the system implementation of malloc and free must be thread safe.
159If a system has multiple processors, the threads are configured for
160full 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
176objc_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
181objc_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
189objc_thread_get_priority(void), int
190        Query a thread's priority.
191
192objc_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
197objc_thread_exit(void), int
198        Terminates a thread.  If this is the last thread executing
199        then the program will terminate.
200
201objc_thread_id(void), int
202        Returns the current thread's id.
203
204objc_thread_set_data(void *value), int
205        Set a pointer to the thread's local storage.  Local storage is
206        thread specific.
207
208objc_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
250Mutexes can be locked recursively.  Each locked mutex remembers
251its owner (by thread id) and how many times it has been locked.  The
252last unlock on a mutex removes the system lock and allows other
253threads to access the mutex.
254
255*****
256* Frontend mutex functions
257* User programs should use these functions.
258
259objc_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
263objc_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
268objc_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       
273objc_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
278objc_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
310Mutexes can be locked recursively.  Each locked mutex remembers
311its owner (by thread id) and how many times it has been locked.  The
312last unlock on a mutex removes the system lock and allows other
313threads to access the mutex.
314
315*
316* Frontend condition mutex functions
317* User programs should use these functions.
318*
319
320objc_condition_allocate(void), objc_condition_t
321        Allocate a condition mutex.
322        Return NULL if error otherwise return condition pointer.
323
324objc_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
332objc_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       
341objc_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
348objc_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.
Note: See TracBrowser for help on using the repository browser.