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
|
---|
4 | and PowerPC are also integrated. They should behave similarly, except that
|
---|
5 | the PowerPC port lacks incremental GC support, and it is unknown to what
|
---|
6 | extent the Linux threads code is functional. See below for M68K specific
|
---|
7 | notes.
|
---|
8 |
|
---|
9 | Incremental GC is supported on Intel IA32 and M68K.
|
---|
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 with Linux threads. We have seen
|
---|
15 | intermittent hangs in sem_wait. So far we have been unable to reproduce
|
---|
16 | these unless the process was being debugged or traced. Thus it's
|
---|
17 | possible that the only real issue is that the debugger loses
|
---|
18 | signals on rare occasions.
|
---|
19 |
|
---|
20 | The garbage collector uses SIGPWR and SIGXCPU if it is used with
|
---|
21 | Linux threads. These should not be touched by the client program.
|
---|
22 |
|
---|
23 | To use threads, you need to abide by the following requirements:
|
---|
24 |
|
---|
25 | 1) You need to use LinuxThreads (which are included in libc6).
|
---|
26 |
|
---|
27 | The collector relies on some implementation details of the LinuxThreads
|
---|
28 | package. It is unlikely that this code will work on other
|
---|
29 | pthread implementations (in particular it will *not* work with
|
---|
30 | MIT pthreads).
|
---|
31 |
|
---|
32 | 2) You must compile the collector with -DGC_LINUX_THREADS and -D_REENTRANT
|
---|
33 | specified in the Makefile.
|
---|
34 |
|
---|
35 | 3a) Every file that makes thread calls should define GC_LINUX_THREADS and
|
---|
36 | _REENTRANT and then include gc.h. Gc.h redefines some of the
|
---|
37 | pthread primitives as macros which also provide the collector with
|
---|
38 | information it requires.
|
---|
39 |
|
---|
40 | 3b) A new alternative to (3a) is to build the collector and compile GC clients
|
---|
41 | with -DGC_USE_LD_WRAP, and to link the final program with
|
---|
42 |
|
---|
43 | (for ld) --wrap read --wrap dlopen --wrap pthread_create \
|
---|
44 | --wrap pthread_join --wrap pthread_detach \
|
---|
45 | --wrap pthread_sigmask --wrap sleep
|
---|
46 |
|
---|
47 | (for gcc) -Wl,--wrap -Wl,read -Wl,--wrap -Wl,dlopen -Wl,--wrap \
|
---|
48 | -Wl,pthread_create -Wl,--wrap -Wl,pthread_join -Wl,--wrap \
|
---|
49 | -Wl,pthread_detach -Wl,--wrap -Wl,pthread_sigmask \
|
---|
50 | -Wl,--wrap -Wl,sleep
|
---|
51 |
|
---|
52 | In any case, _REENTRANT should be defined during compilation.
|
---|
53 |
|
---|
54 | 4) Dlopen() disables collection during its execution. (It can't run
|
---|
55 | concurrently with the collector, since the collector looks at its
|
---|
56 | data structures. It can't acquire the allocator lock, since arbitrary
|
---|
57 | user startup code may run as part of dlopen().) Under unusual
|
---|
58 | conditions, this may cause unexpected heap growth.
|
---|
59 |
|
---|
60 | 5) The combination of GC_LINUX_THREADS, REDIRECT_MALLOC, and incremental
|
---|
61 | collection fails in seemingly random places. This hasn't been tracked
|
---|
62 | down yet, but is perhaps not completely astonishing. The thread package
|
---|
63 | uses malloc, and thus can presumably get SIGSEGVs while inside the
|
---|
64 | package. There is no real guarantee that signals are handled properly
|
---|
65 | at that point.
|
---|
66 |
|
---|
67 | 6) Thread local storage may not be viewed as part of the root set by the
|
---|
68 | collector. This probably depends on the linuxthreads version. For the
|
---|
69 | time being, any collectable memory referenced by thread local storage should
|
---|
70 | also be referenced from elsewhere, or be allocated as uncollectable.
|
---|
71 | (This is really a bug that should be fixed somehow.)
|
---|
72 |
|
---|
73 |
|
---|
74 | M68K LINUX:
|
---|
75 | (From Richard Zidlicky)
|
---|
76 | The bad news is that it can crash every linux-m68k kernel on a 68040,
|
---|
77 | so an additional test is needed somewhere on startup. I have meanwhile
|
---|
78 | patches to correct the problem in 68040 buserror handler but it is not
|
---|
79 | yet in any standard kernel.
|
---|
80 |
|
---|
81 | Here is a simple test program to detect whether the kernel has the
|
---|
82 | problem. It could be run as a separate check in configure or tested
|
---|
83 | upon startup. If it fails (return !0) than mprotect can't be used
|
---|
84 | on that system.
|
---|
85 |
|
---|
86 | /*
|
---|
87 | * test for bug that may crash 68040 based Linux
|
---|
88 | */
|
---|
89 |
|
---|
90 | #include <sys/mman.h>
|
---|
91 | #include <signal.h>
|
---|
92 | #include <unistd.h>
|
---|
93 | #include <stdio.h>
|
---|
94 | #include <stdlib.h>
|
---|
95 |
|
---|
96 |
|
---|
97 | char *membase;
|
---|
98 | int pagesize=4096;
|
---|
99 | int pageshift=12;
|
---|
100 | int x_taken=0;
|
---|
101 |
|
---|
102 | int sighandler(int sig)
|
---|
103 | {
|
---|
104 | mprotect(membase,pagesize,PROT_READ|PROT_WRITE);
|
---|
105 | x_taken=1;
|
---|
106 | }
|
---|
107 |
|
---|
108 | main()
|
---|
109 | {
|
---|
110 | long l;
|
---|
111 |
|
---|
112 | signal(SIGSEGV,sighandler);
|
---|
113 | l=(long)mmap(NULL,pagesize,PROT_READ,MAP_PRIVATE | MAP_ANON,-1,0);
|
---|
114 | if (l==-1)
|
---|
115 | {
|
---|
116 | perror("mmap/malloc");
|
---|
117 | abort();
|
---|
118 | }
|
---|
119 | membase=(char*)l;
|
---|
120 | *(long*)(membase+sizeof(long))=123456789;
|
---|
121 | if (*(long*)(membase+sizeof(long)) != 123456789 )
|
---|
122 | {
|
---|
123 | fprintf(stderr,"writeback failed !\n");
|
---|
124 | exit(1);
|
---|
125 | }
|
---|
126 | if (!x_taken)
|
---|
127 | {
|
---|
128 | fprintf(stderr,"exception not taken !\n");
|
---|
129 | exit(1);
|
---|
130 | }
|
---|
131 | fprintf(stderr,"vmtest Ok\n");
|
---|
132 | exit(0);
|
---|
133 | }
|
---|
134 |
|
---|
135 |
|
---|