/[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.5.12.1 - (show annotations)
Mon Dec 19 01:10:13 2005 UTC (8 years, 4 months ago) by rtoy
Branch: ppc_gencgc_branch
CVS Tags: ppc_gencgc_snap_2006-01-06, ppc_gencgc_snap_2005-12-17
Changes since 1.5: +227 -220 lines
File MIME type: text/plain
Merge code from main branch of 2005-12-17 to ppc gencgc branch.  Still
doesn't work of course.
1 /*
2 * $Header: /tiger/var/lib/cvsroots/cmucl/src/lisp/hpux-os.c,v 1.5.12.1 2005/12/19 01:10:13 rtoy Exp $
3 *
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 #include <sys/times.h>
42 #include <errno.h>
43
44 os_vm_size_t os_vm_page_size = (-1);
45
46 #define MAX_SEGMENTS 20
47 #define ALLOC_SIZE 0x10000
48 static struct segment {
49 os_vm_address_t base;
50 os_vm_size_t len;
51 os_vm_address_t valid;
52 os_vm_address_t protected;
53 } segments[MAX_SEGMENTS];
54
55 void
56 os_init()
57 {
58 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 }
64
65
66 os_vm_address_t os_validate(os_vm_address_t addr, os_vm_size_t len)
67 {
68 int fd, i;
69 caddr_t ret;
70
71 addr = os_trunc_to_page(addr);
72 len = os_round_up_size_to_page(len);
73
74 #ifdef DEBUG
75 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 }
93
94 void
95 os_invalidate(os_vm_address_t addr, os_vm_size_t len)
96 {
97 assert(FALSE);
98 }
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 int i;
104
105 addr = os_trunc_to_page(addr);
106 len = os_round_up_size_to_page(len);
107
108 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
114 for (i = 0; i < MAX_SEGMENTS; i++)
115 if (segments[i].len != 0 && segments[i].base == addr)
116 break;
117
118 assert(i != MAX_SEGMENTS);
119 assert(segments[i].valid == addr);
120
121 segments[i].valid = addr + len;
122 #ifdef DEBUG
123 printf("os_map: addr: 0x%X, len: 0x%X, end: 0x%X\n", addr, len, addr + len);
124 #endif
125 return addr;
126 }
127
128 void
129 os_flush_icache(os_vm_address_t address, os_vm_size_t length)
130 {
131 sanctify_for_execution(address, length);
132 }
133
134 void
135 os_protect(os_vm_address_t addr, os_vm_size_t len, os_vm_prot_t prot)
136 {
137 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 }
155
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 #ifdef DEBUG
168 printf("os_protect: addr: 0x%X, len: 0x%X, end: 0x%X, prot 0x%X\n",
169 addr, len, addr + len, prot);
170 #endif
171 }
172
173 boolean valid_addr(os_vm_address_t addr)
174 {
175 int i;
176
177 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 }
182
183 void
184 segv_handler(int signal, int code, struct sigcontext *context)
185 {
186 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
208 #ifdef DEBUG
209 printf("Mapping: addr: 0x%08x, old: 0x%08x, new: 0x%08x\n",
210 addr, segments[i].valid, nvalid);
211 #endif
212
213 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 }
228 }
229
230 void
231 sigbus_handler(int signal, int code, struct sigcontext *context)
232 {
233 #ifdef DEBUG
234 printf("Bus Error at 0x%X\n", context->sc_sl.sl_ss.ss_cr21);
235 #endif
236
237 if (!interrupt_maybe_gc(signal, code, context))
238 interrupt_handle_now(signal, code, context);
239 }
240
241 void
242 os_install_interrupt_handlers()
243 {
244 interrupt_install_low_level_handler(SIGSEGV, segv_handler);
245 interrupt_install_low_level_handler(SIGBUS, sigbus_handler);
246 }
247
248 void
249 os_zero(os_vm_address_t addr, os_vm_size_t length)
250 {
251 os_vm_address_t block_start;
252 os_vm_size_t block_size;
253 int i;
254
255 #ifdef PRINTNOISE
256 fprintf(stderr, "os_zero: addr: 0x%08x, len: 0x%08x, end: 0x%X\n", addr,
257 length, addr + length);
258 #endif
259
260 block_start = os_round_up_to_page(addr);
261
262 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
270 if (block_size != 0) {
271 /* Now deallocate and allocate the block so that it */
272 /* faults in zero-filled. */
273
274 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 }
288 }
289 }
290
291 os_vm_address_t os_allocate(os_vm_size_t len)
292 {
293 return (os_vm_address_t) malloc(len);
294 }
295
296 os_vm_address_t os_allocate_at(os_vm_address_t addr, os_vm_size_t len)
297 {
298 return os_validate(addr, len);
299 }
300
301 void
302 os_deallocate(os_vm_address_t addr, os_vm_size_t len)
303 {
304 free(addr);
305 }
306
307 os_vm_address_t
308 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 {
318 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
344 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 }
351
352 int
353 getdtablesize(void)
354 {
355 struct rlimit rlp;
356
357 assert(getrlimit(RLIMIT_NOFILE, &rlp) == 0);
358 return rlp.rlim_cur;
359 }
360
361 unsigned long
362 gethostid(void)
363 {
364 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
376 hostent = gethostbyname(hostname);
377 if (hostent == NULL) {
378 perror("gethostbyname");
379 return 0;
380 }
381
382 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
387 return addr;
388 }
389
390 int
391 getpagesize(void)
392 {
393 return os_vm_page_size;
394 }

  ViewVC Help
Powered by ViewVC 1.1.5