/[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 - (hide 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 hallgren 1.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