]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | See README.alpha for Linux on DEC AXP info. |
2 | ||
3 | This file applies mostly to Linux/Intel IA32. Ports to Linux on an M68K, IA64, | |
4 | SPARC, MIPS, Alpha and PowerPC are also integrated. They should behave | |
5 | similarly, except that the PowerPC port lacks incremental GC support, and | |
6 | it is unknown to what extent the Linux threads code is functional. | |
7 | See below for M68K specific notes. | |
8 | ||
9 | Incremental GC is generally supported. | |
10 | ||
11 | Dynamic libraries are supported on an ELF system. A static executable | |
12 | should be linked with the gcc option "-Wl,-defsym,_DYNAMIC=0". | |
13 | ||
14 | The collector appears to work reliably with Linux threads, but beware | |
15 | of older versions of glibc and gdb. | |
16 | ||
17 | The garbage collector uses SIGPWR and SIGXCPU if it is used with | |
18 | Linux threads. These should not be touched by the client program. | |
19 | ||
20 | To use threads, you need to abide by the following requirements: | |
21 | ||
22 | 1) You need to use LinuxThreads or NPTL (which are included in libc6). | |
23 | ||
24 | The collector relies on some implementation details of the LinuxThreads | |
25 | package. This code may not work on other | |
26 | pthread implementations (in particular it will *not* work with | |
27 | MIT pthreads). | |
28 | ||
29 | 2) You must compile the collector with -DGC_LINUX_THREADS (or | |
30 | just -DGC_THREADS) and -D_REENTRANT specified in the Makefile. | |
31 | ||
32 | 3a) Every file that makes thread calls should define GC_LINUX_THREADS and | |
33 | _REENTRANT and then include gc.h. Gc.h redefines some of the | |
34 | pthread primitives as macros which also provide the collector with | |
35 | information it requires. | |
36 | ||
37 | 3b) A new alternative to (3a) is to build the collector and compile GC clients | |
38 | with -DGC_USE_LD_WRAP, and to link the final program with | |
39 | ||
40 | (for ld) --wrap read --wrap dlopen --wrap pthread_create \ | |
41 | --wrap pthread_join --wrap pthread_detach \ | |
42 | --wrap pthread_sigmask --wrap sleep | |
43 | ||
44 | (for gcc) -Wl,--wrap -Wl,read -Wl,--wrap -Wl,dlopen -Wl,--wrap \ | |
45 | -Wl,pthread_create -Wl,--wrap -Wl,pthread_join -Wl,--wrap \ | |
46 | -Wl,pthread_detach -Wl,--wrap -Wl,pthread_sigmask \ | |
47 | -Wl,--wrap -Wl,sleep | |
48 | ||
49 | In any case, _REENTRANT should be defined during compilation. | |
50 | ||
51 | 4) Dlopen() disables collection during its execution. (It can't run | |
52 | concurrently with the collector, since the collector looks at its | |
53 | data structures. It can't acquire the allocator lock, since arbitrary | |
54 | user startup code may run as part of dlopen().) Under unusual | |
55 | conditions, this may cause unexpected heap growth. | |
56 | ||
57 | 5) The combination of GC_LINUX_THREADS, REDIRECT_MALLOC, and incremental | |
58 | collection is probably not fully reliable, though it now seems to work | |
59 | in simple cases. | |
60 | ||
61 | 6) Thread local storage may not be viewed as part of the root set by the | |
62 | collector. This probably depends on the linuxthreads version. For the | |
63 | time being, any collectable memory referenced by thread local storage should | |
64 | also be referenced from elsewhere, or be allocated as uncollectable. | |
65 | (This is really a bug that should be fixed somehow. The current GC | |
66 | version probably gets things right if there are not too many tls locations | |
67 | and if dlopen is not used.) | |
68 | ||
69 | ||
70 | M68K LINUX: | |
71 | (From Richard Zidlicky) | |
72 | The bad news is that it can crash every linux-m68k kernel on a 68040, | |
73 | so an additional test is needed somewhere on startup. I have meanwhile | |
74 | patches to correct the problem in 68040 buserror handler but it is not | |
75 | yet in any standard kernel. | |
76 | ||
77 | Here is a simple test program to detect whether the kernel has the | |
78 | problem. It could be run as a separate check in configure or tested | |
79 | upon startup. If it fails (return !0) than mprotect can't be used | |
80 | on that system. | |
81 | ||
82 | /* | |
83 | * test for bug that may crash 68040 based Linux | |
84 | */ | |
85 | ||
86 | #include <sys/mman.h> | |
87 | #include <signal.h> | |
88 | #include <unistd.h> | |
89 | #include <stdio.h> | |
90 | #include <stdlib.h> | |
91 | ||
92 | ||
93 | char *membase; | |
94 | int pagesize=4096; | |
95 | int pageshift=12; | |
96 | int x_taken=0; | |
97 | ||
98 | int sighandler(int sig) | |
99 | { | |
100 | mprotect(membase,pagesize,PROT_READ|PROT_WRITE); | |
101 | x_taken=1; | |
102 | } | |
103 | ||
104 | main() | |
105 | { | |
106 | long l; | |
107 | ||
108 | signal(SIGSEGV,sighandler); | |
109 | l=(long)mmap(NULL,pagesize,PROT_READ,MAP_PRIVATE | MAP_ANON,-1,0); | |
110 | if (l==-1) | |
111 | { | |
112 | perror("mmap/malloc"); | |
113 | abort(); | |
114 | } | |
115 | membase=(char*)l; | |
116 | *(long*)(membase+sizeof(long))=123456789; | |
117 | if (*(long*)(membase+sizeof(long)) != 123456789 ) | |
118 | { | |
119 | fprintf(stderr,"writeback failed !\n"); | |
120 | exit(1); | |
121 | } | |
122 | if (!x_taken) | |
123 | { | |
124 | fprintf(stderr,"exception not taken !\n"); | |
125 | exit(1); | |
126 | } | |
127 | fprintf(stderr,"vmtest Ok\n"); | |
128 | exit(0); | |
129 | } | |
130 | ||
131 |