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

  ViewVC Help
Powered by ViewVC 1.1.5