Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
cmucl
cmucl
Commits
c159b7a7
Commit
c159b7a7
authored
Jul 27, 1993
by
hallgren
Browse files
Initial revision
parent
55bee36e
Changes
1
Hide whitespace changes
Inline
Side-by-side
lisp/hpux-os.c
0 → 100644
View file @
c159b7a7
/*
* $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
;
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment