Commit | Line | Data |
72aaf631 |
1 | Building |
2 | |
d81a1b93 |
3 | If you want to build with multi-threading support and you are |
4 | running Linux 2.x (with the LinuxThreads library installed: |
5 | that's the linuxthreads and linuxthreads-devel RPMs for RedHat) |
6 | or Digital UNIX 4.x or Solaris 2.x for recentish x (2.5 is OK) |
7 | then you should be able to use |
8 | ./Configure -Dusethreads -Doptimize=-g -ders |
9 | make |
10 | and ignore the rest of this "Building" section. If it doesn't |
11 | work or you are using another platform which you believe supports |
12 | POSIX.1c threads then read on. |
13 | |
72aaf631 |
14 | Omit the -e from your ./Configure arguments. For example, use |
15 | ./Configure -drs |
16 | When it offers to let you change config.sh, do so. If you already |
17 | have a config.sh then you can edit it and do |
18 | ./Configure -S |
19 | to propagate the required changes. |
20 | In ccflags, insert -DUSE_THREADS (and probably -DDEBUGGING since |
21 | that's what I've been building with). Also insert any other |
22 | arguments in there that your compiler needs to use POSIX threads. |
23 | Change optimize to -g to give you better debugging information. |
24 | Include any necessary explicit libraries in libs and change |
25 | ldflags if you need any linker flags instead or as well. |
26 | |
27 | More explicitly, for Linux (when using the standard kernel-threads |
28 | based LinuxThreads library): |
29 | Add -DUSE_THREADS -D_REENTRANT -DDEBUGGING to ccflags and cppflags |
30 | Add -lpthread to libs |
31 | Change optimize to -g |
32 | For Digital Unix 4.x: |
33 | Add -pthread -DUSE_THREADS -DDEBUGGING to ccflags |
34 | Add -DUSE_THREADS -DDEBUGGING to cppflags |
35 | Add -pthread to ldflags |
36 | Change optimize to -g |
d81a1b93 |
37 | Add -lpthread -lc_r to lddlflags |
72aaf631 |
38 | For some reason, the extra includes for pthreads make Digital UNIX |
39 | complain fatally about the sbrk() delcaration in perl's malloc.c |
40 | so use the native malloc as follows: |
41 | Change usemymalloc to n |
42 | Zap mallocobj and mallocsrc (foo='') |
43 | Change d_mymalloc to undef |
d81a1b93 |
44 | For Solaris, do the same as for Linux above. |
72aaf631 |
45 | |
46 | Now you can do a |
d81a1b93 |
47 | make |
48 | |
72aaf631 |
49 | |
50 | Building the Thread extension |
51 | |
52 | Build it away from the perl tree in the usual way. Set your PATH |
53 | environment variable to have your perl build directory first and |
43fe56be |
54 | set PERL5LIB to be /your/perl/build/directory/lib (without those, |
55 | I had problems where the config information from the ordinary perl |
56 | on the system would end up in the Makefile). Then |
57 | perl Makefile.PL PERL_SRC=/your/perl/build/directory |
72aaf631 |
58 | make |
72aaf631 |
59 | |
60 | Then you can try some of the tests with |
61 | perl -Mblib create.t |
62 | perl -Mblib join.t |
63 | perl -Mblib lock.t |
64 | perl -Mblib unsync.t |
65 | perl -Mblib unsync2.t |
66 | perl -Mblib unsync3.t |
67 | perl -Mblib io.t |
d81a1b93 |
68 | perl -Mblib queue.t |
72aaf631 |
69 | The io one leaves a thread reading from the keyboard on stdin so |
70 | as the ping messages appear you can type lines and see them echoed. |
71 | |
72 | Try running the main perl test suite too. There are known |
73 | failures for po/misc test 45 (tries to do local(@_) but @_ is |
74 | now lexical) and some tests involving backticks/system/fork |
d81a1b93 |
75 | may or may not work. Under Linux, many tests may appear to fail |
72aaf631 |
76 | when run under the test harness but work fine when invoked |
77 | manually. |
78 | |
79 | |
80 | Bugs |
81 | |
82 | * cond.t hasn't been redone since condition variable changed. |
83 | |
84 | * FAKE_THREADS should produce a working perl but the Thread |
85 | extension won't build with it yet. |
86 | |
87 | * There's a known memory leak (curstack isn't freed at the end |
88 | of each thread because it causes refcount problems that I |
89 | haven't tracked down yet) and there are very probably others too. |
90 | |
72aaf631 |
91 | * There are still races where bugs show up under contention. |
92 | |
43fe56be |
93 | * Need to document "lock", Thread.pm, Queue.pm, ... |
94 | |
72aaf631 |
95 | * Plenty of others |
96 | |
97 | |
1304aa9d |
98 | Debugging |
99 | |
100 | Use the -DL command-line option to turn on debugging of the |
101 | multi-threading code. Under Linux, that also turns on a quick |
102 | hack I did to grab a bit of extra information from segfaults. |
103 | If you have a fancier gdb/threads setup than I do then you'll |
104 | have to delete the lines in perl.c which say |
105 | #if defined(DEBUGGING) && defined(USE_THREADS) && defined(__linux__) |
106 | DEBUG_L(signal(SIGSEGV, (void(*)(int))catch_sigsegv);); |
107 | #endif |
108 | |
109 | |
43fe56be |
110 | Background |
111 | |
112 | Some old globals (e.g. stack_sp, op) and some old per-interpreter |
113 | variables (e.g. tmps_stack, cxstack) move into struct thread. |
114 | All fields of struct thread (apart from a few only applicable to |
115 | FAKE_THREADS) are of the form Tfoo. For example, stack_sp becomes |
116 | the field Tstack_sp of struct thread. For those fields which moved |
117 | from original perl, thread.h does |
118 | #define foo (thr->Tfoo) |
119 | This means that all functions in perl which need to use one of these |
120 | fields need an (automatic) variable thr which points at the current |
121 | thread's struct thread. For pp_foo functions, it is passed around as |
122 | an argument, for other functions they do |
123 | dTHR; |
124 | which declares and initialises thr from thread-specific data |
125 | via pthread_getspecific. If a function fails to compile with an |
126 | error about "no such variable thr", it probably just needs a dTHR |
127 | at the top. |
128 | |
129 | |
130 | Fake threads |
131 | |
132 | For FAKE_THREADS, thr is a global variable and perl schedules threads |
133 | by altering thr in between appropriate ops. The next and prev fields |
134 | of struct thread keep all fake threads on a doubly linked list and |
135 | the next_run and prev_run fields keep all runnable threads on a |
136 | doubly linked list. Mutexes are stubs for FAKE_THREADS. Condition |
137 | variables are implemented as a list of waiting threads. |
138 | |
139 | |
140 | Mutexes and condition variables |
141 | |
142 | The API is via macros MUTEX_{INIT,LOCK,UNLOCK,DESTROY} and |
143 | COND_{INIT,WAIT,SIGNAL,BROADCAST,DESTROY}. For POSIX threads, |
144 | perl mutexes and condition variables correspond to POSIX ones. |
145 | For FAKE_THREADS, mutexes are stubs and condition variables are |
146 | implmented as lists of waiting threads. For FAKE_THREADS, a thread |
147 | waits on a condition variable by removing itself from the runnable |
148 | list, calling SCHEDULE to change thr to the next appropriate |
149 | runnable thread and returning op (i.e. the new threads next op). |
150 | This means that fake threads can only block while in PP code. |
151 | A PP function which contains a COND_WAIT must be prepared to |
152 | handle such restarts and can use the field "private" of struct |
153 | thread to record its state. For fake threads, COND_SIGNAL and |
154 | COND_BROADCAST work by putting back all the threads on the |
155 | condition variables list into the run queue. Note that a mutex |
156 | must *not* be held while returning from a PP function. |
157 | |
c7848ba1 |
158 | Perl locks and condition variables are both implemented as a |
159 | condpair_t structure, containing a mutex, an "owner" condition |
160 | variable, an owner thread field and another condition variable). |
161 | The structure is attached by 'm' magic to any SV. pp_lock locks |
162 | such an object by waiting on the ownercond condition variable until |
163 | the owner field is zero and then setting the owner field to its own |
164 | thread pointer. The lock is semantically recursive so if the owner |
165 | field already matches the current thread then pp_lock returns |
166 | straight away. If the owner field has to be filled in then |
167 | unlock_condpair is queued as an end-of-block destructor and |
168 | that function zeroes out the owner field and signals the ownercond |
169 | condition variable, thus waking up any other thread that wants to |
170 | lock it. When used as a condition variable, the condpair is locked |
171 | (involving the above wait-for-ownership and setting the owner field) |
172 | and the spare condition variable field is used for waiting on. |
173 | |
174 | |
175 | Thread states |
176 | |
177 | |
178 | $t->join |
179 | R_JOINABLE ---------------------> R_JOINED >----\ |
180 | | \ pthread_join(t) | ^ | |
181 | | \ | | join | pthread_join |
182 | | \ | | | |
183 | | \ | \------/ |
184 | | \ | |
185 | | \ | |
186 | | $t->detach\ pthread_detach | |
187 | | _\| | |
188 | ends| R_DETACHED ends | unlink |
189 | | \ | |
190 | | ends \ unlink | |
191 | | \ | |
192 | | \ | |
193 | | \ | |
194 | | \ | |
195 | | \ | |
196 | V join detach _\| V |
197 | ZOMBIE ----------------------------> DEAD |
198 | pthread_join pthread_detach |
199 | and unlink and unlink |
200 | |
43fe56be |
201 | |
202 | |
72aaf631 |
203 | Malcolm Beattie |
204 | mbeattie@sable.ox.ac.uk |
d81a1b93 |
205 | 2 October 1997 |