Multics Technical Bulletin MTB-732-02
Changes to the Hardcore
To: Distribution
From: Douglas Howe
Date: 13 May 1986
Subject: Changes Required to Hardcore by C
1. Abstract
This MTB describes the changes to hardcore required by C to
install heap variables.
Revision 1
Changes made in this revision correct the initialization of the
stack header and are marked with change bars.
Revision 2 The changes made reflect the comments made on MCR 7395 |
and MCR 7396. The changes also include the description of |
list_heap_variables. |
_________________________________________________________________
Multics project internal documentation; not to be reproduced or
distributed outside the Multics project.
MTB-732-02 Multics Technical Bulletin
Changes to the Hardcore
Comments should be sent to the authors:
via Multics mail to:
DGHowe.Multics
via posted mail to:
Douglas G. Howe
Advanced Computing Technology Centre
Foothills Professional Building
1620 29th St., N.W.
Calgary Alberta Canada T2N-4L7
via telephone to:
(403)-284-6400
(403)-284-6432 (Howe)
via forum on System-M to:
>udd>m>DGHowe>mtgs_dir>c>c_imp (c)
Multics Technical Bulletin MTB-732-02
Changes to the Hardcore
TABLE OF CONTENTS
Section Page Subject
======= ==== =======
1 i Abstract
2 1 Preface
3 2 Introduction
3.1 3 . . References For This Document
4 4 Background
5 5 The Heap
5.1 5 . . Stacking Heaps
5.2 6 . . Heap Variable Name List
5.3 6 . . Mallocs Use of The Heap
6 7 star_heap Links
6.1 7 . . Allocation of Heap Links
7 7 Routines to be Changed
7.1 8 . . Changes to link_snap
7.2 8 . . set_ext_variable_$star_heap
7.3 8 . . heap_manager_
8 8 Multiple Execution Level Heap References
9 9 New Commands
10 9 Initialization of heap Links
11 9 Dependencies
12 9 Documentation Changes
13 10 Include File Changes
14 11 Appendix A
15 12 Appendix B
16 14 Appendix C
17 16 Appendix D
18 19 Appendix E
Multics Technical Bulletin MTB-732-02
Changes to the Hardcore
2. Preface
This MTB along with MTBs 691, 647, 733 and 738 are intended to
give a full explanation of how C will execute under Multics.
MTB-732-02 Multics Technical Bulletin
Changes to the Hardcore
3. Introduction
There are various possible methods of implementing C external
variables. External variables currently are implemented via
*system links which are allocated or freed on a per-login process
basis. C external variables could have been implemented using
the existing structure of *system links in the following ways:
1) use *system links directly.
2) use *system links stacking the variable references by stepping
through all active segments saving and resetting the references.
3) use *system links and a renaming convention where all external
names would have a level associated with them. For example x
would refer to the external variable x for level 0 and x01 would
refer to the variable at level 1.
The previous methods have some disadvantages that a full
implementation of a C environment would not allow. These are:
1) for 2 and 3 above the implementation would take a lot longer
to execute than the current environment.
2) 1 above would not allow for multiple unique execution levels.
3) 2 above alters the users definition of their environment by
renaming the variables.
4) 2 and 3 above involve stepping through all active segments on
exit or entrance to an execution unit to stack the variable
references.
For these reasons a new environment area was developed similar to
the user_free_area. The difference being that this area will be
in the control of the user. This area is called a heap and
references to it are performed by *heap links. This MTB
describes the proposed implementation for *heap links as defined
for C.
Multics Technical Bulletin MTB-732-02
Changes to the Hardcore
3.1. References For This Document
1) MTB-647 created by Greg Baryza.
2) The C Programming Language
Kernighan, Brian W. & Ritchie, Dennis M.
Prentice-Hall (1978)
Englewood Cliffs, New Jersey
3) Multics Programmers Reference Manual (10.2 AG91-03A)
(hereafter referred to as MPRM)
4) MTB 688 titled The Multics C Implementation Specification by
Doug Howe.
5) MTB 691 titled Multics C Execution Environment Specification
by Doug Howe.
MTB-732-02 Multics Technical Bulletin
Changes to the Hardcore
4. Background
Under normal circumstances external variables in C are allocated
on a heap. This heap is allocated and freed on a per-execution
basis, allowing multiple main-execution levels to have a clean
environment. On Multics, external allocations are usually
performed in the user_free_area which is allocated and freed per
ring on a per-login-process basis. On Multics the heap will be
allocated per ring.
This difference can lead to large difficulties in transferring
existing C software to Multics. For this reason a new method of
allocation was proposed for C and is implemented in the form of
*heap external links.
Multics Technical Bulletin MTB-732-02
Changes to the Hardcore
5. The Heap
A new area similar to the user_free_area will be developed This
area will be under direct control of the user and will be
referred to as the `heap'. The heap will be an area obtained via
define_area_.
The heap will be used for an execution units external variable
allocations and for C's storage allocation.
Each heap will contain a heap header pointed to by a new field in
the stack header named heap_header_ptr (see Appendix B). The
heap header is defined as follows and is included in
system_link_names.incl.pl1 (see Appendix A):
1 heap_header based,
2 version char(8), |
2 heap_name_list_ptr pointer,
2 previous_heap_header pointer,
2 area_ptr pointer,
2 current_execution_level fixed bin (17);
where:
heap_name_list_ptr: points to the variable_table_header of the
current heap variables at the current execution level.
previous_heap_header_ptr: points to the previous execution
levels heap header.
area_ptr: points to the heap area. This area is defined to be
extensible.
current_execution_level: represents the current level of
execution by a fixed number starting at zero.
5.1. Stacking Heaps
A method of stacking the heap is required due to the possibility
of entering multiple main execution levels from a C program.
The heap will be allocated and stacked by the environment control
mechanism (main_ in C) every time a new execution unit is entered
or by the user directly. It will remain the users responsibility
to include the environment control mechanism with their bound
execution unit. For a description of the environment mechanism
see MTB 691.
MTB-732-02 Multics Technical Bulletin
Changes to the Hardcore
The ability to stack the heap will be added in the form of entry
points in a module named heap_manager_. The pushing of a heap
will be a simple allocation of a new heap at the current
execution level. A new heap header will be created and then the
previous levels heap header will be chained in a list of heap
headers.
The popping of the heap will involve the freeing of all heap
segments that have been allocated for the current level and
resetting the heap to the previous levels heap segments.
For a more detailed description of the entry points in
heap_manager_ see Appendix D.
In order for the new heap levels references to be effective, the
execution environment will also have to be stacked. To perform
this the LOT and ISOT entries for this module will have to be
saved / reset. (see MTB 691)
5.2. Heap Variable Name List
In order to keep track of the external variable references at
each level, a name list will be generated for each heap level.
The name list will be composed of a variable_table_header
(defined in system_link_names.incl.pl1 see Appendix A.) pointing
to a series of variable_nodes from a hash table contained in the
variable_table_header. The variable_table_header will also
contain some metering information as it currently does for
set_ext_variable_.
NOTE: All heap structure allocations will take place in the heap
area. This includes the heap header, variable nodes and variable
node header.
5.3. Mallocs Use of The Heap
C's allocation routines will allocate and free their storage on
the current execution levels heap. The variables will not exist
on the heaps name list but will be allocated or freed directly in
the heap by the use of the standard Multics allocation routines
(allocate and free).
Multics Technical Bulletin MTB-732-02
Changes to the Hardcore
6. star_heap Links
To reference external variables allocated within the heap a new
type of link is required. This new link type will be called a
`*heap' link. `*heap' links are defined as a link with a type of
5 and a class of 6. This puts them into the same family as
`*system' links.
`*heap' links will act the same as `*system' links in terms of
initialization and references.
The only languages at this point that will support heap links
will be C and ALM.
6.1. Allocation of Heap Links
The allocation of `*heap' link targets will take place in the
current heap. The allocation of the space required for each heap
variable will be done via the standard Multics allocation
packages. When a variable is allocated an entry is made on the
heap name list stating the variables name, size and
initialization information.
7. Routines to be Changed
In order to implement `*heap' links the following system routines
will be altered:
1) link_snap : link_snap has to understand `*heap' links in the
same manner that it currently understands `*system' links.
2) set_ext_variable_$star_heap : is a new entry point in
set_ext_variable controlling the allocation and resolution of
references to `*heap' links.
3) heap_manager_ : a new group of entry points to control the
heap and return information concerning heap levels.
4) link_man$get_initial_linkage : will have to be altered to
initialize the new field being added to the stack_header
structure. (see Appendix B)
5) bootload_1 : will have to be altered to initialize the new
field being added to the stack header for the ring zero stack
header. (see Appendix B).
6) interpret_link_ : will have to understand heap links.
7) linkage_error_ : will have to understand heap links.
MTB-732-02 Multics Technical Bulletin
Changes to the Hardcore
7.1. Changes to link_snap
The changes to link_snap involve checking for `*heap' links
similar to how `*system' links are checked for now. When a
`*heap' link is found a call to the entry point
set_ext_variable_$star_heap will perform the desired function.
7.2. set_ext_variable_$star_heap
star_heap will control the allocation and references to heap
variables via `*heap' links. The biggest difference between
star_heap and the other entry points in set_ext_variable_ is
where the allocation of the external variable takes place. In
set_ext_variable_ external variables are allocated in the
user_free_area pointed to by user_free_ptr in the users stack
header. `*heap' links are allocated in the defined heap pointed
to by area_ptr in the heap header.
star_heap is called from link_snap or user programs to allocate
or find a heap variable on the current execution levels heap. If
the variable is not found it is allocated, initialized and added
to the name list at the current level of execution. If it is
found the address to the target variable node is returned. If
the heap does not exist a level zero heap is created. This heap
will then exist for the life of the login process. Normal,
stacked heaps will begin at level one.
7.3. heap_manager_
A series of entry points will be available in heap_manager_ to
handle various heap operations. For a complete description see
Appendix D.
8. Multiple Execution Level Heap References
With the stacking of the heap and the use of the environment
control mechanism (main_), references across execution levels to
heap variables of the same name will be resolved to the specific
execution levels name list and thus to separate copies of the
heap variable.
Multics Technical Bulletin MTB-732-02
Changes to the Hardcore
9. New Commands
A new command will be added to Multics to allow the user to find
out information concerning `*heap' links as follows:
1) list_heap_variables would be equivalent to list_ext_variables
for the current heap level. For a complete description see |
Appendix E. |
10. Initialization of_heap Links
`*heap' links are initialized in the same manner that is
currently done for `*system' links. `*heap' links will be
initialized on first reference within an execution unit.
11. Dependencies
The above mentioned design is dependent on the following:
1) If the entry is recursive the execution environment has been
stacked. The environment for the module being entered must be
fresh / clean On exit from the module the environment will
have to be reset to the previous value (see MTB 691).
2) Binding or Link Editing (via the Linkage Editor) of the
executable object is required to join all initialization
information together for heap links. This is required only if
the initialization information is separated across segments or
if the sequence in which the variable is referenced can not be
guarantied to initialize it correctly.
3) Access to the heap header information is required by main_ and
C so that it can make use of the heap.
12. Documentation Changes
The following lists all the changes required to Multics
documentation.
1) heap_manager_.info and AG93 Manual changes see Appendix D.
2) set_ext_variable_.info and AG93 Manual changes will be
included with MTB 738.
3) Change AG91 to describe the changes to the stack header as
follows:
MTB-732-02 Multics Technical Bulletin
Changes to the Hardcore
add the declaration of the new stack header in section H-3 and
add the following to H-4.
heap_header_ptr
points to the heap header for the current execution level
for the current ring.
4) The changes to the Commands Manual and lhv.info can be found |
in Appendix E. |
13. Include File Changes
The following lists the required changes to system include files.
1) system_link_names.incl.pl1 Appendix A.
2) stack_header.incl.pl1 Appendix B.
3) stack_header.incl.alm Appendix C.
Multics Technical Bulletin MTB-732-02
Changes to the Hardcore
14. Appendix A
/* BEGIN INCLUDE FILE ... system_link_names.incl.pl1 */
/* created by M. Weaver 7/28/76 */
/* Modified: 82-11-19 by T. Oke to add LIST_TEMPLATE_INIT. */
/* Modified 02/11/83 by M. Weaver to add have_vla_variables flag */
dcl 1 variable_table_header aligned based,
2 hash_table (0:63) ptr unaligned,
2 total_search_time fixed bin (71),
2 total_allocation_time fixed bin (71),
2 number_of_searches fixed bin,
2 number_of_variables fixed bin (35),
2 flags unaligned,
3 have_vla_variables bit (1) unaligned,
3 pad bit (11) unaligned,
2 cur_num_of_variables fixed bin (24) unal,
2 number_of_steps fixed bin,
2 total_allocated_size fixed bin (35);
dcl 1 variable_node aligned based,
2 forward_thread ptr unaligned,
2 vbl_size fixed bin (24) unsigned unaligned,
2 init_type fixed bin (11) unaligned,
2 time_allocated fixed bin (71),
2 vbl_ptr ptr,
2 init_ptr ptr,
2 name_size fixed bin(21) aligned,
2 name char (nchars refer (variable_node.name_size));
dcl 1 heap_header based, |
2 version char(8), |
2 heap_name_list_ptr pointer, |
2 previous_heap_ptr pointer, |
2 area_ptr pointer, |
2 execution_level fixed bin (17); |
dcl heap_header_version_1 char(8) static options (constant) |
init ("Heap_v01"); |
/* END INCLUDE FILE ... system_link_names.incl.pl1 */
MTB-732-02 Multics Technical Bulletin
Changes to the Hardcore
15. Appendix B
/* BEGIN INCLUDE FILE ... stack_header.incl.pl1 .. 3/72 Bill Silver*/
/* modified 7/76 by M. Weaver for *system links and more system use
of areas */
/* modified 3/77 by M. Weaver to add rnt_ptr */
/* Modified April 1983 by C. Hornig for tasking.
(the trace stuff is temporary - MBW) */
/* format: style2 */
/* NOTE --------------------------------------------------
the following structures are also declared in stack_header.incl.alm and
should be kept equivalent to these
-------------------------------------------------------
*/
dcl sb ptr;
dcl 1 stack_header based (sb) aligned,
2 pad1 (4) fixed bin,
2 old_lot_ptr ptr,
2 combined_stat_ptr ptr,
2 clr_ptr ptr,
2 max_lot_size fixed bin (17) unal,
2 main_proc_invoked fixed bin (11) unal,
2 have_static_vlas bit (1) unal,
2 pad4 bit (2) unal,
2 run_unit_depth fixed bin (2) unal,
2 cur_lot_size fixed bin (17) unal,
2 pad2 bit (18) unal,
2 system_free_ptr ptr,
2 user_free_ptr ptr,
2 null_ptr ptr,
2 stack_begin_ptr ptr,
2 stack_end_ptr ptr,
2 lot_ptr ptr,
2 signal_ptr ptr,
2 bar_mode_sp ptr,
2 pl1_operators_ptr ptr,
2 call_op_ptr ptr,
2 push_op_ptr ptr,
2 return_op_ptr ptr,
2 return_no_pop_op_ptr
ptr,
2 entry_op_ptr ptr,
2 trans_op_tv_ptr ptr,
2 isot_ptr ptr,
2 sct_ptr ptr,
Multics Technical Bulletin MTB-732-02
Changes to the Hardcore
2 unwinder_ptr ptr,
2 sys_link_info_ptr ptr,
2 rnt_ptr ptr,
2 ect_ptr ptr,
2 assign_linkage_ptr ptr,
2 task_data_ptr ptr,
2 trace,
3 frames,
4 count fixed bin,
4 top_ptr ptr unal,
3 in_trace bit (36) aligned,
2 mbz bit (36) aligned, |
2 heap_header_ptr ptr; |
/* The following offset refers to a table within the pl1
operator table. */
dcl tv_offset fixed bin init (361) internal static;
/* (551) octal */
/* The following constants are offsets within this transfer vector table. */
dcl (
call_offset fixed bin init (271),
push_offset fixed bin init (272),
return_offset fixed bin init (273),
return_no_pop_offset fixed bin init (274),
entry_offset fixed bin init (275)
) internal static;
/* The following declaration is an overlay of the whole stack header.
Procedures which move the whole stack header should use this overlay.
*/
dcl stack_header_overlay (size (stack_header))
fixed bin based (sb);
/* END INCLUDE FILE ... stack_header.incl.pl1 */
MTB-732-02 Multics Technical Bulletin
Changes to the Hardcore
16. Appendix C
" BEGIN INCLUDE FILE ... stack_header.incl.alm 3/72 Bill Silver
"
" modified 7/76 by M. Weaver for *system links and more system
" use of areas
" modified 3/77 by M. Weaver to add rnt_ptr
" modified 7/77 by S. Webber to add run_unit_depth and
" assign_linkage_ptr
" modified 6/83 by J. Ives to add trace_frames and in_trace.
" NOTE --------------------------------------------------
" the following declarations describe the stack header structure which is
" declared in stack_header.incl.pl1 and should be kept equivalent
" --------------------------------------------------------
equ stack_header.old_lot_ptr,4
equ stack_header.combined_stat_ptr,6
equ stack_header.clr_ptr,8
equ stack_header.max_lot_size,10
equ stack_header.main_proc_invoked,10
equ stack_header.run_unit_depth,10
equ stack_header.cur_lot_size,11
equ stack_header.system_free_ptr,12
equ stack_header.user_free_ptr,14
equ stack_header.parent_ptr,16
equ stack_header.stack_begin_ptr,18
equ stack_header.stack_end_ptr,20
equ stack_header.lot_ptr,22
equ stack_header.signal_ptr,24
equ stack_header.bar_mode_sp,26
equ stack_header.pl1_operators_ptr,28
equ stack_header.call_op_ptr,30
equ stack_header.push_op_ptr,32
equ stack_header.return_op_ptr,34
equ stack_header.ret_no_pop_op_ptr,36
equ stack_header.entry_op_ptr,38
equ stack_header.trans_op_tv_ptr,40
equ stack_header.isot_ptr,42
equ stack_header.sct_ptr,44
equ stack_header.unwinder_ptr,46
Multics Technical Bulletin MTB-732-02
Changes to the Hardcore
equ stack_header.sys_link_info_ptr,48
equ stack_header.rnt_ptr,50
equ stack_header.ect_ptr,52
equ stack_header.assign_linkage_ptr,54
equ stack_header.task_data_ptr,56
equ stack_header.trace_frames,58
equ stack_header.in_trace,60
equ stack_header.heap_header_ptr,62 |
equ stack_header_end,64
equ trace_frames.count,0
equ trace_frames.top_ptr,1
" The following constant is an offset within the pl1 operators
" table. It references a transfer vector table.
bool tv_offset,551
" The following constants are offsets within this transfer vector
" table.
equ call_offset,tv_offset+271
equ push_offset,tv_offset+272
equ return_offset,tv_offset+273
equ return_no_pop_offset,tv_offset+274
equ entry_offset,tv_offset+275
" END INCLUDE FILE stack_header.incl.alm
MTB-732-02 Multics Technical Bulletin
Changes to the Hardcore
17. Appendix D
03/17/86 heap_manager_
Entry points in heap_manager_:
(List is generated by the help command)
:Entry: push_heap_level: 03/17/86: heap_manager_$push_heap_level
Function: This entry point creates a new heap level, allocates
the heap header and chains the previous heap to the current
heap. If the stack_header_ptr is null an error of
error_table_$null_info_ptr is returned.
Syntax:
declare heap_manager_$push_heap_level entry (pointer, fixed
bin(17), fixed bin(35));
call heap_manager_$push_heap_level (stack_header_ptr, exe_level,
code);
Arguments:
stack_header_ptr
is a pointer to the stack header. This can be obtained via
the PL/1 builtin stackbaseptr(). (Input)
exe_level
is the new execution level after the new heap is created.
(Output)
code
is a standard status code. (Output)
:Entry: pop_heap_level: 03/17/86: heap_manager_$pop_heap_level
Function: This entry point resets the heap to the previous level
freeing the old heap and any variables allocated therein.
Syntax:
declare heap_manager_$pop_heap_level entry (pointer, fixed
bin(35));
call heap_manager_$pop_heap_level (stack_header_ptr, code);
Multics Technical Bulletin MTB-732-02
Changes to the Hardcore
Arguments:
stack_header_ptr
is a pointer to the stack header. This can be obtained via
the PL/1 builtin stackbaseptr(). (Input)
code
is a standard status code. (Output)
:Entry: get_heap_header: 03/17/86: heap_manager_$get_heap_header
Function: This entry point returns a pointer to the heap header
for the specified execution level. If the execution level does
not exist an error of error_table_$no_heap_defined is returned.
Syntax:
declare heap_manager_$get_heap_header entry (pointer, fixed
bin(17), pointer, fixed bin(35));
call heap_manager_$get_heap_header (stack_header_ptr, exe_level,
heap_header_ptr, code);
Arguments:
exe_level
is the execution level of the heap required. If a -1 is passed
then the current execution level is used. (Input)
stack_header_ptr
is a pointer to the stack header. This can be obtained via
the PL/1 builtin stackbaseptr(). (Input)
heap_header_ptr
is a pointer to the heap header for the passed execution
level. (Output).
code
is a standard status code. (Output)
:Entry: get_heap_level: 03/17/86: heap_manager_$get_heap_level
Function: This entry point returns the current execution level
from the current heap header. If the heap does not exist an execution
level of -1 is returned.
Syntax:
declare heap_manager_$get_heap_level entry (pointer)
returns (fixed bin(17));
exe_level = heap_manager_$get_heap_level (stack_header_ptr);
MTB-732-02 Multics Technical Bulletin
Changes to the Hardcore
Arguments:
stack_header_ptr
is a pointer to the stack header. This can be obtained via
the PL/1 builtin stackbaseptr(). (Input)
:Entry: get_heap_area: 03/17/86: heap_manager_$get_heap_area
Function: This entry point returns a pointer to the heap area
for the specified level. The area is max_segsize - 50 words.
If the heap level specified does not exist an error of
error_table_$no_heap_defined is returned.
Syntax:
declare heap_manager_$get_heap_area entry (pointer, fixed
bin(17), pointer, fixed bin(35));
call heap_manager_$get_heap_area (stack_header_ptr, exe_level,
heap_area_ptr, code);
Arguments:
exe_level
is the execution level of the heap area required. If a -1 is
passed then the current execution level is used. (Input)
stack_header_ptr
is a pointer to the stack header. This can be obtained via
the PL/1 builtin stackbaseptr(). (Input)
heap_area_ptr
is pointer to the heap area for the passed level. (Output)
code
is a standard status code. (Output)
Multics Technical Bulletin MTB-732-02
Changes to the Hardcore
18. Appendix E
05/12/86 list_heap_variables, lhv |
|
Syntax: lhv names {-control_args} |
|
|
Function: Prints information concerning heap variables. Only |
variables at the current execution level are printed. The |
default information is the location and size of each specified |
variable. |
|
Arguments: |
names |
are names of external variables, separated by spaces. |
|
|
Control arguments: |
-all, -a |
prints information for all heap variables at the current |
execution level. |
-long, -lg |
prints how and when the variables were allocated. |
-no_header, -nhe |
suppresses the printing of the header. |
-to level |
specifes what execution level to stop printing variables at. |
If not present the current execution level is assumed. |
-from level |
specifies what execution level to start printing variables at. |
If not present execution level 0 is assumed. |
|
Note: The -from and -to arguments are meant to be used together to|
specify a range of execution levels to be printed. If neither are |
present the current execution level is assumed. |