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