/[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.7 - (hide annotations)
Thu Sep 15 18:26:51 2005 UTC (8 years, 7 months ago) by rtoy
Branch: MAIN
CVS Tags: double-double-array-base, double-double-init-sparc-2, double-double-base, snapshot-2007-09, snapshot-2007-08, snapshot-2007-05, snapshot-2008-01, snapshot-2008-02, snapshot-2008-03, snapshot-2006-11, snapshot-2006-10, double-double-init-sparc, snapshot-2006-12, snapshot-2007-01, snapshot-2007-02, release-19e, release-19d, double-double-init-ppc, release-19c, release-19c-base, double-double-init-%make-sparc, snapshot-2007-03, snapshot-2007-04, snapshot-2007-07, snapshot-2007-06, double-double-array-checkpoint, double-double-reader-checkpoint-1, release-19d-base, release-19e-pre1, double-double-irrat-end, release-19e-pre2, release-19d-pre2, release-19d-pre1, double-double-init-checkpoint-1, double-double-reader-base, double-double-init-x86, snapshot-2005-11, double-double-sparc-checkpoint-1, snapshot-2005-10, snapshot-2005-12, release-19c-pre1, release-19e-base, double-double-irrat-start, snapshot-2007-12, snapshot-2007-10, snapshot-2007-11, snapshot-2006-02, snapshot-2006-03, snapshot-2006-01, snapshot-2006-06, snapshot-2006-07, snapshot-2006-04, snapshot-2006-05, pre-telent-clx, snapshot-2006-08, snapshot-2006-09
Branch point for: double-double-reader-branch, double-double-array-branch, release-19d-branch, double-double-branch, release-19e-branch, release-19c-branch
Changes since 1.6: +227 -220 lines
File MIME type: text/plain
Indent all source files using GNU indent using the config in
.indent.pro.
1 hallgren 1.1 /*
2 rtoy 1.7 * $Header: /tiger/var/lib/cvsroots/cmucl/src/lisp/hpux-os.c,v 1.7 2005/09/15 18:26:51 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     os_init()
57     {
58 rtoy 1.7 int i;
59    
60     os_vm_page_size = sysconf(_SC_PAGE_SIZE);
61     for (i = 0; i < MAX_SEGMENTS; i++)
62     segments[i].len = 0;
63 hallgren 1.1 }
64    
65    
66 rtoy 1.7 os_vm_address_t os_validate(os_vm_address_t addr, os_vm_size_t len)
67 hallgren 1.1 {
68 rtoy 1.7 int fd, i;
69     caddr_t ret;
70 hallgren 1.1
71 rtoy 1.7 addr = os_trunc_to_page(addr);
72     len = os_round_up_size_to_page(len);
73 hallgren 1.1
74     #ifdef DEBUG
75 rtoy 1.7 printf("os_validate: addr: 0x%X, len: 0x%X, end: 0x%X\n", addr, len,
76     addr + len);
77     #endif
78     assert(addr != NULL);
79     assert(len != 0);
80    
81     for (i = 0; i < MAX_SEGMENTS; i++)
82     if (segments[i].len == 0)
83     break;
84    
85     assert(i != MAX_SEGMENTS);
86    
87     segments[i].base = addr;
88     segments[i].len = len;
89     segments[i].valid = addr;
90     segments[i].protected = addr + len;
91     return addr;
92 hallgren 1.1 }
93    
94     void
95     os_invalidate(os_vm_address_t addr, os_vm_size_t len)
96     {
97 rtoy 1.7 assert(FALSE);
98 hallgren 1.1 }
99    
100     os_vm_address_t
101     os_map(int fd, int offset, os_vm_address_t addr, os_vm_size_t len)
102     {
103 rtoy 1.7 int i;
104 hallgren 1.1
105 rtoy 1.7 addr = os_trunc_to_page(addr);
106     len = os_round_up_size_to_page(len);
107 hallgren 1.1
108 rtoy 1.7 if (mmap(addr, len, OS_VM_PROT_ALL, MAP_FILE | MAP_FIXED | MAP_PRIVATE, fd,
109     (off_t) offset) == (os_vm_address_t) - 1) {
110     perror("mmap");
111     return NULL;
112     }
113 hallgren 1.1
114 rtoy 1.7 for (i = 0; i < MAX_SEGMENTS; i++)
115     if (segments[i].len != 0 && segments[i].base == addr)
116     break;
117 hallgren 1.1
118 rtoy 1.7 assert(i != MAX_SEGMENTS);
119     assert(segments[i].valid == addr);
120 hallgren 1.1
121 rtoy 1.7 segments[i].valid = addr + len;
122 hallgren 1.1 #ifdef DEBUG
123 rtoy 1.7 printf("os_map: addr: 0x%X, len: 0x%X, end: 0x%X\n", addr, len, addr + len);
124 hallgren 1.1 #endif
125 rtoy 1.7 return addr;
126 hallgren 1.1 }
127    
128     void
129     os_flush_icache(os_vm_address_t address, os_vm_size_t length)
130     {
131 rtoy 1.7 sanctify_for_execution(address, length);
132 hallgren 1.1 }
133    
134     void
135     os_protect(os_vm_address_t addr, os_vm_size_t len, os_vm_prot_t prot)
136     {
137 rtoy 1.7 int i;
138    
139     addr = os_trunc_to_page(addr);
140     len = os_round_up_size_to_page(len);
141    
142     for (i = 0; i < MAX_SEGMENTS; i++)
143     if (segments[i].base <= addr
144     && addr < segments[i].base + segments[i].len) break;
145    
146     assert(i != MAX_SEGMENTS);
147    
148     if (prot) {
149     assert(segments[i].base == addr && segments[i].len == len);
150     segments[i].protected = addr + len;
151     } else {
152     assert(segments[i].protected == addr + len);
153     segments[i].protected = addr;
154 hallgren 1.1 }
155 rtoy 1.7
156     if (addr < segments[i].valid)
157     if (mprotect(addr, segments[i].valid - addr, prot) == -1) {
158     perror("mprotect");
159     printf("segments[i].base: 0x%X\n", segments[i].base);
160     printf("segments[i].len: 0x%X\n", segments[i].len);
161     printf("segments[i].valid: 0x%X\n", segments[i].valid);
162     printf("addr: 0x%X, segments[i].valid-addr: 0x%X\n", addr,
163     segments[i].valid - addr);
164     printf("prot: 0x%X, len 0x%X\n", prot, len);
165     assert(FALSE);
166     }
167 hallgren 1.1 #ifdef DEBUG
168 rtoy 1.7 printf("os_protect: addr: 0x%X, len: 0x%X, end: 0x%X, prot 0x%X\n",
169     addr, len, addr + len, prot);
170 hallgren 1.1 #endif
171     }
172    
173 rtoy 1.7 boolean valid_addr(os_vm_address_t addr)
174 hallgren 1.1 {
175 rtoy 1.7 int i;
176 hallgren 1.1
177 rtoy 1.7 for (i = 0; i < MAX_SEGMENTS; i++)
178     if (segments[i].base <= addr
179     && addr < segments[i].base + segments[i].len) return TRUE;
180     return FALSE;
181 hallgren 1.1 }
182    
183     void
184     segv_handler(int signal, int code, struct sigcontext *context)
185     {
186 rtoy 1.7 int i;
187     os_vm_address_t addr, nvalid;
188    
189     sigsetmask(BLOCKABLE);
190    
191     addr = (os_vm_address_t) context->sc_sl.sl_ss.ss_cr21; /* verify this!!! */
192     for (i = 0; i < MAX_SEGMENTS; i++)
193     if (segments[i].len != 0 && segments[i].base <= addr &&
194     addr < segments[i].base + segments[i].len)
195     break;
196     if (i == MAX_SEGMENTS || addr < segments[i].valid)
197     interrupt_handle_now(signal, code, context);
198     else if (segments[i].protected <= addr) {
199     if (!interrupt_maybe_gc(signal, code, context))
200     interrupt_handle_now(signal, code, context);
201     } else {
202     nvalid =
203     ((os_vm_address_t)
204     (((long) (addr + ALLOC_SIZE)) & ~((long) (ALLOC_SIZE - 1))));
205     if (nvalid > segments[i].protected)
206     nvalid = segments[i].protected;
207 hallgren 1.1
208     #ifdef DEBUG
209 rtoy 1.7 printf("Mapping: addr: 0x%08x, old: 0x%08x, new: 0x%08x\n",
210     addr, segments[i].valid, nvalid);
211 hallgren 1.1 #endif
212    
213 rtoy 1.7 if (mmap(segments[i].valid, nvalid - segments[i].valid,
214     OS_VM_PROT_ALL, MAP_ANONYMOUS | MAP_FIXED | MAP_PRIVATE, -1,
215     0) == (os_vm_address_t) - 1) {
216     perror("mmap");
217     printf("segments[i].base: 0x%X\n", segments[i].base);
218     printf("segments[i].len: 0x%X\n", segments[i].len);
219     printf("segments[i].valid: 0x%X\n", segments[i].valid);
220     printf("segments[i].protected: 0x%X\n", segments[i].protected);
221     printf("nvalid: 0x%X\n", nvalid);
222     printf("nvalid-segments[i].valid: 0x%X\n",
223     nvalid - segments[i].valid);
224     assert(FALSE);
225     }
226     segments[i].valid = nvalid;
227 hallgren 1.1 }
228     }
229    
230     void
231     sigbus_handler(int signal, int code, struct sigcontext *context)
232     {
233     #ifdef DEBUG
234 rtoy 1.7 printf("Bus Error at 0x%X\n", context->sc_sl.sl_ss.ss_cr21);
235 hallgren 1.1 #endif
236    
237 rtoy 1.7 if (!interrupt_maybe_gc(signal, code, context))
238     interrupt_handle_now(signal, code, context);
239 hallgren 1.1 }
240    
241     void
242     os_install_interrupt_handlers()
243     {
244 rtoy 1.7 interrupt_install_low_level_handler(SIGSEGV, segv_handler);
245     interrupt_install_low_level_handler(SIGBUS, sigbus_handler);
246 hallgren 1.1 }
247    
248     void
249 rtoy 1.7 os_zero(os_vm_address_t addr, os_vm_size_t length)
250 hallgren 1.1 {
251     os_vm_address_t block_start;
252     os_vm_size_t block_size;
253     int i;
254    
255 emarsden 1.5 #ifdef PRINTNOISE
256 rtoy 1.7 fprintf(stderr, "os_zero: addr: 0x%08x, len: 0x%08x, end: 0x%X\n", addr,
257     length, addr + length);
258 hallgren 1.1 #endif
259    
260 rtoy 1.7 block_start = os_round_up_to_page(addr);
261 hallgren 1.1
262 rtoy 1.7 length -= block_start - addr;
263     block_size = os_trunc_size_to_page(length);
264    
265     if (block_start > addr)
266     memset((char *) addr, 0, block_start - addr);
267     if (block_size < length)
268     assert(FALSE);
269 hallgren 1.1
270     if (block_size != 0) {
271     /* Now deallocate and allocate the block so that it */
272     /* faults in zero-filled. */
273    
274 rtoy 1.7 for (i = 0; i < MAX_SEGMENTS; i++)
275     if (segments[i].base <= block_start &&
276     block_start < segments[i].base + segments[i].len)
277     break;
278     assert(i != MAX_SEGMENTS);
279     assert(block_start + block_size == segments[i].base + segments[i].len);
280    
281     if (segments[i].valid > block_start) {
282     if (munmap(block_start, segments[i].valid - block_start) == -1) {
283     perror("munmap");
284     return;
285     }
286     segments[i].valid = block_start;
287 hallgren 1.1 }
288     }
289     }
290    
291 rtoy 1.7 os_vm_address_t os_allocate(os_vm_size_t len)
292 hallgren 1.1 {
293 rtoy 1.7 return (os_vm_address_t) malloc(len);
294 hallgren 1.1 }
295    
296 rtoy 1.7 os_vm_address_t os_allocate_at(os_vm_address_t addr, os_vm_size_t len)
297 hallgren 1.1 {
298 rtoy 1.7 return os_validate(addr, len);
299 hallgren 1.1 }
300    
301     void
302 rtoy 1.7 os_deallocate(os_vm_address_t addr, os_vm_size_t len)
303 hallgren 1.1 {
304 rtoy 1.7 free(addr);
305 hallgren 1.1 }
306    
307     os_vm_address_t
308 rtoy 1.7 os_reallocate(os_vm_address_t addr, os_vm_size_t old_len, os_vm_size_t len)
309     {
310     addr = (os_vm_address_t) realloc(addr, len);
311     assert(addr != NULL);
312     return addr;
313     }
314    
315     int
316     getrusage(int who, struct rusage *rusage)
317 hallgren 1.1 {
318 rtoy 1.7 static long ticks_per_sec = 0;
319     static long usec_per_tick = 0;
320     struct tms buf;
321     clock_t uticks, sticks;
322    
323     memset(rusage, 0, sizeof(struct rusage));
324    
325     if (ticks_per_sec == 0) {
326     ticks_per_sec = sysconf(_SC_CLK_TCK);
327     usec_per_tick = 1000000 / ticks_per_sec;
328     }
329    
330     if (times(&buf) == -1)
331     return -1;
332    
333     if (who == RUSAGE_SELF) {
334     uticks = buf.tms_utime;
335     sticks = buf.tms_stime;
336     } else if (who == RUSAGE_CHILDREN) {
337     uticks = buf.tms_utime;
338     sticks = buf.tms_stime;
339     } else {
340     errno = EINVAL;
341     return -1;
342     }
343 wlott 1.4
344 rtoy 1.7 rusage->ru_utime.tv_sec = uticks / ticks_per_sec;
345     rusage->ru_utime.tv_usec = (uticks % ticks_per_sec) * usec_per_tick;
346     rusage->ru_stime.tv_sec = sticks / ticks_per_sec;
347     rusage->ru_stime.tv_usec = (sticks % ticks_per_sec) * usec_per_tick;
348    
349     return 0;
350 hallgren 1.1 }
351    
352     int
353     getdtablesize(void)
354     {
355 rtoy 1.7 struct rlimit rlp;
356    
357     assert(getrlimit(RLIMIT_NOFILE, &rlp) == 0);
358     return rlp.rlim_cur;
359 hallgren 1.1 }
360    
361     unsigned long
362     gethostid(void)
363     {
364 rtoy 1.7 char hostname[256];
365     struct hostent *hostent;
366     static unsigned long addr = NULL;
367    
368     if (addr)
369     return addr;
370    
371     if (gethostname(hostname, sizeof(hostname)) == -1) {
372     perror("gethostname");
373     return 0;
374     }
375 hallgren 1.1
376 rtoy 1.7 hostent = gethostbyname(hostname);
377     if (hostent == NULL) {
378     perror("gethostbyname");
379     return 0;
380     }
381 hallgren 1.1
382 rtoy 1.7 addr = ((unsigned char *) (hostent->h_addr))[0] << 24 |
383     ((unsigned char *) (hostent->h_addr))[1] << 16 |
384     ((unsigned char *) (hostent->h_addr))[2] << 8 |
385     ((unsigned char *) (hostent->h_addr))[3];
386 hallgren 1.1
387 rtoy 1.7 return addr;
388 hallgren 1.3 }
389    
390     int
391     getpagesize(void)
392     {
393 rtoy 1.7 return os_vm_page_size;
394 hallgren 1.1 }

  ViewVC Help
Powered by ViewVC 1.1.5