/[cmucl]/src/lisp/hpux-os.c
ViewVC logotype

Contents of /src/lisp/hpux-os.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.11 - (hide annotations)
Thu Sep 1 05:18:26 2011 UTC (2 years, 7 months ago) by rtoy
Branch: MAIN
CVS Tags: GIT-CONVERSION, snapshot-2011-09, HEAD
Changes since 1.10: +5 -1 lines
File MIME type: text/plain
Add os_init0 to allow for some really early OS inits.

On Linux, os_init can re-exec lisp to set up the correct personality.
Not normally a problem, but if any output happens before os_init is
called, the output appears to happen twice.  So add os_init0 to do
this early on, before any output.  This is a bit of a kludge.

lisp/lisp.c:
o Call os_init0 early in main.

lisp/Linux-os.c:
o Move the personality stuff from os_init to os_init0.

lisp/Darwin-os.c:
lisp/FreeBSD-os.c:
lisp/NetBSD-os.c:
lisp/OpenBSD-os.c:
lisp/hpux-os.c:
lisp/irix-os.c:
lisp/mach-os.c:
lisp/osf1-os.c:
lisp/solaris-os.c:
lisp/sunos-os.c:
o Add dummy implementation of os_init0.  These OSes don't (currently)
  need anything special.

lisp/os.h:
o Declare os_init0.
1 hallgren 1.1 /*
2 rtoy 1.11 * $Header: /tiger/var/lib/cvsroots/cmucl/src/lisp/hpux-os.c,v 1.11 2011/09/01 05:18:26 rtoy Exp $
3 hallgren 1.1 *
4     * OS-dependent routines. This file (along with os.h) exports an
5     * OS-independent interface to the operating system VM facilities.
6     * Suprisingly, this interface looks a lot like the Mach interface
7     * (but simpler in some places). For some operating systems, a subset
8     * of these functions will have to be emulated.
9     *
10     */
11    
12     /* Assumptions these routines are based on:
13     os_validate: Not called with NULL for an addr.
14     os_invalidate: Never called.
15     os_map: Files are only mapped at the beginning of one of the areas passed
16     to os_validate.
17     os_protect: Only called on an entire region when giving permissions and only
18     called from some point in a segment to the end of the segment
19     when removing them.
20     Only called with all protections or no protections.
21     os_zero: Only ever zeroed from some point in a segment to the end of the
22     segment.
23     os_allocate_at: Calls to here are disjoint from those around it (the others
24     in os-common.c) since it calls os_validate and the others (in
25     os-common.c) use malloc, etc.
26     Note that os_validate does not actually allocate memory until it has to map
27     the particular section in.
28     */
29    
30     /* #define DEBUG */
31    
32     #include <stdio.h>
33     #include <assert.h>
34     #include <signal.h>
35     #include <sys/file.h>
36     #include <unistd.h>
37     #include "os.h"
38     #include <sys/resource.h>
39     #include "interrupt.h"
40     #include <netdb.h>
41 hallgren 1.2 #include <sys/times.h>
42 wlott 1.4 #include <errno.h>
43 hallgren 1.1
44 rtoy 1.7 os_vm_size_t os_vm_page_size = (-1);
45 hallgren 1.1
46     #define MAX_SEGMENTS 20
47 rtoy 1.7 #define ALLOC_SIZE 0x10000
48 hallgren 1.1 static struct segment {
49 rtoy 1.7 os_vm_address_t base;
50     os_vm_size_t len;
51     os_vm_address_t valid;
52     os_vm_address_t protected;
53 hallgren 1.1 } segments[MAX_SEGMENTS];
54    
55     void
56 rtoy 1.11 os_init0(const char *argv[], const char *envp[])
57     {}
58    
59     void
60 rtoy 1.10 os_init(const char *argv[], const char *envp[])
61 hallgren 1.1 {
62 rtoy 1.7 int i;
63    
64     os_vm_page_size = sysconf(_SC_PAGE_SIZE);
65     for (i = 0; i < MAX_SEGMENTS; i++)
66     segments[i].len = 0;
67 hallgren 1.1 }
68    
69    
70 rtoy 1.7 os_vm_address_t os_validate(os_vm_address_t addr, os_vm_size_t len)
71 hallgren 1.1 {
72 rtoy 1.7 int fd, i;
73     caddr_t ret;
74 hallgren 1.1
75 rtoy 1.7 addr = os_trunc_to_page(addr);
76     len = os_round_up_size_to_page(len);
77 hallgren 1.1
78     #ifdef DEBUG
79 rtoy 1.7 printf("os_validate: addr: 0x%X, len: 0x%X, end: 0x%X\n", addr, len,
80     addr + len);
81     #endif
82     assert(addr != NULL);
83     assert(len != 0);
84    
85     for (i = 0; i < MAX_SEGMENTS; i++)
86     if (segments[i].len == 0)
87     break;
88    
89     assert(i != MAX_SEGMENTS);
90    
91     segments[i].base = addr;
92     segments[i].len = len;
93     segments[i].valid = addr;
94     segments[i].protected = addr + len;
95     return addr;
96 hallgren 1.1 }
97    
98     void
99     os_invalidate(os_vm_address_t addr, os_vm_size_t len)
100     {
101 rtoy 1.7 assert(FALSE);
102 hallgren 1.1 }
103    
104     os_vm_address_t
105     os_map(int fd, int offset, os_vm_address_t addr, os_vm_size_t len)
106     {
107 rtoy 1.7 int i;
108 hallgren 1.1
109 rtoy 1.7 addr = os_trunc_to_page(addr);
110     len = os_round_up_size_to_page(len);
111 hallgren 1.1
112 rtoy 1.7 if (mmap(addr, len, OS_VM_PROT_ALL, MAP_FILE | MAP_FIXED | MAP_PRIVATE, fd,
113     (off_t) offset) == (os_vm_address_t) - 1) {
114     perror("mmap");
115     return NULL;
116     }
117 hallgren 1.1
118 rtoy 1.7 for (i = 0; i < MAX_SEGMENTS; i++)
119     if (segments[i].len != 0 && segments[i].base == addr)
120     break;
121 hallgren 1.1
122 rtoy 1.7 assert(i != MAX_SEGMENTS);
123     assert(segments[i].valid == addr);
124 hallgren 1.1
125 rtoy 1.7 segments[i].valid = addr + len;
126 hallgren 1.1 #ifdef DEBUG
127 rtoy 1.7 printf("os_map: addr: 0x%X, len: 0x%X, end: 0x%X\n", addr, len, addr + len);
128 hallgren 1.1 #endif
129 rtoy 1.7 return addr;
130 hallgren 1.1 }
131    
132     void
133     os_flush_icache(os_vm_address_t address, os_vm_size_t length)
134     {
135 rtoy 1.7 sanctify_for_execution(address, length);
136 hallgren 1.1 }
137    
138     void
139     os_protect(os_vm_address_t addr, os_vm_size_t len, os_vm_prot_t prot)
140     {
141 rtoy 1.7 int i;
142    
143     addr = os_trunc_to_page(addr);
144     len = os_round_up_size_to_page(len);
145    
146     for (i = 0; i < MAX_SEGMENTS; i++)
147     if (segments[i].base <= addr
148     && addr < segments[i].base + segments[i].len) break;
149    
150     assert(i != MAX_SEGMENTS);
151    
152     if (prot) {
153     assert(segments[i].base == addr && segments[i].len == len);
154     segments[i].protected = addr + len;
155     } else {
156     assert(segments[i].protected == addr + len);
157     segments[i].protected = addr;
158 hallgren 1.1 }
159 rtoy 1.7
160     if (addr < segments[i].valid)
161     if (mprotect(addr, segments[i].valid - addr, prot) == -1) {
162     perror("mprotect");
163     printf("segments[i].base: 0x%X\n", segments[i].base);
164     printf("segments[i].len: 0x%X\n", segments[i].len);
165     printf("segments[i].valid: 0x%X\n", segments[i].valid);
166     printf("addr: 0x%X, segments[i].valid-addr: 0x%X\n", addr,
167     segments[i].valid - addr);
168     printf("prot: 0x%X, len 0x%X\n", prot, len);
169     assert(FALSE);
170     }
171 hallgren 1.1 #ifdef DEBUG
172 rtoy 1.7 printf("os_protect: addr: 0x%X, len: 0x%X, end: 0x%X, prot 0x%X\n",
173     addr, len, addr + len, prot);
174 hallgren 1.1 #endif
175     }
176    
177 rtoy 1.7 boolean valid_addr(os_vm_address_t addr)
178 hallgren 1.1 {
179 rtoy 1.7 int i;
180 hallgren 1.1
181 rtoy 1.7 for (i = 0; i < MAX_SEGMENTS; i++)
182     if (segments[i].base <= addr
183     && addr < segments[i].base + segments[i].len) return TRUE;
184     return FALSE;
185 hallgren 1.1 }
186    
187     void
188     segv_handler(int signal, int code, struct sigcontext *context)
189     {
190 rtoy 1.7 int i;
191     os_vm_address_t addr, nvalid;
192    
193     sigsetmask(BLOCKABLE);
194    
195     addr = (os_vm_address_t) context->sc_sl.sl_ss.ss_cr21; /* verify this!!! */
196     for (i = 0; i < MAX_SEGMENTS; i++)
197     if (segments[i].len != 0 && segments[i].base <= addr &&
198     addr < segments[i].base + segments[i].len)
199     break;
200     if (i == MAX_SEGMENTS || addr < segments[i].valid)
201     interrupt_handle_now(signal, code, context);
202     else if (segments[i].protected <= addr) {
203     if (!interrupt_maybe_gc(signal, code, context))
204     interrupt_handle_now(signal, code, context);
205     } else {
206     nvalid =
207     ((os_vm_address_t)
208     (((long) (addr + ALLOC_SIZE)) & ~((long) (ALLOC_SIZE - 1))));
209     if (nvalid > segments[i].protected)
210     nvalid = segments[i].protected;
211 hallgren 1.1
212     #ifdef DEBUG
213 rtoy 1.7 printf("Mapping: addr: 0x%08x, old: 0x%08x, new: 0x%08x\n",
214     addr, segments[i].valid, nvalid);
215 hallgren 1.1 #endif
216    
217 rtoy 1.7 if (mmap(segments[i].valid, nvalid - segments[i].valid,
218     OS_VM_PROT_ALL, MAP_ANONYMOUS | MAP_FIXED | MAP_PRIVATE, -1,
219     0) == (os_vm_address_t) - 1) {
220     perror("mmap");
221     printf("segments[i].base: 0x%X\n", segments[i].base);
222     printf("segments[i].len: 0x%X\n", segments[i].len);
223     printf("segments[i].valid: 0x%X\n", segments[i].valid);
224     printf("segments[i].protected: 0x%X\n", segments[i].protected);
225     printf("nvalid: 0x%X\n", nvalid);
226     printf("nvalid-segments[i].valid: 0x%X\n",
227     nvalid - segments[i].valid);
228     assert(FALSE);
229     }
230     segments[i].valid = nvalid;
231 hallgren 1.1 }
232     }
233    
234     void
235     sigbus_handler(int signal, int code, struct sigcontext *context)
236     {
237     #ifdef DEBUG
238 rtoy 1.7 printf("Bus Error at 0x%X\n", context->sc_sl.sl_ss.ss_cr21);
239 hallgren 1.1 #endif
240    
241 rtoy 1.7 if (!interrupt_maybe_gc(signal, code, context))
242     interrupt_handle_now(signal, code, context);
243 hallgren 1.1 }
244    
245     void
246 cshapiro 1.8 os_install_interrupt_handlers(void)
247 hallgren 1.1 {
248 rtoy 1.7 interrupt_install_low_level_handler(SIGSEGV, segv_handler);
249     interrupt_install_low_level_handler(SIGBUS, sigbus_handler);
250 hallgren 1.1 }
251    
252     void
253 rtoy 1.7 os_zero(os_vm_address_t addr, os_vm_size_t length)
254 hallgren 1.1 {
255     os_vm_address_t block_start;
256     os_vm_size_t block_size;
257     int i;
258    
259 emarsden 1.5 #ifdef PRINTNOISE
260 rtoy 1.7 fprintf(stderr, "os_zero: addr: 0x%08x, len: 0x%08x, end: 0x%X\n", addr,
261     length, addr + length);
262 hallgren 1.1 #endif
263    
264 rtoy 1.7 block_start = os_round_up_to_page(addr);
265 hallgren 1.1
266 rtoy 1.7 length -= block_start - addr;
267     block_size = os_trunc_size_to_page(length);
268    
269     if (block_start > addr)
270     memset((char *) addr, 0, block_start - addr);
271     if (block_size < length)
272     assert(FALSE);
273 hallgren 1.1
274     if (block_size != 0) {
275     /* Now deallocate and allocate the block so that it */
276     /* faults in zero-filled. */
277    
278 rtoy 1.7 for (i = 0; i < MAX_SEGMENTS; i++)
279     if (segments[i].base <= block_start &&
280     block_start < segments[i].base + segments[i].len)
281     break;
282     assert(i != MAX_SEGMENTS);
283     assert(block_start + block_size == segments[i].base + segments[i].len);
284    
285     if (segments[i].valid > block_start) {
286     if (munmap(block_start, segments[i].valid - block_start) == -1) {
287     perror("munmap");
288     return;
289     }
290     segments[i].valid = block_start;
291 hallgren 1.1 }
292     }
293     }
294    
295 rtoy 1.7 os_vm_address_t os_allocate(os_vm_size_t len)
296 hallgren 1.1 {
297 rtoy 1.7 return (os_vm_address_t) malloc(len);
298 hallgren 1.1 }
299    
300 rtoy 1.7 os_vm_address_t os_allocate_at(os_vm_address_t addr, os_vm_size_t len)
301 hallgren 1.1 {
302 rtoy 1.7 return os_validate(addr, len);
303 hallgren 1.1 }
304    
305     void
306 rtoy 1.7 os_deallocate(os_vm_address_t addr, os_vm_size_t len)
307 hallgren 1.1 {
308 rtoy 1.7 free(addr);
309 hallgren 1.1 }
310    
311     os_vm_address_t
312 rtoy 1.7 os_reallocate(os_vm_address_t addr, os_vm_size_t old_len, os_vm_size_t len)
313     {
314     addr = (os_vm_address_t) realloc(addr, len);
315     assert(addr != NULL);
316     return addr;
317     }
318    
319     int
320     getrusage(int who, struct rusage *rusage)
321 hallgren 1.1 {
322 rtoy 1.7 static long ticks_per_sec = 0;
323     static long usec_per_tick = 0;
324     struct tms buf;
325     clock_t uticks, sticks;
326    
327     memset(rusage, 0, sizeof(struct rusage));
328    
329     if (ticks_per_sec == 0) {
330     ticks_per_sec = sysconf(_SC_CLK_TCK);
331     usec_per_tick = 1000000 / ticks_per_sec;
332     }
333    
334     if (times(&buf) == -1)
335     return -1;
336    
337     if (who == RUSAGE_SELF) {
338     uticks = buf.tms_utime;
339     sticks = buf.tms_stime;
340     } else if (who == RUSAGE_CHILDREN) {
341     uticks = buf.tms_utime;
342     sticks = buf.tms_stime;
343     } else {
344     errno = EINVAL;
345     return -1;
346     }
347 wlott 1.4
348 rtoy 1.7 rusage->ru_utime.tv_sec = uticks / ticks_per_sec;
349     rusage->ru_utime.tv_usec = (uticks % ticks_per_sec) * usec_per_tick;
350     rusage->ru_stime.tv_sec = sticks / ticks_per_sec;
351     rusage->ru_stime.tv_usec = (sticks % ticks_per_sec) * usec_per_tick;
352    
353     return 0;
354 hallgren 1.1 }
355    
356     int
357     getdtablesize(void)
358     {
359 rtoy 1.7 struct rlimit rlp;
360    
361     assert(getrlimit(RLIMIT_NOFILE, &rlp) == 0);
362     return rlp.rlim_cur;
363 hallgren 1.1 }
364    
365     unsigned long
366     gethostid(void)
367     {
368 rtoy 1.7 char hostname[256];
369     struct hostent *hostent;
370     static unsigned long addr = NULL;
371    
372     if (addr)
373     return addr;
374    
375     if (gethostname(hostname, sizeof(hostname)) == -1) {
376     perror("gethostname");
377     return 0;
378     }
379 hallgren 1.1
380 rtoy 1.7 hostent = gethostbyname(hostname);
381     if (hostent == NULL) {
382     perror("gethostbyname");
383     return 0;
384     }
385 hallgren 1.1
386 rtoy 1.7 addr = ((unsigned char *) (hostent->h_addr))[0] << 24 |
387     ((unsigned char *) (hostent->h_addr))[1] << 16 |
388     ((unsigned char *) (hostent->h_addr))[2] << 8 |
389     ((unsigned char *) (hostent->h_addr))[3];
390 hallgren 1.1
391 rtoy 1.7 return addr;
392 hallgren 1.3 }
393    
394     int
395     getpagesize(void)
396     {
397 rtoy 1.7 return os_vm_page_size;
398 hallgren 1.1 }

  ViewVC Help
Powered by ViewVC 1.1.5