From c159b7a71f76ada52ffe743b3b249b4b2420c2c7 Mon Sep 17 00:00:00 2001 From: hallgren <hallgren> Date: Tue, 27 Jul 1993 16:02:04 +0000 Subject: [PATCH] Initial revision --- lisp/hpux-os.c | 348 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 348 insertions(+) create mode 100644 lisp/hpux-os.c diff --git a/lisp/hpux-os.c b/lisp/hpux-os.c new file mode 100644 index 000000000..73459276e --- /dev/null +++ b/lisp/hpux-os.c @@ -0,0 +1,348 @@ +/* + * $Header: /Volumes/share2/src/cmucl/cvs2git/cvsroot/src/lisp/hpux-os.c,v 1.1 1993/07/27 16:02:04 hallgren Exp $ + * + * OS-dependent routines. This file (along with os.h) exports an + * OS-independent interface to the operating system VM facilities. + * Suprisingly, this interface looks a lot like the Mach interface + * (but simpler in some places). For some operating systems, a subset + * of these functions will have to be emulated. + * + */ + +/* Assumptions these routines are based on: +os_validate: Not called with NULL for an addr. +os_invalidate: Never called. +os_map: Files are only mapped at the beginning of one of the areas passed + to os_validate. +os_protect: Only called on an entire region when giving permissions and only + called from some point in a segment to the end of the segment + when removing them. + Only called with all protections or no protections. +os_zero: Only ever zeroed from some point in a segment to the end of the + segment. +os_allocate_at: Calls to here are disjoint from those around it (the others + in os-common.c) since it calls os_validate and the others (in + os-common.c) use malloc, etc. +Note that os_validate does not actually allocate memory until it has to map +the particular section in. +*/ + +/* #define DEBUG */ + +#include <stdio.h> +#include <assert.h> +#include <signal.h> +#include <sys/file.h> +#include <unistd.h> +#include "os.h" +#include <sys/resource.h> +#include "interrupt.h" +#include <netdb.h> + +os_vm_size_t os_vm_page_size=(-1); + +#define MAX_SEGMENTS 20 +#define ALLOC_SIZE 0x10000 +static struct segment { + os_vm_address_t base; + os_vm_size_t len; + os_vm_address_t valid; + os_vm_address_t protected; +} segments[MAX_SEGMENTS]; + +void +os_init() +{ + int i; + os_vm_page_size=sysconf(_SC_PAGE_SIZE); + for(i=0;i<MAX_SEGMENTS;i++) + segments[i].len=0; +} + + +os_vm_address_t +os_validate(os_vm_address_t addr, os_vm_size_t len) +{ + int fd,i; + caddr_t ret; + + addr=os_trunc_to_page(addr); + len=os_round_up_size_to_page(len); + +#ifdef DEBUG + printf("os_validate: addr: 0x%X, len: 0x%X, end: 0x%X\n",addr,len,addr+len); +#endif + assert(addr!=NULL); + assert(len!=0); + + for(i=0;i<MAX_SEGMENTS;i++) + if(segments[i].len==0) break; + + assert(i!=MAX_SEGMENTS); + + segments[i].base=addr; + segments[i].len=len; + segments[i].valid=addr; + segments[i].protected=addr+len; + return addr; +} + +void +os_invalidate(os_vm_address_t addr, os_vm_size_t len) +{ + assert(FALSE); +} + +os_vm_address_t +os_map(int fd, int offset, os_vm_address_t addr, os_vm_size_t len) +{ + int i; + + addr=os_trunc_to_page(addr); + len=os_round_up_size_to_page(len); + + if(mmap(addr,len,OS_VM_PROT_ALL,MAP_FILE|MAP_FIXED|MAP_PRIVATE,fd, + (off_t)offset) == (os_vm_address_t)-1) { + perror("mmap"); + return NULL; + } + + for(i=0;i<MAX_SEGMENTS;i++) + if(segments[i].len!=0 && segments[i].base==addr) break; + + assert(i!=MAX_SEGMENTS); + assert(segments[i].valid==addr); + + segments[i].valid=addr+len; +#ifdef DEBUG + printf("os_map: addr: 0x%X, len: 0x%X, end: 0x%X\n",addr,len,addr+len); +#endif + return addr; +} + +void +os_flush_icache(os_vm_address_t address, os_vm_size_t length) +{ + sanctify_for_execution(address,length); +} + +void +os_protect(os_vm_address_t addr, os_vm_size_t len, os_vm_prot_t prot) +{ + int i; + addr=os_trunc_to_page(addr); + len=os_round_up_size_to_page(len); + + for(i=0;i<MAX_SEGMENTS;i++) + if(segments[i].base<=addr && addr<segments[i].base+segments[i].len) + break; + + assert(i!=MAX_SEGMENTS); + + if(prot) { + assert(segments[i].base==addr && segments[i].len==len); + segments[i].protected=addr+len; + } else { + assert(segments[i].protected==addr+len); + segments[i].protected=addr; + } + + if(addr<segments[i].valid) + if(mprotect(addr,segments[i].valid-addr,prot) == -1) { + perror("mprotect"); + printf("segments[i].base: 0x%X\n",segments[i].base); + printf("segments[i].len: 0x%X\n",segments[i].len); + printf("segments[i].valid: 0x%X\n",segments[i].valid); + printf("addr: 0x%X, segments[i].valid-addr: 0x%X\n",addr, + segments[i].valid-addr); + printf("prot: 0x%X, len 0x%X\n",prot,len); + assert(FALSE); + } +#ifdef DEBUG + printf("os_protect: addr: 0x%X, len: 0x%X, end: 0x%X, prot 0x%X\n", + addr,len,addr+len,prot); +#endif +} + +boolean +valid_addr(os_vm_address_t addr) +{ + int i; + + for(i=0;i<MAX_SEGMENTS;i++) + if(segments[i].base<=addr && addr<segments[i].base+segments[i].len) + return TRUE; + return FALSE; +} + +void +segv_handler(int signal, int code, struct sigcontext *context) +{ + int i; + os_vm_address_t addr,nvalid; + sigsetmask(BLOCKABLE); + + addr=(os_vm_address_t)context->sc_sl.sl_ss.ss_cr21; /* verify this!!! */ + for(i=0;i<MAX_SEGMENTS;i++) + if(segments[i].len!=0 && segments[i].base<=addr && + addr<segments[i].base+segments[i].len) + break; + if(i==MAX_SEGMENTS || addr<segments[i].valid) + interrupt_handle_now(signal,code,context); + else if(segments[i].protected<=addr) { + if(!interrupt_maybe_gc(signal,code,context)) + interrupt_handle_now(signal,code,context); + } else { + nvalid=((os_vm_address_t)(((long)(addr+ALLOC_SIZE))&~((long)(ALLOC_SIZE-1)))); + if(nvalid>segments[i].protected) nvalid=segments[i].protected; + +#ifdef DEBUG + printf("Mapping: addr: 0x%08x, old: 0x%08x, new: 0x%08x\n", + addr,segments[i].valid,nvalid); +#endif + + if(mmap(segments[i].valid,nvalid-segments[i].valid, + OS_VM_PROT_ALL,MAP_ANONYMOUS|MAP_FIXED|MAP_PRIVATE,-1,0) == + (os_vm_address_t)-1) { + perror("mmap"); + printf("segments[i].base: 0x%X\n",segments[i].base); + printf("segments[i].len: 0x%X\n",segments[i].len); + printf("segments[i].valid: 0x%X\n",segments[i].valid); + printf("segments[i].protected: 0x%X\n",segments[i].protected); + printf("nvalid: 0x%X\n",nvalid); + printf("nvalid-segments[i].valid: 0x%X\n",nvalid-segments[i].valid); + assert(FALSE); + } + segments[i].valid=nvalid; + } +} + +void +sigbus_handler(int signal, int code, struct sigcontext *context) +{ +#ifdef DEBUG + printf("Bus Error at 0x%X\n",context->sc_sl.sl_ss.ss_cr21); +#endif + + if(!interrupt_maybe_gc(signal, code, context)) + interrupt_handle_now(signal, code, context); +} + +void +os_install_interrupt_handlers() +{ + interrupt_install_low_level_handler(SIGSEGV,segv_handler); + interrupt_install_low_level_handler(SIGBUS,sigbus_handler); +} + +void +os_zero(os_vm_address_t addr,os_vm_size_t length) +{ + os_vm_address_t block_start; + os_vm_size_t block_size; + int i; + +#ifdef DEBUG + fprintf(stderr,"os_zero: addr: 0x%08x, len: 0x%08x, end: 0x%X\n",addr, + length,addr+length); +#endif + + block_start=os_round_up_to_page(addr); + + length-=block_start-addr; + block_size=os_trunc_size_to_page(length); + + if(block_start>addr) + bzero((char *)addr,block_start-addr); + if(block_size<length) + assert(FALSE); + + if (block_size != 0) { + /* Now deallocate and allocate the block so that it */ + /* faults in zero-filled. */ + + for(i=0;i<MAX_SEGMENTS;i++) + if(segments[i].base<=block_start && + block_start<segments[i].base+segments[i].len) + break; + assert(i!=MAX_SEGMENTS); + assert(block_start+block_size==segments[i].base+segments[i].len); + + if(segments[i].valid>block_start) { + if(munmap(block_start,segments[i].valid-block_start)==-1) { + perror("munmap"); + return; + } + segments[i].valid=block_start; + } + } +} + +os_vm_address_t +os_allocate(os_vm_size_t len) +{ + return (os_vm_address_t) malloc(len); +} + +os_vm_address_t +os_allocate_at(os_vm_address_t addr, os_vm_size_t len) +{ + return os_validate(addr, len); +} + +void +os_deallocate(os_vm_address_t addr,os_vm_size_t len) +{ + free(addr); +} + +os_vm_address_t +os_reallocate(os_vm_address_t addr, os_vm_size_t old_len, + os_vm_size_t len) +{ + addr=(os_vm_address_t) realloc(addr,len); + assert(addr!=NULL); + return addr; +} + +void +getrusage(int who,struct rusage *rusage) +{ + bzero(rusage,sizeof(struct rusage)); +} + +int +getdtablesize(void) +{ + struct rlimit rlp; + assert(getrlimit(RLIMIT_NOFILE,&rlp)==0); + return rlp.rlim_cur; +} + +unsigned long +gethostid(void) +{ + char hostname[256]; + struct hostent *hostent; + static unsigned long addr=NULL; + + if(addr) return addr; + + if(gethostname(hostname, sizeof(hostname)) == -1) { + perror("gethostname"); + return 0; + } + + hostent = gethostbyname(hostname); + if(hostent == NULL) { + perror("gethostbyname"); + return 0; + } + + addr = ((unsigned char *)(hostent->h_addr))[0] << 24 | + ((unsigned char *)(hostent->h_addr))[1] << 16 | + ((unsigned char *)(hostent->h_addr))[2] << 8 | + ((unsigned char *)(hostent->h_addr))[3]; + + return addr; +} -- GitLab