1 |
721 |
jeremybenn |
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 and -D_REENTRANT
|
30 |
|
|
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 fails in seemingly random places. This hasn't been tracked
|
59 |
|
|
down yet, but is perhaps not completely astonishing. The thread package
|
60 |
|
|
uses malloc, and thus can presumably get SIGSEGVs while inside the
|
61 |
|
|
package. There is no real guarantee that signals are handled properly
|
62 |
|
|
at that point.
|
63 |
|
|
|
64 |
|
|
6) Thread local storage may not be viewed as part of the root set by the
|
65 |
|
|
collector. This probably depends on the linuxthreads version. For the
|
66 |
|
|
time being, any collectable memory referenced by thread local storage should
|
67 |
|
|
also be referenced from elsewhere, or be allocated as uncollectable.
|
68 |
|
|
(This is really a bug that should be fixed somehow.)
|
69 |
|
|
|
70 |
|
|
|
71 |
|
|
M68K LINUX:
|
72 |
|
|
(From Richard Zidlicky)
|
73 |
|
|
The bad news is that it can crash every linux-m68k kernel on a 68040,
|
74 |
|
|
so an additional test is needed somewhere on startup. I have meanwhile
|
75 |
|
|
patches to correct the problem in 68040 buserror handler but it is not
|
76 |
|
|
yet in any standard kernel.
|
77 |
|
|
|
78 |
|
|
Here is a simple test program to detect whether the kernel has the
|
79 |
|
|
problem. It could be run as a separate check in configure or tested
|
80 |
|
|
upon startup. If it fails (return !0) than mprotect can't be used
|
81 |
|
|
on that system.
|
82 |
|
|
|
83 |
|
|
/*
|
84 |
|
|
* test for bug that may crash 68040 based Linux
|
85 |
|
|
*/
|
86 |
|
|
|
87 |
|
|
#include
|
88 |
|
|
#include
|
89 |
|
|
#include
|
90 |
|
|
#include
|
91 |
|
|
#include
|
92 |
|
|
|
93 |
|
|
|
94 |
|
|
char *membase;
|
95 |
|
|
int pagesize=4096;
|
96 |
|
|
int pageshift=12;
|
97 |
|
|
int x_taken=0;
|
98 |
|
|
|
99 |
|
|
int sighandler(int sig)
|
100 |
|
|
{
|
101 |
|
|
mprotect(membase,pagesize,PROT_READ|PROT_WRITE);
|
102 |
|
|
x_taken=1;
|
103 |
|
|
}
|
104 |
|
|
|
105 |
|
|
main()
|
106 |
|
|
{
|
107 |
|
|
long l;
|
108 |
|
|
|
109 |
|
|
signal(SIGSEGV,sighandler);
|
110 |
|
|
l=(long)mmap(NULL,pagesize,PROT_READ,MAP_PRIVATE | MAP_ANON,-1,0);
|
111 |
|
|
if (l==-1)
|
112 |
|
|
{
|
113 |
|
|
perror("mmap/malloc");
|
114 |
|
|
abort();
|
115 |
|
|
}
|
116 |
|
|
membase=(char*)l;
|
117 |
|
|
*(long*)(membase+sizeof(long))=123456789;
|
118 |
|
|
if (*(long*)(membase+sizeof(long)) != 123456789 )
|
119 |
|
|
{
|
120 |
|
|
fprintf(stderr,"writeback failed !\n");
|
121 |
|
|
exit(1);
|
122 |
|
|
}
|
123 |
|
|
if (!x_taken)
|
124 |
|
|
{
|
125 |
|
|
fprintf(stderr,"exception not taken !\n");
|
126 |
|
|
exit(1);
|
127 |
|
|
}
|
128 |
|
|
fprintf(stderr,"vmtest Ok\n");
|
129 |
|
|
exit(0);
|
130 |
|
|
}
|
131 |
|
|
|
132 |
|
|
|