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