
?? RIGHT := 110, LEFT := 1 ??
??
FMT (FORMAT := ON, keyw = upper, ident := lower) ??
MODULE mlm$initialize_memory_link;
*copyc OSD$DEFAULT_PRAGMATS
{---------------------------------------------------------------------------
{ This module contains the routine which is called during startup of the
{ job monitor task of the system job to initialize the memory link.
{
{ This routine will create a file and open it for segment access.  This
{ segment will then become part of every task's address space so that
{ the memory link can access it by the same segment number in every task.
{ A pointer to the memory link segment is placed in the variable
{ MLV$SHARED_SEGMENT.
{
{ The memory link initialization routine must reside in ring 1 so that
{ the variable MLV$SHARED_SEGMENT is defined in the mainframe wired
{ table segment.  The memory link segment has read and write access from
{ ring 2 and below.  The memory link will (probably) run in ring 2.
{---------------------------------------------------------------------------
?? PUSH (LISTEXT := ON) ??
*copyc OSV$MAINFRAME_WIRED_HEAP
*copyc MLT$C170_RQST_BLK
*copyc MLD$MEMORY_LINK_DECLARATIONS
*copyc MLT$ANT_ENTRY
*copyc OSP$RESET_HEAP
*copyc osv$170_os_type
*copyc PMP$ZERO_OUT_TABLE
*copyc MMP$FREE_PAGES
?? POP ??

  SECTION
    mls$mem_link: WRITE;

  VAR
    mlv$enabled: [XREF] boolean,
    mlv$c170_rqst_blk: [XREF] mlt$c170_rqst_blk,
    mlv$shared_segment: [XDCL, mls$mem_link] mlt$shared_segment;

?? EJECT ??
{--------------------------------------------------------------}
{name:}
{  mlp$initialize}
{Purpose:}
{  This routine sets up the memory link shared segment.
{  The segment is present in the address space of every task, and
{  is created in shared, wired mode.
{Input:}
{  none. }
{Output:}
{  none.}
{Error Codes:}
{None.}
{---------------------------------------------------------------}

  PROCEDURE [XDCL, #GATE] mlp$initialize (VAR status: ost$status);



    VAR
      ae: 1 .. mlc$max_ant_entries,
      i: integer,
      hp: ^ost$heap;

    IF osv$170_os_type = osc$ot7_none THEN
      status.normal := TRUE;
      RETURN;
    IFEND;
    mlv$enabled := TRUE;
{
{ reset all heaps and initialize all data tables in the memory link segment.
{
    hp := #LOC (mlv$shared_segment.pspace);
    osp$reset_heap (hp, 20000000, FALSE, 1);
    mlv$shared_segment.tlock := mlc$not_ilk;
    mlv$shared_segment.plock := mlc$not_ilk;
    mlv$shared_segment.dust_id.index := 0;
    mlv$shared_segment.dust_id.seqno := 0;
    mlv$shared_segment.next_free_ant_entry := mlc$max_primary_entry + 1;
    FOR ae := 1 TO mlc$max_ant_entries DO
      mlv$shared_segment.ant [ae].application_name := mlc$empty_entry;
      mlv$shared_segment.ant [ae].reservation := mlc$not_ilk;
      mlv$shared_segment.ant [ae].max_messages := 0;
      mlv$shared_segment.ant [ae].unique := - 1;
      mlv$shared_segment.ant [ae].receive_list := NIL;
      mlv$shared_segment.ant [ae].permit_list := NIL;
      mlv$shared_segment.ant [ae].sn_fwd_p := mlc$end_of_chain;
      mlv$shared_segment.ant [ae].sn_bkwd_p := mlc$end_of_chain;
      mlv$shared_segment.ant [ae].system_name.c170_c180_flag := mlc$none;
      mlv$shared_segment.ant [ae].handler := NIL;
      IF ae <= mlc$max_primary_entry THEN
        mlv$shared_segment.ant [ae].forward_p := mlc$end_of_chain;
        mlv$shared_segment.ant [ae].backward_p := mlc$end_of_chain;
      ELSEIF ae < mlc$max_ant_entries THEN
        mlv$shared_segment.ant [ae].forward_p := ae + 1;
        mlv$shared_segment.ant [ae].backward_p := ae - 1;
      ELSE
        mlv$shared_segment.ant [ae].forward_p := mlc$end_of_chain;
        mlv$shared_segment.ant [ae].backward_p := ae - 1;
      IFEND;
    FOREND;
    FOR ae := 1 TO mlc$max_sn_entry DO
      mlv$shared_segment.sn_chain_table [ae] := mlc$end_of_chain;
    FOREND;

{ allocate all buffers, but only enable the first few

    ALLOCATE mlv$c170_rqst_blk.buffers IN osv$mainframe_wired_heap^;
    pmp$zero_out_table (mlv$c170_rqst_blk.buffers, initial_buffer_count * (mlc$max_message_length + 1));
    FOR i := initial_buffer_count TO mlimi - 1 DO
      mlv$c170_rqst_blk.arr [i].op_status := not_available;
    { NOTE: op_status is referenced by #compare_swap after being initialized and
    {       cannot be referenced by this procedure again.
    FOREND;
    mmp$free_pages (#LOC (mlv$c170_rqst_blk.buffers^ [initial_buffer_count]), (mlimi - initial_buffer_count) *
          (mlc$max_message_length + 1), osc$nowait, status);
    status.normal := TRUE;
    mlv$c170_rqst_blk.reject_calls := accept_all_calls;
  PROCEND mlp$initialize;
MODEND mlm$initialize_memory_link
