1 This file describes in little detail the modifications to the
2 Objective-C runtime needed to make it thread safe.
4 First off, kudos to Galen Hunt who is the author of this great work.
6 If you have an comments or just want to know where to
7 send me money to express your undying graditude for threading the
8 Objective-C runtime you can reach Galen at:
10 gchunt@cs.rochester.edu
12 Any questions, comments, bug reports, etc. should send email either to the
13 GCC bug account or to:
15 Scott Christley <scottc@ocbi.com>
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
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.
42 ******************************************************************************
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.
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.
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
86 1) Initialized once in unithread mode.
87 2) Initialized value will always be same, guaranteed by lock on selector
90 ******************************************************************************
93 On Solaris, you must link with -lthread to include the system
94 thread library. We use its low level thread and mutex implementations.
96 On OSF/1, you must link with -lpthreads to include the pthreads library.
98 On WIN32, thread support is built-in to the WIN32 API; refer to your
99 compiler documentation for the appropriate library.
101 ******************************************************************************
104 The thread system attempts to create multiple threads using whatever
105 operating system or library thread support is available. It does
106 assume that all system functions are thread safe. Notably this means
107 that the system implementation of malloc and free must be thread safe.
108 If a system has multiple processors, the threads are configured for
109 full parallel processing.
111 __objc_init_thread_system(void), int
112 Initialize the thread subsystem. Call once by __objc_exec_class.
114 __objc_fini_thread_system(void), int
115 Closes the thread subsystem.
117 objc_thread_detach(SEL selector, id object, id argument), int
118 Creates and detaches a new thread. The new thread starts by
119 sending the given selector with a single argument to the
122 objc_thread_set_priority(int priority), int
123 Sets a threads relative priority within the program. Valid
126 OBJC_THREAD_INTERACTIVE_PRIORITY
127 OBJC_THREAD_BACKGROUND_PRIORITY
128 OBJC_THREAD_LOW_PRIORITY
130 objc_thread_get_priority(void), int
131 Query a threads priority.
133 objc_thread_yield(void), void
134 Yields processor to another thread with equal or higher
135 priority. It is up to the system scheduler to determine if
136 the processor is taken or not.
138 objc_thread_exit(void), int
139 Terminates a thread. If this is the last thread executing
140 then the program will terminate.
142 objc_thread_id(void), int
143 Returns the current thread's id.
145 objc_thread_set_data(void *value), int
146 Set a pointer to the thread's local storage. Local storage is
149 objc_thread_get_data(void), void *
150 Returns the pointer to the thread's local storage.
152 ******************************************************************************
155 Mutexs can be locked recursively. Each mutex locked mutex remembers
156 its owner (by thread id) and how many times it has been locked. The
157 last unlock on a mutex removes the system lock and allows other
158 threads to access the mutex.
160 objc_mutex_allocate(void), Mutex_t
161 Allocates a new mutex. Mutex is initially unlocked.
163 objc_mutex_deallocate(Mutex_t mutex), int
164 Free a mutex. Before freeing the mutex, makes sure that no
165 one else is using it.
167 objc_mutex_lock(Mutex_t mutex), int
168 Locks a mutex. As mentioned earlier, the same thread may call
169 this routine repeatedly.
171 objc_mutex_trylock(Mutex_t mutex), int
172 Attempts to lock a mutex. Returns -1 if failed. If lock on
173 mutex can be acquired then function operates exactly as
176 objc_mutex_unlock(Mutex_t mutex), int
177 Unlocks the mutex by one level. Other threads may not acquire
178 the mutex until this thread has released all locks on it.
180 ******************************************************************************
181 * Sample run of thread-test/checks/test01.m
183 << program started >> -- Program started
184 __objc_exec_class(Object.m) -- Initialize once
185 __objc_init_mutex_system
186 __objc_init_thread_system
187 __objc_init_selector_tables()
188 __objc_init_class_tables()
189 __objc_init_dispatch_tables()
190 __objc_exec_class(Protocol.m) -- Called repeatedly
191 __objc_init_protocols(0x000746d4) -- Called repeatedly
192 class_add_method_list(0x74718, 0x74208) -- Called repeatedly
193 << main called >> -- Main called
194 __objc_init_install_dtable(0x6d980, 0x6d5c0) -- Called repeatedly
195 << delegatePool filled, count=10 >> -- Code in secondary function
196 __objc_init_install_dtable(0x76268, 0x70614) -- Called repeatedly
197 Array: count=1 -- More secondary code.
198 EltNodeCollector: count=1
199 << end of program >> -- End of program