/[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 - (show annotations)
Sat Jul 19 14:10:16 2003 UTC (10 years, 9 months ago) by emarsden
Branch: MAIN
CVS Tags: release-19b-pre1, release-19b-pre2, snapshot-2003-10, snapshot-2004-10, snapshot-2004-08, snapshot-2004-09, snapshot-2004-05, snapshot-2004-06, snapshot-2004-07, dynamic-extent-base, mod-arith-base, sparc_gencgc_merge, snapshot-2004-12, snapshot-2004-11, amd64-merge-start, prm-before-macosx-merge-tag, snapshot-2003-11, snapshot-2005-07, release-19a-base, sparc_gencgc, snapshot-2003-12, release-19a-pre1, release-19a-pre3, release-19a-pre2, release-19a, snapshot-2005-03, release-19b-base, snapshot-2004-04, snapshot-2005-01, snapshot-2005-06, snapshot-2005-05, snapshot-2005-04, ppc_gencgc_snap_2005-05-14, snapshot-2005-02, snapshot-2005-09, snapshot-2005-08, lisp-executable-base
Branch point for: release-19b-branch, mod-arith-branch, sparc_gencgc_branch, dynamic-extent, ppc_gencgc_branch, lisp-executable, release-19a-branch
Changes since 1.4: +2 -2 lines
File MIME type: text/plain
  - fix a signed/unsigned cast bug that was prevented the
    auto-gc-trigger from functioning correctly when using certain
    dynamic-space sizes (for platforms that don't have an internal gc
    trigger).

  - added a few #include files to avoid compiler warnings

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

  ViewVC Help
Powered by ViewVC 1.1.5