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

  ViewVC Help
Powered by ViewVC 1.1.5