Skip to content
GitLab
Explore
Sign in
Register
Primary navigation
Search or go to…
Project
cmucl
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Package Registry
Model registry
Operate
Environments
Terraform modules
Monitor
Incidents
Service Desk
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Terms and privacy
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
Carl Shapiro
cmucl
Commits
c159b7a7
Commit
c159b7a7
authored
31 years ago
by
hallgren
Browse files
Options
Downloads
Patches
Plain Diff
Initial revision
parent
55bee36e
No related branches found
Branches containing commit
No related tags found
Tags containing commit
No related merge requests found
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
lisp/hpux-os.c
+348
-0
348 additions, 0 deletions
lisp/hpux-os.c
with
348 additions
and
0 deletions
lisp/hpux-os.c
0 → 100644
+
348
−
0
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
;
}
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment