.ad 8
.bm 8
.fm 4
.bt $Copyright (c) 2000-2005 SAP AG$$Page %$
.tm 12
.hm 6
.hs 3
.tt 1 $SQL$Project Distributed Database System$VBD20$
.tt 2 $$$
.tt 3 $TorstenS$BD-data-cache$$2000-12-12$
***********************************************************
.nf
 
 .nf
 
    ========== licence begin  GPL
    Copyright (c) 2000-2005 SAP AG
 
    This program is free software; you can redistribute it and/or
    modify it under the terms of the GNU General Public License
    as published by the Free Software Foundation; either version 2
    of the License, or (at your option) any later version.
 
    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.
 
    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
    ========== licence end
.fo
 
 
.fo
.nf
.sp
Module  : systembufferinterface
=========
.sp
Purpose : dynamic cache for B*-tree-nodes (data cache)
.CM *-END-* purpose -------------------------------------
.sp
.cp 3
Define  :
 
        PROCEDURE
              bd20CheckExclusiveLockedPageForIO (
                    TaskId         : tsp00_TaskId;
                    VAR FileId     : tgg00_FileId;
                    PageNo         : tsp00_PageNo;
                    recMode        : tbd02_RecoveryMode;
                    pCBlock        : tbd02_pDataCBlock (* ptocSynonym tbd_nodeptr *);
                    VAR bWritePage : boolean;
                    VAR PageState  : tbd02_CachePageState);
 
        PROCEDURE
              bd20CheckRootNptrs (
                    TaskId      : tsp00_TaskId;
                    VAR TrError : tgg00_BasisError;
                    Root        : tsp00_PageNo;
                    pNode       : tbd_nodeptr;
                    pCBlock     : tbd02_pDataCBlock (* ptocSynonym tbd_nodeptr *));
 
        PROCEDURE
              bd20LockPageForFree (
                    TaskId               : tsp00_TaskId;
                    VAR TrError          : tgg00_BasisError;
                    VAR FileId           : tgg00_FileId;
                    PageNo               : tsp00_PageNo;
                    recMode              : tbd02_RecoveryMode;
                    FirstCall            : boolean;
                    VAR PageLockedToFree : boolean;
                    VAR PageState        : tbd02_CachePageState;
                    VAR nptr             : tbd_nodeptr;
                    VAR cbptr            : tbd02_pDataCBlock);
 
        PROCEDURE
              bd20FreePage (
                    TaskId              : tsp00_TaskId;
                    PageNo              : tsp00_PageNo;
                    recMode             : tbd02_RecoveryMode;
                    VAR TrError         : tgg00_BasisError;
                    VAR ExclFileLockCnt : tsp00_Int2);
 
        PROCEDURE
              bd20FlushDataCache (
                    VAR Trans : tgg00_TransContext);
 
        PROCEDURE
              bd20ForcedIODone (
                    pCBlock : tbd02_pDataCBlock (* ptocSynonym tbd_nodeptr *);
                    TaskId  : tsp00_TaskId);
 
        PROCEDURE
              bd20GetPage (
                    TaskId              : tsp00_TaskId;
                    VAR WaitContext     : tgg00_WaitContext;
                    VAR TrError         : tgg00_BasisError;
                    VAR ExclFileLockCnt : tsp00_Int2;
                    VAR FileId          : tgg00_FileId;
                    PageNo              : tsp00_PageNo;
                    recMode             : tbd02_RecoveryMode;
                    NodeRequest         : tbd_node_request;
                    VAR nptr            : tbd_nodeptr;
                    VAR cbptr           : tbd02_pDataCBlock (* ptocSynonym tbd_nodeptr &*);
                    VAR PageState       : tbd02_CachePageState);
 
        PROCEDURE
              bd20InitDataCache (
                    TaskId          : tsp00_TaskId;
                    VAR TrError     : tgg00_BasisError;
                    TotalFreeFrames : tsp00_Int4;
                    TotalDataPages  : tsp00_Int4);
 
        FUNCTION
              bd20IsPageChanged (
                    pCBlock : tbd02_pDataCBlock (* ptocSynonym tbd_nodeptr *) ) : boolean;
 
        FUNCTION
              bd20IsPageExclusiveLocked (
                    pCBlock : tbd02_pDataCBlock (* ptocSynonym tbd_nodeptr *)) : boolean;
 
        FUNCTION
              bd20IsPageShareLocked (
                    pCBlock : tbd02_pDataCBlock (* ptocSynonym tbd_nodeptr *)) : boolean;
 
        FUNCTION
              bd20GetPageUsageCount (
                    pCBlock : tbd02_pDataCBlock (* ptocSynonym tbd_nodeptr *)) : tsp00_Int2;
 
        PROCEDURE
              bd20NewPage (
                    TaskId        : tsp00_TaskId;
                    VAR TrError   : tgg00_BasisError;
                    VAR FileId    : tgg00_FileId;
                    PageNo        : tsp00_PageNo;
                    recMode       : tbd02_RecoveryMode;
                    VAR nptr      : tbd_nodeptr;
                    VAR cbptr     : tbd02_pDataCBlock;
                    VAR PageState : tbd02_CachePageState);
 
        PROCEDURE
              bd20ProtectDataCacheFrames (
                    TaskId : tsp00_TaskId;
                    Enable : boolean);
 
        PROCEDURE
              bd20RReleasePage (
                    TaskId              : tsp00_TaskId;
                    VAR ExclFileLockCnt : tsp00_Int2;
                    VAR FileId          : tgg00_FileId;
                    VAR nptr            : tbd_nodeptr;
                    VAR cbptr           : tbd02_pDataCBlock;
                    recMode             : tbd02_RecoveryMode;
                    LruInfo             : tbd_lru_info);
 
        PROCEDURE
              bd20WReleasePage (
                    TaskId              : tsp00_TaskId;
                    VAR FileId          : tgg00_FileId;
                    VAR ExclFileLockCnt : tsp00_Int2;
                    VAR nptr            : tbd_nodeptr;
                    VAR cbptr           : tbd02_pDataCBlock;
                    VAR IoState         : tbd02_SwapState;
                    recMode             : tbd02_RecoveryMode);
 
        PROCEDURE
              bd20ReplaceOldOccupant (
                    TaskId               : tsp00_TaskId;
                    VAR TrError          : tgg00_BasisError;
                    PageNo               : tsp00_PageNo;
                    recMode              : tbd02_RecoveryMode;
                    cbptr                : tbd02_pDataCBlock (* ptocSynonym tbd_nodeptr *);
                    setBlockedForNewNode : boolean);
 
        PROCEDURE
              bd20ShutdownDataCache (
                    TaskId             : tsp00_TaskId;
                    emergency_shutdown : boolean);
 
        PROCEDURE
              bd20UsePage (
                    TaskId        : tsp00_TaskId;
                    VAR TrError   : tgg00_BasisError;
                    PageNo        : tsp00_PageNo;
                    recMode       : tbd02_RecoveryMode;
                    cbptr         : tbd02_pDataCBlock (* ptocSynonym tbd_nodeptr *);
                    NodeRequest   : tbd_node_request;
                    VAR nptr      : tbd_nodeptr);
 
        PROCEDURE
              bd20ClearAccessStatistic(
                    TaskId : tsp00_TaskId );
 
        FUNCTION
              bd20GetFileTfn (
                    pCBlock : tbd02_pDataCBlock (* ptocSynonym tbd_nodeptr *)) : tgg00_Tfn;
 
        PROCEDURE
              bd20GetAccessStatistic(
                    TaskId               : tsp00_TaskId;
                    VAR HistoryTotal     : tsp00_8ByteCounter;
                    VAR HistoryHit       : tsp00_8ByteCounter;
                    VAR HistoryMiss      : tsp00_8ByteCounter;
                    VAR OmsDataTotal     : tsp00_8ByteCounter;
                    VAR OmsDataHit       : tsp00_8ByteCounter;
                    VAR OmsDataMiss      : tsp00_8ByteCounter;
                    VAR SqlDataTotal     : tsp00_8ByteCounter;
                    VAR SqlDataHit       : tsp00_8ByteCounter;
                    VAR SqlDataMiss      : tsp00_8ByteCounter);
              (* ptocExport hbd20_1.h *)
 
        PROCEDURE
              bd20GetCacheSize (
                    VAR TotalPages : tsp00_Int4;
                    VAR UnMapPages : tsp00_Int4);
 
        PROCEDURE
              bd20GetWorkloadCounter (
                    VAR DataCacheSize          : tsp00_Int4;
                    VAR OmsHistoryPageCnt      : tsp00_Int4;
                    VAR OmsDataPageCnt         : tsp00_Int4;
                    VAR OmsUnloadedVersPageCnt : tsp00_Int4;
                    VAR SqlDataPageCnt         : tsp00_Int4);
              (* ptocExport hbd20_2.h *)
 
        FUNCTION
              bd20IsPageRequested (
                    cbptr : tbd02_pDataCBlock (* ptocSynonym tbd_nodeptr *)) : boolean;
              (* ptocExport hbd20_3.h *)
 
        FUNCTION
              bd20ReduceDataCache(TaskId : tsp00_TaskId) : tbd_nodeptr;
              (* ptocExport hbd20_4.h *)
 
        PROCEDURE
              bd20PrepareSavepoint (
                    TaskId           : tsp00_TaskId;
                    ConverterVersion : tsp00_Int4);
 
        PROCEDURE
              bd20SavepointCompleted (
                    TaskId           : tsp00_TaskId;
                    ConverterVersion : tsp00_Int4);
 
        PROCEDURE
              bd20SetPreventSplit (TaskId : tsp00_TaskId);
 
        PROCEDURE
              bd20UnSetPreventSplit (TaskId : tsp00_TaskId);
              (* ptocExport hbd20_5.h *)
 
        FUNCTION
              bd20ExclusiveLocks (TaskId : tsp00_TaskId) : boolean;
 
        PROCEDURE
              bd20FullestDataCacheSegment (
                    TaskId      : tsp00_TaskId;
                    VAR CacheNo : integer);
 
        PROCEDURE
              bd20GetPageForIO (
                    TaskId           : tsp00_TaskId;
                    RegOffset        : integer;
                    VAR TrError      : tgg00_BasisError;
                    VAR FlushElems   : tsp00_Int2;
                    VAR NodePtrList  : tbd00_NodePtrList;
                    VAR CBlockList   : tbd2_data_cb_flush_list;
                    VAR Completed    : boolean;
                    VAR IsSequential : boolean);
 
        FUNCTION
              bd20IOElemCount (
                    TaskId    : tsp00_TaskId;
                    RegOffset : integer) : tsp00_Int4;
 
        PROCEDURE
              bd20PreDisplaceIO (
                    TaskId           : tsp00_TaskId;
                    RegOffset        : integer;
                    VAR TrError      : tgg00_BasisError;
                    VAR UseIOChain   : boolean;
                    VAR FlushElems   : tsp00_Int2;
                    VAR NodePtrList  : tbd00_NodePtrList;
                    VAR CBlockList   : tbd2_data_cb_flush_list;
                    VAR IsSequential : boolean);
 
        PROCEDURE
              bd20ResetIOState (
                    TaskId     : tsp00_TaskId;
                    RegOffset  : integer;
                    FlushElems : tsp00_Int2;
                    CBlockList : tbd2_data_cb_flush_list);
              (* ptocExport hbd20_6.h *)
 
        FUNCTION
              bd20GetNumberOfChangedPages : tsp00_Int4;
              (* ptocExport hbd20_7.h *)
 
        PROCEDURE
              bd20DumpDataCache (
                    VAR hostfile   : tgg00_VfFileref;
                    VAR b          : tsp00_Page;
                    VAR dump_pno   : tsp00_Int4;
                    VAR pos        : integer;
                    VAR host_error : tsp00_VfReturn;
                    VAR errtext    : tsp00_ErrText);
 
        PROCEDURE
              bd20DumpDataCacheFrames (
                    VAR hostfile   : tgg00_VfFileref;
                    VAR b          : tsp00_Page;
                    VAR dump_pno   : tsp00_Int4;
                    VAR pos        : integer;
                    VAR host_error : tsp00_VfReturn;
                    VAR errtext    : tsp00_ErrText);
 
.CM *-END-* define --------------------------------------
.sp;.cp 3
Use     :
 
        FROM
              error_text_handling : VBD06;
 
        PROCEDURE
              b06check_vresume_cnt (pid : tsp00_TaskId);
 
        PROCEDURE
              b06write_filename_and_root (VAR file_id : tgg00_FileId);
 
      ------------------------------ 
 
        FROM
              BD_Wrapper : VBD999;
 
        FUNCTION
              bd999GetFrame( TaskId : tsp00_TaskId ) : tbd_nodeptr;
 
        PROCEDURE
              bd999GetAWEFrame(
                    TaskId      : tsp00_TaskId;
                    VAR pFrame  : tbd_nodeptr;
                    VAR BlockNo : tsp00_Int4);
 
        PROCEDURE
              bd999ReleaseFrame(
                    TaskId : tsp00_TaskId;
                    pNode  : tbd_nodeptr);
 
        PROCEDURE
              bd999WriteDataPage(
                    VAR Trans : tgg00_TransContext;
                    VAR pNode : tbd_nodeptr);
 
        PROCEDURE
              bd999ResumeOneDataWriter (
                    TaskId    : tsp00_TaskId;
                    RegOffset : integer);
 
        FUNCTION
              bd999GetPageSize : tsp00_Int4;
 
      ------------------------------ 
 
        FROM
              ref_statistic : VBD73;
 
        PROCEDURE
              bd73DataIOStatistic (
                    Level    : integer;
                    FileType : tgg00_Tfn;
                    is_virt  : boolean;
                    is_read  : boolean);
 
      ------------------------------ 
 
        FROM
              KB_Logging : VKB560;
 
        PROCEDURE
              kb560InsertToWaitForPrepare(taskid : tsp00_TaskId;
                    VAR waitcontext : tgg00_WaitContext);
 
      ------------------------------ 
 
        FROM
              Configuration_Parameter : VGG01;
 
        VAR
              g01default_lru : boolean;
              g01glob        : tgg00_KernelGlobals;
 
        PROCEDURE
              g01allocate_msg (msg_label : tsp00_C8;
                    msg_text   : tsp00_C24;
                    alloc_size : tsp00_Int4);
 
        PROCEDURE
              g01abort (msg_no : tsp00_Int4;
                    msg_label : tsp00_C8;
                    msg_text  : tsp00_C24;
                    bad_value : tsp00_Int4);
 
        FUNCTION
              g01dw_io_area_size : tsp00_Int4;
 
        FUNCTION
              g01dw_io_area_flush : tsp00_Int4;
 
        FUNCTION
              g01dw_lru_tail_flush : tsp00_Int4;
 
        FUNCTION
              g01io_block_count : tsp00_Int4;
 
        FUNCTION
              g01is_archive : boolean;
 
        FUNCTION
              g01maxdatawriter : tsp00_Int4;
 
        FUNCTION
              g01maxservertask : tsp00_Int4;
 
        FUNCTION
              g01maxuser : tsp00_Int4;
 
        PROCEDURE
              g01next_prim_number (VAR prim_int : tsp00_Int4);
 
        PROCEDURE
              g01new_dump_page (VAR hostfile : tgg00_VfFileref;
                    VAR buf      : tsp00_Page;
                    VAR out_pno  : tsp00_Int4;
                    VAR out_pos  : integer;
                    VAR host_err : tsp00_VfReturn;
                    VAR errtext  : tsp00_ErrText);
 
        PROCEDURE
              g01opmsg (msg_prio : tsp3_priority;
                    msg_type  : tsp3_msg_type;
                    msg_no    : tsp00_Int4;
                    msg_label : tsp00_C8;
                    msg_text  : tsp00_C24;
                    msg_value : tsp00_Int4);
 
        PROCEDURE
              g01optextmsg (msg_prio : tsp3_priority;
                    msg_type  : tsp3_msg_type;
                    msg_no    : tsp00_Int4;
                    msg_label : tsp00_C8;
                    msg_text  : tsp00_C40);
 
        FUNCTION
              g01region_cnt (region_type : tgg00_RegionType) : tsp00_Int4;
 
      ------------------------------ 
 
        FROM
              Regions_and_Longwaits : VGG08;
 
        VAR
              g08datacache : tsp00_RegionId;
              g08data1     : tsp00_RegionId;
 
      ------------------------------ 
 
        FROM
              Kernel_move_and_fill : VGG101;
 
        PROCEDURE
              SAPDB_PascalMove (
                    mod_id      : tsp00_C6;
                    mod_num     : tsp00_Int4;
                    source_upb  : tsp00_Int4;
                    dest_upb    : tsp00_Int4;
                    source      : tsp00_MoveObjPtr;
                    src_pos     : tsp00_Int4;
                    destin      : tsp00_MoveObjPtr;
                    dest_pos    : tsp00_Int4;
                    length      : tsp00_Int4;
                    VAR e       : tgg00_BasisError);
 
        PROCEDURE
              SAPDB_PascalForcedMove (
                    source_upb  : tsp00_Int4;
                    destin_upb  : tsp00_Int4;
                    source      : tsp00_MoveObjPtr;
                    source_pos  : tsp00_Int4;
                    destin      : tsp00_MoveObjPtr;
                    destin_pos  : tsp00_Int4;
                    length      : tsp00_Int4);
 
        PROCEDURE
              g10mv (
                    mod_id      : tsp00_C6;
                    mod_num     : tsp00_Int4;
                    source_upb  : tsp00_Int4;
                    dest_upb    : tsp00_Int4;
                    source      : tsp00_MoveObjPtr;
                    src_pos     : tsp00_Int4;
                    destin      : tsp00_MoveObjPtr;
                    dest_pos    : tsp00_Int4;
                    length      : tsp00_Int4;
                    VAR e       : tgg00_BasisError);
 
        PROCEDURE
              s10mv (
                    source_upb  : tsp00_Int4;
                    destin_upb  : tsp00_Int4;
                    source      : tsp00_MoveObjPtr;
                    source_pos  : tsp00_Int4;
                    destin      : tsp00_MoveObjPtr;
                    destin_pos  : tsp00_Int4;
                    length      : tsp00_Int4);
 
      ------------------------------ 
 
        FROM
              GG_edit_routines : VGG17;
 
        PROCEDURE
              g17hexto_line (c : char;
                    VAR ln_len : integer;
                    VAR ln     : tsp_c40);
 
        PROCEDURE
              g17trimint4_to_line (int : tsp00_Int4;
                    VAR ln_len : integer;
                    VAR ln     : tsp_c40);
 
      ------------------------------ 
 
        FROM
              RTE_kernel : VEN101;
 
        PROCEDURE
              vabort (write_core : boolean);
 
        PROCEDURE
              vbegexcl (pid : tsp00_TaskId;
                    region : tsp00_RegionId);
 
        PROCEDURE
              vendexcl (pid : tsp00_TaskId;
                    region : tsp00_RegionId);
 
        PROCEDURE
              vfwrite (hostfileno : tsp00_Int4;
                    buf         : tsp00_VfBufaddr;
                    VAR error   : tsp00_VfReturn;
                    VAR errtext : tsp00_ErrText);
 
        PROCEDURE
              vmalloc (length : tsp00_Int4;
                    VAR p  : tbd02_pDataCBlock;
                    VAR ok : boolean);
 
        PROCEDURE
              vmfree  (p : tbd02_pDataCBlock);
 
        PROCEDURE
              vprio (pid     : tsp00_TaskId;
                    prio     : tsp00_Uint1;
                    set_prio : boolean);
 
        PROCEDURE
              v2prio (pid : tsp00_TaskId;
                    prio     : tsp00_Uint1;
                    set_prio : boolean;
                    root     : tsp00_PageNo;
                    leaf     : tsp00_PageNo;
                    locktype : integer);
 
        PROCEDURE
              vresume (pid  : tsp00_TaskId);
 
        PROCEDURE
              vtracewriter_alive;
 
        FUNCTION
              RTEMem_AWEAvailable : boolean;
 
        FUNCTION
              RTEMem_AWENumOfPhysicalPages : tsp00_Int4;
 
        FUNCTION
              RTEMem_AWENumOfMapAreaPages : tsp00_Int4;
 
        FUNCTION
              RTEMem_AWENumOfFreePhysicalPages : tsp00_Int4;
 
        FUNCTION
              RTEMem_AWENumOfFreeMapAreaPages : tsp00_Int4;
 
        PROCEDURE
              RTEMem_AWEReservePhysPage (VAR PhysPageNo : tsp00_Int4);
 
        PROCEDURE
              RTEMem_AWEReleasePhysPage (PhysPageNo : tsp00_Int4);
 
        PROCEDURE
              RTEMem_AWEMap (
                    pMappingPageAddr : tbd_nodeptr;
                    PhysPageNo       : tsp00_Int4);
 
        PROCEDURE
              RTEMem_AWEUnMap (pMappingPageAddr : tbd_nodeptr);
 
        FUNCTION
              RTESys_MemProtectReadWrite(
                    pvAdr  : tbd_nodeptr;
                    ulSize : tsp00_Longint) : tsp00_Longint;
 
        FUNCTION
              RTESys_MemProtectReadOnly(
                    pvAdr  : tbd_nodeptr;
                    ulSize : tsp00_Longint) : tsp00_Longint;
 
      ------------------------------ 
 
        FROM
              RTE-Extension-20 : VSP20;
 
        PROCEDURE
              s20ch4 (val : tsp00_Int4;
                    VAR dest : tsp00_Page;
                    di       : tsp00_Int4);
 
      ------------------------------ 
 
        FROM
              RTE-Extension-30 : VSP30;
 
&       ifdef TRACE
      ------------------------------ 
 
        FROM
              Test_Procedures : VTA01;
 
        PROCEDURE
              t01addr (debug : tgg00_Debug;
                    nam     : tsp00_Sname;
                    pointer : tbd02_pDataCBlock);
 
        PROCEDURE
              t01addr2 (debug : tgg00_Debug;
                    nam1     : tsp00_Sname;
                    pointer1 : tbd02_pDataCBlock;
                    nam2     : tsp00_Sname;
                    pointer2 : tbd02_pDataCBlock);
 
        PROCEDURE
              t01bool (debug : tgg00_Debug;
                    nam      : tsp00_Sname;
                    curr_bool: boolean);
 
        PROCEDURE
              t01int4 (layer : tgg00_Debug;
                    nam : tsp00_Sname;
                    int : tsp00_Int4);
 
        PROCEDURE
              t01int4_addr (layer : tgg00_Debug;
                    nam1    : tsp00_Sname;
                    int     : tsp00_Int4;
                    nam2    : tsp00_Sname;
                    bufaddr : tbd02_pDataCBlock);
 
        PROCEDURE
              t01name (layer : tgg00_Debug;
                    nam : tsp00_Name);
 
        PROCEDURE
              t01p2int4 (layer : tgg00_Debug;
                    nam1 : tsp00_Sname;
                    int1 : tsp00_Int4;
                    nam2 : tsp00_Sname;
                    int2 : tsp00_Int4);
 
        FUNCTION
              t01trace (layer : tgg00_Debug) : boolean;
&       endif
 
.CM *-END-* use -----------------------------------------
.sp;.cp 3
Synonym :
 
        PROCEDURE
              g17hexto_line;
 
              tsp00_Line tsp_c40
 
        PROCEDURE
              g17trimint4_to_line;
 
              tsp00_Line tsp_c40
 
        FUNCTION
              RTEMem_AWEMap;
 
              tsp00_PageAddr tbd_nodeptr
 
        FUNCTION
              RTEMem_AWEUnMap;
 
              tsp00_PageAddr tbd_nodeptr
 
        FUNCTION
              RTESys_MemProtectReadWrite;
 
              tsp00_MoveObjPtr tbd_nodeptr
 
        FUNCTION
              RTESys_MemProtectReadOnly;
 
              tsp00_MoveObjPtr tbd_nodeptr
 
        PROCEDURE
              vmalloc;
 
              tsp00_ObjAddr tbd02_pDataCBlock
 
        PROCEDURE
              vmfree;
 
              tsp00_ObjAddr tbd02_pDataCBlock
 
        PROCEDURE
              vfwrite;
 
              tsp_vf_bufaddr tsp00_VfBufaddr
 
        PROCEDURE
              v2prio;
 
              integer  tsp00_PageNo
 
        PROCEDURE
              s20ch4;
 
              tsp00_MoveObj tsp00_Page
&             ifdef TRACE
 
        PROCEDURE
              t01addr;
 
              tsp00_BufAddr tbd02_pDataCBlock
 
        PROCEDURE
              t01addr2;
 
              tsp00_BufAddr tbd02_pDataCBlock
 
        PROCEDURE
              t01int4_addr;
 
              tsp00_BufAddr tbd02_pDataCBlock
&             endif
 
.CM *-END-* synonym -------------------------------------
.sp;.cp 3
Author  : JuergenP
.sp
.cp 3
Created : 1982-11-19
.sp
.cp 3
.sp
.cp 3
Release :      Date : 2000-11-21
.sp
***********************************************************
.sp
.cp 10
.fo
.oc _/1
Specification:
 
.CM *-END-* specification -------------------------------
.sp 2
************************************************************
.sp
.cp 10
.fo
.oc _/1
Description:
 
 
The dump file contains global structures of this module
in the following sequence :
.sp2;.nf
                                        length in bytes :
.sp
 
DUMPLABEL : 'B20BUFCO'                         8
DUMPCODE  :  205                               2
             B20BUF                     (int4) 4
 
 
DUMPLABEL : 'B20REGIO'                         8
DUMPCODE  :  203                               2
             DATAREGIONS                (int4) 4
 
 
DUMPLABEL : 'B20ALL  '                         8
DUMPCODE  :  237                               2
             B20NEXT_SHRINK_SEGMENT     (int4) 4
             B20TOTAL_CHANGED_PAGES     (int4) 4
             B20SVP_IS_REQUESTED        (bool) 1
 
 
The following informations are printed for each
datacache region:
 
DUMPLABEL : 'B20VARS '                         8
DUMPCODE  :  207                               2
             NO_OF_DATACACHE_REGION     (int4) 4
             DC_CACHE_SIZE              (int4) 4
             DC_FIRST_CB             (pointer) 4 (BIT64)
             DC_LAST_CB              (pointer) 4 (BIT64)
             DC_FIRST_LRU            (pointer) 4 (BIT64)
             DC_LAST_LRU             (pointer) 4 (BIT64)
             DC_MID                  (pointer) 4 (BIT64)
             DC_IO_MID               (pointer) 4 (BIT64)
             DC_FREE_LIST            (pointer) 4 (BIT64)
             DC_FRAME_LESS_CBS       (pointer) 4
             DC_FREE_COUNT              (int4) 4
             DC_UNMAP_FREE_COUNT        (int4) 4
             DC_FRAME_LESS_CB_CNT       (int4) 4
             DC_HEAD_LIST_SIZE          (int4) 4
             DC_SVP_ELEMS               (int4) 4
             DC_IO_ELEMS                (int4) 4
             DC_NUM_SPLIT_LOCKS         (int4) 4
             DC_OLD_OCCUPANTS           (int4) 4
             DC_IO_AREA_SIZE            (int4) 4
             DC_REC_REA_SIZE           (int4) 4
             DC_IO_AREA_FLUSH_COUNT     (int4) 4
             DC_LRU_TAIL_FLUSH_COUNT    (int4) 4
             DC_UNDO_PAGE_COUNT         (int4) 4
             DC_OMS_DATA_COUNT          (int4) 4
             DC_SQL_DATA_COUNT          (int4) 4
             DC_IOQ_HEAD_1           (pointer) 4 (BIT64)
             DC_IOQ_HEAD_2           (pointer) 4 (BIT64)
             DC_IOQ_TAIL_1           (pointer) 4 (BIT64)
             DC_IOQ_TAIL_2           (pointer) 4 (BIT64)
             DC_OVERFLOW_PID_QUEUE   (pointer) 4 (BIT64)
             DC_PID_QUEUE_HEAD       (pointer) 4 (BIT64)
             DC_PID_QUEUE_FREE       (pointer) 4 (BIT64)
             DC_BUFFER_ACTIVE           (bool) 1
             DC_SVP_ACTIVE              (bool) 1
             DC_PREVENT_SPLIT           (bool) 1
             DC_IS_SWITCH               (bool) 1
 
 
DUMPLABEL : 'B20HDLIS'                         8
DUMPCODE  :  209                               2
             DC_HEAD_LIST_SIZE          (int4) 4
             HD_ELEMS_OCCUPIED          (int4) 4
             HD_ELEMS_ON_THIS_PAGE      (int2) 2
             IS_END_OF_HDLIST           (bool) 1
 
             T_HEAD_LIST_ELEM
                ARRAYINDEX              (int4) 4
                HE_CB                (pointer) 4 (BIT64
                HE_OLD_OCC_CNT          (int4) 4
                HE_FILL                 (int4) 4 (BIT64)
 
 
DUMPLABEL : 'B20HDLFO'                         8
DUMPCODE  :  211                               2
             HD_ELEMS_ON_THIS_PAGE      (int2) 2
             IS_END_OF_HDLIST           (bool) 1
 
 
DUMPCODE  : 'B20CBLOC'                         8
DUMPCODE  :  213                               2
             DCB_ELEMS_ON_THIS_PAGE     (int2) 2
             IS_END_OF_CBLIST           (bool) 1
 
             CONTROLBLOCK
                STORAGE_ADDRESS               (pointer) 4 (BIT64)
                DCB_OCCUPANT                     (int4) 4
                DCB_FRAMEPTR                  (pointer) 4 (BIT64)
                DCB_FRAMEPTR^.ID                 (int4) 4
                DCB_LAST_OWNER                   (int4) 4
                DCB_OLD_OCCUPANT                 (int4) 4
                DCB_FIXED_NEXT                (pointer) 4 (BIT64)
                DCB_VAR_NEXT                  (pointer) 4 (BIT64)
                DCB_LRU_NEXT                  (pointer) 4 (BIT64)
                DCB_LRU_PREV                  (pointer) 4 (BIT64)
                DCB_QUEUE_OCC                 (pointer) 4 (BIT64)
                DCB_QUEUE_OLD_OCC             (pointer) 4 (BIT64)
                DCB_LOCK_REQ_HEAD             (pointer) 4 (BIT64)
                DCB_LOCK_REQ_TAIL             (pointer) 4 (BIT64)
                DCB_IO_PREV                   (pointer) 4 (BIT64)
                DCB_IO_NEXT                   (pointer) 4 (BIT64)
                DCB_USAGE                        (int2) 2
                DCB_CHANGED_STATE  (tbd02_ChangedState) 1
                DCB_IO_STATE               (t_io_state) 1
                DCB_LRU_RECHAIN                  (bool) 1
                DCB_TFN                      (tfn_type) 1
                DCB_IS_COPY_SOURCE               (bool) 1
                DCB_EXCLUSIVE_LOCKED             (bool) 1
                DCB_OLD_RECMODE                  (enum) 1
                DCB_DW_IO_AREA                   (bool) 1
                DCB_COPY_NO                      (int1) 1
                DCB_RECMODE                      (enum) 1
 
 
DUMPLABEL : 'B20CBLFO'                         8
DUMPCODE  :  215                               2
             DCB_ELEMS_ON_THIS_PAGE     (int2) 2
             IS_END_OF_CBLIST           (bool) 1
 
 
DUMPLABEL : 'B20QUELE'                         8
DUMPCODE  :  217                               2
             DCB_ELEMS_ON_THIS_PAGE     (int2) 2
             IS_END_OF_CBLIST           (bool) 1
 
             T_PID_QUEUE_ELEM
                STORAGE_ADDRESS      (pointer) 4 (BIT64)
                PQE_CHAIN            (pointer) 4 (BIT64)
                PQE_NEXT             (pointer) 4 (BIT64)
                PQE_PID                 (int4) 4
                PQE_STATE               (int1) 1
                PQE_FILL1               (bool) 1
                PQE_FILL2               (int2) 2
 
 
DUMPLABEL : 'B20QUFOL'                         8
DUMPCODE  :  219                               2
             DCB_ELEMS_ON_THIS_PAGE     (int2) 2
             IS_END_OF_CBLIST           (bool) 1
 
 
.CM *-END-* description ---------------------------------
.sp 2
**********************************************************
.sp
.cp 10
.nf
.oc _/1
Structure:
 
.CM *-END-* structure -----------------------------------
.sp 2
**********************************************************
.sp
.cp 10
.nf
.oc _/1
.CM -lll-
Code    :
 
 
(* ++++++++++++++++ *)
&ifdef TRACE
&define SUSP_REASON
&endif
&if $OS = WIN32 AND NOT DEFINED BIT64
&define AWE_USAGE
&endif
&if $KIND = SLOW or $KIND = QUICK
&ifdef AWE_USAGE
&define TEST_AWE
&endif
&endif
(* ++++++++++++++++ *)
CONST
      c_hl_lower_lim           =    9973;
      c_hl_upper_lim           = 1999993;
      c_max_aux_cbs            = 2000000;
      c_max_copies             =       2;
      c_max_headlist           = 2000000;
      c_max_pids               =   66000;
      c_nil_hash               =      -1;
      c_p50_percent            =       2;
      c_rechain_frac           =      10;
      c_dc_task_prio           =       2;
      (* *)
      NIL_AWE_HANDLE_BD20      = NIL_PAGE_NO_GG00;
      FIRST_SEGMENT_BD20       =  0;
      LAST_SEGMENT_BD20        = 63;
      MAX_AUX_IO_FRAMES_BD20   = MAX_DATA_WRITER_BD00 * MAX_VF_BUFFERS_BD00;
      MAX_AUX_IO_FRAMES_BD20_1 = MAX_AUX_IO_FRAMES_BD20 - 1;
      (* *)
      ASSERT_ID_1_BD20        = 1;
      ASSERT_ID_2_BD20        = 2;
      ASSERT_ID_3_BD20        = 3;
      ASSERT_ID_4_BD20        = 4;
      ASSERT_ID_5_BD20        = 5;
      ASSERT_ID_6_BD20        = 6;
      ASSERT_ID_7_BD20        = 7;
      ASSERT_ID_8_BD20        = 8;
      ASSERT_ID_9_BD20        = 9;
      ASSERT_ID_10_BD20       = 10;
      ASSERT_ID_11_BD20       = 11;
      ASSERT_ID_12_BD20       = 12;
      ASSERT_ID_13_BD20       = 13;
      ASSERT_ID_14_BD20       = 14;
      ASSERT_ID_15_BD20       = 15;
      ASSERT_ID_16_BD20       = 16;
      ASSERT_ID_17_BD20       = 17;
      ASSERT_ID_18_BD20       = 18;
      (* *)
      ADD_TMP_TO_IO_CHAIN_BD20 =    true;
      IS_VIRTUAL_IO_BD20       =    true;
      IS_READ_IO_BD20      =    true;
      RESUME_ALL_BD20          =    true;
      SET_PRIO_BD20            =    true;
      WRITE_CORE_BD20          =    true;
      IGNORE_DIRTY_PAGES_BD20  =    true;
      (* *)
      MSG_MID_EXIST           = 'MID ALREADY EXIST       ';
      MSG_IOMID_EXIST         = 'IO MID ALREADY EXIST    ';
      MSG_LOCK_FREE           = 'B20RESUME L FREE (copy) ';
      MSG_FLUSH               = 'B20RESUME FLUSH         ';
      MSG_FREE                = 'B20RESUME FREE          ';
      MSG_RESET_IO_STATE      = 'B20RESUME RESET IO STATE';
      MSG_WRELEASE            = 'B20RESUME W_RELEASE     ';
      MSG_SHUTDOWN            = 'B20RESUME SHUTDOWN      ';
      MSG_USE_PAGE            = 'B20RESUME USE PAGE      ';
      MSG_REPLACE             = 'B20RESUME OLD_OCCUP     ';
      MSG_NO_MORE_MEMORY      = 'NO MORE MEMORY          ';
      MSG_NO_AUX_FRAMES       = 'NO AUX FRAMES AVAILABLE ';
      MSG_CBLOCK_NOT_FOUND    = 'CBLOCK NOT FOUND        ';
      MSG_LOOP_OVERFLOW       = 'MORE LOOPS THAN CBLOCKS ';
 
TYPE
 
      t_head_list_elem = RECORD
            he_cb          : tbd02_pDataCBlock;
            he_old_occ_cnt : tsp00_Int4;
&           ifdef BIT64
            he_fill        : tsp00_Int4;
&           endif
      END;
 
      t_head_list = ARRAY [0..c_max_headlist] OF t_head_list_elem;
      (* *)
      t_head_list_ptr = ^t_head_list;
      (* *)
      t_aux_controlblocks = ARRAY [0..c_max_aux_cbs] OF tbd02_DataCBlock;
      (* *)
      t_aux_pid_queue_list = ARRAY [1..c_max_pids] OF tbd02_TaskQueueItem;
      (* *)
      t_aux_cb_ptr = ^t_aux_controlblocks;
      (* *)
      t_aux_pid_queue_ptr  = ^t_aux_pid_queue_list;
      (* *)
 
      t_AWE_FramePoolEntry = RECORD
            fpe_pFrame_bd20 : tbd_nodeptr;
      END;
 
      t_AWE_FramePool = ARRAY [0..MAX_AUX_IO_FRAMES_BD20_1] OF t_AWE_FramePoolEntry;
      (* *)
      t_pAWE_FramePool = ^t_AWE_FramePool;
 
      b20ptr = RECORD
            CASE integer OF
                1 :
                    (nodeaddr       : tbd_nodeptr);
                2 :
                    (cblockaddr     : tbd02_pDataCBlock);
                3 :
                    (aux_cb_addr    : t_aux_cb_ptr);
                4 :
                    (pid_queue_addr : tbd02_pTaskQueueItem);
                5 :
                    (aux_hl_addr    : t_head_list_ptr);
                6:
                    (aux_chain_addr : t_aux_pid_queue_ptr);
                7:
                    (pAuxFramePool  : t_pAWE_FramePool);
                END;
            (*ENDCASE*) 
 
 
      t_datacache = RECORD
            dc_pHeadList          : t_head_list_ptr;
            dc_pAWEAuxBuffer      : tbd_nodeptr;  (* AWE *)
            (* *)
            dc_pIOQueueHead1      : tbd02_pDataCBlock;
            dc_pIOQueueHead2      : tbd02_pDataCBlock;
            dc_pIOQueueTail1      : tbd02_pDataCBlock;
            dc_pIOQueueTail2      : tbd02_pDataCBlock;
            dc_pFirstCBlock       : tbd02_pDataCBlock;
            dc_pLastCBlock        : tbd02_pDataCBlock;
            dc_pFirstLRU          : tbd02_pDataCBlock;
            dc_pLastLRU           : tbd02_pDataCBlock;
            dc_pMid               : tbd02_pDataCBlock;
            dc_pIOMid             : tbd02_pDataCBlock;
            dc_pFreeList          : tbd02_pDataCBlock;
            dc_pFrameLessCBlocks  : tbd02_pDataCBlock;
            dc_pUnMapFreeList     : tbd02_pDataCBlock; (* AWE *)
            dc_pLastMappedCBlock  : tbd02_pDataCBlock; (* AWE *)
            (* *)
            dc_pTaskQueueHead     : tbd02_pTaskQueueItem;
            dc_pTaskQueueFree     : tbd02_pTaskQueueItem;
            dc_pOverflowTaskQueue : tbd02_pTaskQueueItem;
            dc_pSvpEndTaskQueue   : tbd02_pTaskQueueItem;
            (* *)
            dc_SegmentId          : tsp00_Int4;
            dc_IOAreaSize         : tsp00_Int4;
            dc_SVPElems           : tsp00_Int4;
            dc_IOElems            : tsp00_Int4;
            dc_HeadListSize       : tsp00_Int4;
            dc_FreeCount          : tsp00_Int4;
            dc_OldOccupants       : tsp00_Int4;
            dc_SegmentSize        : tsp00_Int4;
            dc_RecAreaSize        : tsp00_Int4;
            dc_NumSplitLocks      : tsp00_Int4;
            dc_IOAreaFlushCnt     : tsp00_Int4;
            dc_LruTailFlushCnt    : tsp00_Int4;
            dc_FrameLessCBlockCnt : tsp00_Int4;
            dc_UndoFilePageCnt    : tsp00_Int4;
            dc_OmsDataPageCnt     : tsp00_Int4;
            dc_OmsTempPageCnt     : tsp00_Int4;
            dc_SqlDataPageCnt     : tsp00_Int4;
            dc_UnMapFreeCount     : tsp00_Int4; (* AWE *)
            dc_UnMapAreaSize      : tsp00_Int4; (* AWE *)
            (* *)
            dc_UndoFileHit        : tsp00_8ByteCounter;
            dc_UndoFileMiss       : tsp00_8ByteCounter;
            dc_OmsDataHit         : tsp00_8ByteCounter;
            dc_OmsDataMiss        : tsp00_8ByteCounter;
            dc_SqlDataHit         : tsp00_8ByteCounter;
            dc_SqlDataMiss        : tsp00_8ByteCounter;
            (* *)
            dc_SVPActive          : boolean;
            dc_SegmentActive      : boolean;
            dc_PreventSplit       : boolean;
            dc_IOSwitch           : boolean;
            dc_MemoryProtection   : boolean;
      END;
 
 
VAR
      bd20ForArchive           : boolean;
      bd20CBlockInit           : tbd02_DataCBlockInit;
      bd20DataCacheList        : ARRAY [FIRST_SEGMENT_BD20..LAST_SEGMENT_BD20] OF t_datacache;
      bd20RegionCount          : tsp00_Int4;
      bd20TotalChangedPages    : tsp00_Int4;
      bd20NextShrinkSegment    : tsp00_Int4;
      (* *)
&     ifdef AWE_USAGE
 
      bd20AWEFramePool : RECORD
            fp_pPool_bd20       : t_pAWE_FramePool;
            fp_OccupiedCnt_bd20 : tsp00_Int4;
            fp_PoolSize_bd20    : tsp00_Int4
      END;
 
&     endif
 
 
(*------------------------------*) 
 
FUNCTION
      bd20GetNumberOfChangedPages : tsp00_Int4;
 
BEGIN
bd20GetNumberOfChangedPages := bd20TotalChangedPages;
END;
 
(*------------------------------*) 
 
PROCEDURE
      bd20CheckExclusiveLockedPageForIO (
            TaskId         : tsp00_TaskId;
            VAR FileId     : tgg00_FileId;
            PageNo         : tsp00_PageNo;
            recMode        : tbd02_RecoveryMode;
            pCBlock        : tbd02_pDataCBlock;
            VAR bWritePage : boolean;
            VAR PageState  : tbd02_CachePageState);
 
VAR
      RegOffset     : integer;
      HashIndex     : tsp00_Int4;
      pPredCBlock   : tbd02_pDataCBlock; (* not used *)
      pCurrCBlock   : tbd02_pDataCBlock; (* not used *)
      pSourceCBlock : tbd02_pDataCBlock;
 
BEGIN
bWritePage := false;
IF  (pCBlock^.dcb_UsageCnt_bd02 = 1                 ) AND
    (pCBlock^.dcb_io_state = iosBlocked_ebd02       ) AND
    (pCBlock^.dcb_ChangedState_bd02 <> cstNone_ebd02)
THEN
    BEGIN
    RegOffset  := PageNo MOD bd20RegionCount;
    HashIndex  := PageNo MOD bd20DataCacheList [RegOffset].dc_HeadListSize;
    (* *)
    vbegexcl (TaskId, g08data1 + RegOffset);
    (* *)
    WITH bd20DataCacheList [RegOffset] DO
        BEGIN
        IF  dc_SegmentActive
        THEN
            BEGIN
            IF  (dc_SVPActive AND (pCBlock^.dcb_ChangedState_bd02 = cstSvpRelevant_ebd02  )) OR
                ((NOT dc_SVPActive) AND (pCBlock^.dcb_ChangedState_bd02 = cstChanged_ebd02))
            THEN
                BEGIN
                IF  pCBlock^.dcb_copy_no = 0
                THEN
                    bWritePage := true
                ELSE
                    BEGIN (* dcb_copy_no > 0 ==> pSourceCBlock <> NIL *)
                    PageState.cpsWaitForWrite_bd02 := true;
                    bd20c_search_in_chain_incl_copy (bd20DataCacheList [RegOffset],
                          HashIndex, PageNo, recMode, pCurrCBlock, pPredCBlock,
                          PageState.cpsFound_bd02, pSourceCBlock);
                    bd20_InsertOccupant (TaskId, FileId, bd20DataCacheList [RegOffset],
                          pSourceCBlock)
                    END
                (*ENDIF*) 
                END
            ELSE
                IF  (dc_SVPActive AND (pCBlock^.dcb_ChangedState_bd02 = cstChanged_ebd02))
                THEN
                    BEGIN
                    PageState.cpsWaitForSvpEnd_bd02 := true;
                    bd20_InsertSavepointEnd (TaskId, FileId, bd20DataCacheList [RegOffset]);
                    END;
                (*ENDIF*) 
            (*ENDIF*) 
            END
        (*ENDIF*) 
        END;
    (*ENDWITH*) 
    (* *)
    vendexcl (TaskId, g08data1 + RegOffset);
    (* *)
    END
(*ENDIF*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      bd20CheckRootNptrs (
            TaskId      : tsp00_TaskId;
            VAR TrError : tgg00_BasisError;
            Root        : tsp00_PageNo;
            pNode       : tbd_nodeptr;
            pCBlock     : tbd02_pDataCBlock);
 
VAR
      RegOffset : integer;
 
BEGIN
(* PTS 1106125 TS 2000-03-24 *)
RegOffset := Root MOD bd20RegionCount;
vbegexcl (TaskId, g08data1 + RegOffset);
IF  NOT bd20DataCacheList [RegOffset].dc_SegmentActive
THEN
    TrError := e_shutdown
ELSE
    BEGIN
    IF  pNode^.nd_id <> Root
    THEN
        g01abort (csp3_b20x1_illegal_page_no, csp3_n_datacache,
              'BD20CheckRoot id <> root', pNode^.nd_id);
    (*ENDIF*) 
    IF  pCBlock <> NIL
    THEN
        BEGIN
        IF  pCBlock^.dcb_occupant <> pNode^.nd_id
        THEN
            g01abort (csp3_b20x1_illegal_page_no, csp3_n_datacache,
                  'BD20CheckRoot occu <> id', pNode^.nd_id);
        (*ENDIF*) 
        END
    (*ENDIF*) 
    END;
(*ENDIF*) 
vendexcl (TaskId, g08data1 + RegOffset);
(* PTS 1106125 *)
END;
 
(*------------------------------*) 
 
PROCEDURE
      bd20ClearAccessStatistic(
            TaskId : tsp00_TaskId );
 
VAR
      RegOffset : tsp00_Int4;
 
BEGIN
FOR RegOffset := 0 TO bd20RegionCount - 1 DO
    WITH bd20DataCacheList [RegOffset] DO
        BEGIN
        vbegexcl (TaskId, g08data1 + RegOffset);
        dc_UndoFileHit      := 0;
        dc_UndoFileMiss     := 0;
        dc_OmsDataHit       := 0;
        dc_OmsDataMiss      := 0;
        dc_SqlDataHit       := 0;
        dc_SqlDataMiss      := 0;
        vendexcl (TaskId, g08data1 + RegOffset);
        END
    (*ENDWITH*) 
(*ENDFOR*) 
END;
 
(*------------------------------*) 
 
FUNCTION
      bd20GetFileTfn (
            pCBlock : tbd02_pDataCBlock) : tgg00_Tfn;
 
BEGIN
IF  NIL = pCBlock
THEN
    bd20GetFileTfn := tfnNil_egg00
ELSE
    bd20GetFileTfn := pCBlock^.dcb_tfn
(*ENDIF*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      bd20GetAccessStatistic(
            TaskId               : tsp00_TaskId;
            VAR HistoryTotal     : tsp00_8ByteCounter;
            VAR HistoryHit       : tsp00_8ByteCounter;
            VAR HistoryMiss      : tsp00_8ByteCounter;
            VAR OmsDataTotal     : tsp00_8ByteCounter;
            VAR OmsDataHit       : tsp00_8ByteCounter;
            VAR OmsDataMiss      : tsp00_8ByteCounter;
            VAR SqlDataTotal     : tsp00_8ByteCounter;
            VAR SqlDataHit       : tsp00_8ByteCounter;
            VAR SqlDataMiss      : tsp00_8ByteCounter);
 
VAR
      RegOffset : tsp00_Int4;
 
BEGIN
HistoryTotal  := 0;
HistoryHit    := 0;
HistoryMiss   := 0;
OmsDataTotal  := 0;
OmsDataHit    := 0;
OmsDataMiss   := 0;
SqlDataTotal  := 0;
SqlDataHit    := 0;
SqlDataMiss   := 0;
(* *)
FOR RegOffset := 0 TO bd20RegionCount - 1 DO
    WITH bd20DataCacheList [RegOffset] DO
        BEGIN
        vbegexcl (TaskId, g08data1 + RegOffset);
        (* *)
        HistoryHit   := HistoryHit   + dc_UndoFileHit;
        HistoryMiss  := HistoryMiss  + dc_UndoFileMiss;
        HistoryTotal := HistoryTotal + dc_UndoFileHit + dc_UndoFileMiss;
        (* *)
        OmsDataHit      := OmsDataHit   + dc_OmsDataHit;
        OmsDataMiss     := OmsDataMiss  + dc_OmsDataMiss;
        OmsDataTotal    := OmsDataTotal + dc_OmsDataHit + dc_OmsDataMiss;
        (* *)
        SqlDataHit      := SqlDataHit   + dc_SqlDataHit;
        SqlDataMiss     := SqlDataMiss  + dc_SqlDataMiss;
        SqlDataTotal    := SqlDataTotal + dc_SqlDataHit + dc_SqlDataMiss;
        vendexcl (TaskId, g08data1 + RegOffset);
        END;
    (*ENDWITH*) 
(*ENDFOR*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      bd20GetCacheSize (
            VAR TotalPages : tsp00_Int4;
            VAR UnMapPages : tsp00_Int4);
 
VAR
      RegOffset : tsp00_Int4;
 
BEGIN
TotalPages := 0;
UnMapPages := 0;
FOR RegOffset := 0 TO bd20RegionCount - 1 DO
    BEGIN
    TotalPages := TotalPages + bd20DataCacheList [RegOffset].dc_SegmentSize;
    UnMapPages := UnMapPages + bd20DataCacheList [RegOffset].dc_UnMapAreaSize;
    END
(*ENDFOR*) 
END;
 
(*------------------------------*) 
 
FUNCTION
      bd20_GetCacheSize : tsp00_Int4;
 
VAR
      CacheSize : tsp00_Int4;
      RegOffset : tsp00_Int4;
 
BEGIN
CacheSize := 0;
FOR RegOffset := 0 TO bd20RegionCount - 1 DO
    CacheSize := CacheSize + bd20DataCacheList [RegOffset].dc_SegmentSize;
(*ENDFOR*) 
bd20_GetCacheSize := CacheSize;
END;
 
(*------------------------------*) 
 
PROCEDURE
      bd20GetWorkloadCounter (
            VAR DataCacheSize          : tsp00_Int4;
            VAR OmsHistoryPageCnt      : tsp00_Int4;
            VAR OmsDataPageCnt         : tsp00_Int4;
            VAR OmsUnloadedVersPageCnt : tsp00_Int4;
            VAR SqlDataPageCnt         : tsp00_Int4);
 
VAR
      RegOffset      : tsp00_Int4;
 
BEGIN
(* PTS 1111572 E.Z. *)
OmsHistoryPageCnt      := 0;
OmsDataPageCnt         := 0;
OmsUnloadedVersPageCnt := 0;
SqlDataPageCnt         := 0;
DataCacheSize          := bd20_GetCacheSize;
(* *)
(* Dirty read to avoid performance problems *)
(* *)
FOR RegOffset := 0 TO bd20RegionCount - 1 DO
    WITH bd20DataCacheList [RegOffset] DO
        BEGIN
        OmsHistoryPageCnt      := OmsHistoryPageCnt      + dc_UndoFilePageCnt;
        OmsDataPageCnt         := OmsDataPageCnt         + dc_OmsDataPageCnt;
        OmsUnloadedVersPageCnt := OmsUnloadedVersPageCnt + dc_OmsTempPageCnt;
        SqlDataPageCnt         := SqlDataPageCnt         + dc_SqlDataPageCnt;
        END
    (*ENDWITH*) 
(*ENDFOR*) 
END;
 
(*------------------------------*) 
 
FUNCTION
      bd20IsPageRequested (cbptr : tbd02_pDataCBlock) : boolean;
 
BEGIN
bd20IsPageRequested := (cbptr^.dcb_lock_req_head <> NIL);
END;
 
&ifdef TESTONLY
(*------------------------------*) 
 
PROCEDURE
      bd20ReduceCache(TaskId : tsp00_TaskId);
 
VAR
      AuxPtr  : tbd_nodeptr;
 
BEGIN
IF  bd20DataCacheList [FIRST_SEGMENT_BD20].dc_SegmentActive
THEN
    WITH bd20DataCacheList[ FIRST_SEGMENT_BD20 ] DO
        BEGIN
        IF  ( dc_FrameLessCBlockCnt < (( dc_SegmentSize + dc_FrameLessCBlockCnt ) DIV 2 ))
        THEN
            BEGIN
            AuxPtr := bd20ReduceDataCache( TaskId );
            g01opmsg (sp3p_knldiag, sp3m_info, csp3_bd_msg, csp3_n_datacache,
                  'TimeOut Task Reduce Cach', dc_SegmentSize);
            END;
        (*ENDIF*) 
        END;
    (*ENDWITH*) 
(*ENDIF*) 
END;
 
&endif
(*------------------------------*) 
 
FUNCTION
      bd20ReduceDataCache (TaskId : tsp00_TaskId) : tbd_nodeptr;
 
VAR
      Dummy               : boolean;
      bFoundAWE           : boolean;    (* PTS 1114525 TS 2002-02-27 *)
      DummyCnt            : tsp00_Int4; (* PTS 1114525 TS 2002-02-27 *)
      CurrRegOffset       : tsp00_Int4; (* PTS 1111664 TS 2001-11-27 *)
      StopRegOffset       : tsp00_Int4; (* PTS 1111664 TS 2001-11-27 *)
      HashIndex           : tsp00_Int4;
      CBlockCnt           : tsp00_Int4;
      NumOfRechainCBlocks : tsp00_Int4;
      NumOfIOAreaCBlocks  : tsp00_Int4;
      pFrame              : tbd_nodeptr;
      pCBlock             : tbd02_pDataCBlock;
      pPredCBlock         : tbd02_pDataCBlock;
      pUsableCBlock       : tbd02_pDataCBlock; (* PTS 1114525 TS 2002-02-27 *)
 
BEGIN
pCBlock       := NIL;
pFrame        := NIL;
pUsableCBlock := NIL; (* PTS 1114525 TS 2002-02-27 *)
(* *)
vbegexcl (TaskId, g08datacache);
(* *)
CurrRegOffset         := bd20NextShrinkSegment;
bd20NextShrinkSegment := (bd20NextShrinkSegment + 1) MOD bd20RegionCount;
(* *)
vendexcl (TaskId, g08datacache);
(* *)
StopRegOffset := CurrRegOffset;
REPEAT   (* PTS 1111664 TS 2001-11-27 *)
    (* *)
    vbegexcl (TaskId, g08data1 + CurrRegOffset);
    (* *)
    WITH bd20DataCacheList [CurrRegOffset] DO
        BEGIN
        IF  (dc_pFreeList <> NIL)
        THEN
            BEGIN
            dc_FreeCount  := dc_FreeCount - 1;
            pCBlock       := dc_pFreeList;
            pFrame        := pCBlock^.dcb_pFrame_bd02;
            dc_pFreeList  := pCBlock^.dcb_VarNext_bd02;
            END
        ELSE
            BEGIN
            IF  dc_pLastMappedCBlock <> NIL
            THEN
                pCBlock := dc_pLastMappedCBlock
            ELSE
                pCBlock := dc_pLastLRU;
            (*ENDIF*) 
            WHILE (pFrame = NIL) AND (pCBlock <> NIL) DO
                WITH pCBlock^ DO
                    BEGIN (* PTS 1114525 TS 2002-02-27 *)
                    IF  (dcb_UsageCnt_bd02 <> 0       ) OR
                        (dcb_io_state <> iosNone_ebd02) OR
                        (dcb_pFrame_bd02 = NIL        ) OR
                        (dcb_IsSourceOfACopy_bd02     ) OR  (* PTS 1123610 HH 2003-08-13 *)
                        (dcb_copy_no <> 0)
                    THEN
                        pCBlock := dcb_lru_prev
                    ELSE
                        BEGIN (* Usable *)
                        IF  (dcb_ChangedState_bd02 = cstNone_ebd02)
                        THEN
                            BEGIN
                            pFrame    := pCBlock^.dcb_pFrame_bd02;
                            HashIndex := pCBlock^.dcb_occupant MOD dc_HeadListSize;
                            bd20_SearchInChain (bd20DataCacheList [CurrRegOffset], HashIndex, pCBlock^.dcb_occupant,
                                  pCBlock^.dcb_RecMode_bd02, pCBlock, pPredCBlock, Dummy);
                            bd20del_from_chain (bd20DataCacheList [CurrRegOffset], HashIndex, pCBlock, pPredCBlock);
                            bd20_DelFromLRUList (bd20DataCacheList [CurrRegOffset], pCBlock);
                            bd20_DecrementWorkloadCounter (bd20DataCacheList [CurrRegOffset], pCBlock^.dcb_tfn);
                            END
                        ELSE
                            BEGIN
                            IF  pUsableCBlock = NIL
                            THEN
                                pUsableCBlock := pCBlock;
                            (*ENDIF*) 
                            pCBlock := dcb_lru_prev
                            END
                        (*ENDIF*) 
                        END;
                    (*ENDIF*) 
                    END;
                (*ENDWITH*) 
            (*ENDWHILE*) 
&           ifdef AWE_USAGE
            IF  ((pFrame = NIL) AND (pUsableCBlock <> NIL) AND (dc_UnMapAreaSize > 0))
            THEN
                BEGIN (* PTS 1114525 TS 2002-02-27 *)
                bd20_SearchAndUseUnMappedFrame (bd20DataCacheList [CurrRegOffset],
                      pUsableCBlock, DummyCnt, bFoundAWE);
                IF  bFoundAWE
                THEN
                    BEGIN
                    pCBlock := pUsableCBlock;
                    pFrame  := pCBlock^.dcb_pFrame_bd02;
                    bd20_DelFromLRUList (bd20DataCacheList [CurrRegOffset], pCBlock);
                    END;
                (*ENDIF*) 
                END;
&           endif
            (*ENDIF*) 
            END;
        (*ENDIF*) 
        IF  pFrame = NIL
        THEN
            BEGIN
            (* *)
            vendexcl (TaskId, g08data1 + CurrRegOffset);
            (* *)
            CurrRegOffset := (CurrRegOffset + 1) MOD bd20RegionCount;
            END
        ELSE
            BEGIN (* bFound *)
            dc_FrameLessCBlockCnt         := dc_FrameLessCBlockCnt + 1;
            pPredCBlock                   := dc_pFrameLessCBlocks;
            pCBlock^.dcb_VarNext_bd02     := pPredCBlock;
            dc_pFrameLessCBlocks          := pCBlock;
            pCBlock^.dcb_pFrame_bd02      := NIL;
&           ifdef AWE_USAGE
            pCBlock^.dcb_AWE_BlockNo_bd02 := NIL_AWE_HANDLE_BD20;
&           endif
            (* *)
            dc_SegmentSize := dc_SegmentSize - 1;
            dc_RecAreaSize := (dc_SegmentSize + 1) DIV c_rechain_frac;
            IF  dc_SegmentSize < 100
            THEN
                BEGIN
                dc_IOAreaSize      := (dc_SegmentSize + 1) DIV c_p50_percent;
                dc_IOAreaFlushCnt  := trunc (((dc_SegmentSize+1)/10) * 2);
                (* NOTE: dc_LruTailFlushCnt MUST BE LESS EQUAL THAN dc_RecAreaSize! *)
                dc_LruTailFlushCnt := trunc ((dc_RecAreaSize+1)/2);
                END
            ELSE
                BEGIN
                dc_IOAreaSize      := trunc (((dc_SegmentSize + 1) / 100)* g01dw_io_area_size);
                dc_IOAreaFlushCnt  := trunc (((dc_SegmentSize+1)/100) * g01dw_io_area_flush);
                dc_LruTailFlushCnt := trunc (((dc_RecAreaSize+1)/100) * g01dw_lru_tail_flush);
                END;
            (*ENDIF*) 
            (* Maintain rechain and io-area *)
            dc_pMid             := NIL;
            dc_pIOMid           := NIL;
            pCBlock             := dc_pLastLRU;
            CBlockCnt           := 1;
            NumOfRechainCBlocks := dc_RecAreaSize - dc_FreeCount - dc_UnMapFreeCount;
            NumOfIOAreaCBlocks  := dc_IOAreaSize - dc_FreeCount - dc_UnMapFreeCount;
            WHILE pCBlock <> NIL DO
                BEGIN
                IF  CBlockCnt <= NumOfRechainCBlocks
                THEN
                    pCBlock^.dcb_lru_rechain := true
                ELSE
                    BEGIN
                    pCBlock^.dcb_lru_rechain := false;
                    IF  CBlockCnt = NumOfRechainCBlocks + 1
                    THEN
                        dc_pMid := pCBlock;
                    (*ENDIF*) 
                    END;
                (*ENDIF*) 
                IF  CBlockCnt <= NumOfIOAreaCBlocks
                THEN
                    pCBlock^.dcb_dw_io_area := true
                ELSE
                    BEGIN
                    pCBlock^.dcb_dw_io_area := false;
                    IF  CBlockCnt = NumOfIOAreaCBlocks + 1
                    THEN
                        dc_pIOMid := pCBlock;
                    (*ENDIF*) 
                    END;
                (*ENDIF*) 
                CBlockCnt := CBlockCnt + 1;
                pCBlock   := pCBlock^.dcb_lru_prev;
                END;
            (*ENDWHILE*) 
            IF  bd20DataCacheList [CurrRegOffset].dc_MemoryProtection
            THEN
                bd20_ReadWriteAccessToFrame (bd20DataCacheList [CurrRegOffset], pFrame);
            (*ENDIF*) 
            IF  g01glob.datacachecheck
&               ifdef TEST_AWE
                OR
                (dc_UnMapAreaSize > 0)
&               endif
            THEN
                bd20_CheckLRUList (bd20DataCacheList [CurrRegOffset]);
            (* *)
            (*ENDIF*) 
            vendexcl (TaskId, g08data1 + CurrRegOffset);
            (* *)
            END
        (*ENDIF*) 
        END
    (*ENDWITH*) 
UNTIL
    ((pFrame <> NIL) OR (CurrRegOffset = StopRegOffset));
(*ENDREPEAT*) 
IF  pFrame = NIL
THEN
    g01opmsg (sp3p_knldiag, sp3m_error, csp3_bd_msg, csp3_n_datacache,
          'No free pages available ', 0);
(*ENDIF*) 
bd20ReduceDataCache := pFrame;
END;
 
(*------------------------------*) 
 
PROCEDURE
      bd20SavepointCompleted (
            TaskId           : tsp00_TaskId;
            ConverterVersion : tsp00_Int4);
 
VAR
      RegOffset : integer;
 
BEGIN
bd20TotalChangedPages := 0;
FOR RegOffset := 0 TO bd20RegionCount - 1 DO
    vbegexcl (TaskId, g08data1 + RegOffset);
(*ENDFOR*) 
FOR RegOffset := 0 TO bd20RegionCount - 1 DO
    WITH bd20DataCacheList [RegOffset] DO
        BEGIN
        bd20TotalChangedPages := bd20TotalChangedPages + dc_IOElems;
        dc_SVPActive          := false;
        bd20_ResumeOverflow (bd20DataCacheList [RegOffset], MAX_INT4_SP00);
        bd20_ResumeSavepointEnd (bd20DataCacheList [RegOffset]);
        IF  (0 <> dc_SVPElems)
        THEN
            g01abort (csp3_b20x1_check_io_cnt, csp3_n_savepoint,
                  'SVP NOT FINISHED        ', dc_SVPElems);
        (*ENDIF*) 
        IF  g01glob.datacachecheck
        THEN
            bd20check_svp_chain (bd20DataCacheList [RegOffset]);
        (*ENDIF*) 
        END;
    (*ENDWITH*) 
(*ENDFOR*) 
(* *)
FOR RegOffset := bd20RegionCount - 1 DOWNTO 0 DO
    vendexcl (TaskId, g08data1 + RegOffset);
(*ENDFOR*) 
(* *)
g01opmsg ( sp3p_knldiag, sp3m_info, csp3_b20_savepoint_completed,
      csp3_n_savepoint, 'B20SVP_COMPLETED        ', ConverterVersion);
END;
 
(* CR 1105627  *)
(*------------------------------*) 
 
PROCEDURE
      bd20DumpDataCache (
            VAR hostfile   : tgg00_VfFileref;
            VAR b          : tsp00_Page;
            VAR dump_pno   : tsp00_Int4;
            VAR pos        : integer;
            VAR host_error : tsp00_VfReturn;
            VAR errtext    : tsp00_ErrText);
 
VAR
      RegOffset : tsp00_Int4;
 
BEGIN
RegOffset := 0;
(* *)
(* First dump all the small structures and than the space consuming frames *)
(* *)
WHILE (host_error = vf_ok) AND (RegOffset <= bd20RegionCount - 1) DO
    BEGIN
    bd20_DumpDataCache (bd20DataCacheList [RegOffset], RegOffset,
          hostfile, b, dump_pno, pos, host_error, errtext);
    RegOffset := succ (RegOffset)
    END;
(*ENDWHILE*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      bd20_DumpDataCache (
            VAR datacache  : t_datacache;
            RegOffset      : tsp00_Int4;
            VAR hostfile   : tgg00_VfFileref;
            VAR b          : tsp00_Page;
            VAR dump_pno   : tsp00_Int4;
            VAR pos        : integer;
            VAR host_error : tsp00_VfReturn;
            VAR errtext    : tsp00_ErrText);
 
CONST
      mark0_b20bufco   = 'B20BUFCO';
      code0_b20bufco   = 205;
      mark1_b20hdlis   = 'B20HDLIS';
      code1_b20hdlis   = 209;
      mark2_b20hdlfo   = 'B20HDLFO';
      code2_b20hdlfo   = 211;
      mark3_b20cbloc   = 'B20CBLOC';
      code3_b20cbloc   = 213;
      mark4_b20cblfo   = 'B20CBLFO';
      code4_b20cblfo   = 215;
      mark5_b20vars    = 'B20VARS ';
      code5_b20vars    = 207;
      mark6_b20quele   = 'B20QUELE';
      code6_b20quele   = 217;
      mark7_b20qufol   = 'B20QUFOL';
      code7_b20qufol   = 219;
      mark11_b20regio  = 'B20REGIO';
      code11_b20regio  = 203;
      (* *)
      mark20_b20all    = 'B20ALL  ';
      code20_b20all    = 237;
 
VAR
      move_err           : tgg00_BasisError;
      dump_mark          : tsp00_C8;
      buf_ptr            : tsp00_VfBufaddr;
      act_block          : tbd02_pDataCBlock;
      act_pid_queue      : tbd02_pTaskQueueItem;
      p                  : b20ptr;
      i                  : tsp00_Int4;
      hd_elem_count      : tsp00_Int4;
      elems_on_page      : tsp00_Int4;
      elems_pos          : integer;
      cb_len             : integer;
      hd_elem_len        : integer;
      queue_elem_len     : integer;
      h_int              : tsp00_IntMapC2;
 
BEGIN
move_err     := e_ok;
buf_ptr      := @b;
cb_len       := sizeof (tbd02_DataCBlock)
      +         sizeof (tbd02_pDataCBlock)
      +         sizeof (tsp00_PageNo)
      +         sizeof (tsp00_PageNo);
hd_elem_len  := sizeof (t_head_list_elem)
      +         sizeof (tsp00_Int4);
WITH datacache DO
    BEGIN
    (* *)
    (* --- FILL PREVIOUS DUMPPAGE --- *)
    (* *)
    IF  host_error = vf_ok
    THEN
        g01new_dump_page (hostfile, b, dump_pno, pos, host_error, errtext);
    (*ENDIF*) 
    IF  host_error = vf_ok
    THEN
        BEGIN
        IF  RegOffset = 0
        THEN
            BEGIN
            (* *)
            (* --- BUFFERSIZE --- *)
            (* *)
            dump_mark := mark0_b20bufco;
            g10mv ('VBD20 ',   1,    
                  sizeof (dump_mark), sizeof (b),
                  @dump_mark, 1,
                  @b, pos, sizeof (dump_mark), move_err);
            move_err := e_ok; (* ignore error *)
            pos           := pos + sizeof (dump_mark);
            h_int.mapInt_sp00 := code0_b20bufco;
            b[pos]        := h_int.mapC2_sp00[1];
            b[pos + 1]    := h_int.mapC2_sp00[2];
            pos           := pos + 2;
            s20ch4 (bd20_GetCacheSize, b, pos);
            pos           := pos + 4;
            (* *)
            (* --- NO OF DATACACHE REGIONS --- *)
            (* *)
            dump_mark := mark11_b20regio;
            g10mv ('VBD20 ',   2,    
                  sizeof (dump_mark), sizeof (b),
                  @dump_mark, 1,
                  @b, pos, sizeof (dump_mark), move_err);
            move_err := e_ok; (* ignore error *)
            pos           := pos + sizeof (dump_mark);
            h_int.mapInt_sp00 := code11_b20regio;
            b[pos]        := h_int.mapC2_sp00[1];
            b[pos + 1]    := h_int.mapC2_sp00[2];
            pos           := pos + 2;
            s20ch4 (bd20RegionCount, b, pos);
            pos           := pos + 4;
            (* *)
            (* --- GENERAL INFO ABOUT CACHES --- *)
            (* *)
            dump_mark := mark20_b20all;
            g10mv ('VBD20 ',   3,    
                  sizeof (dump_mark), sizeof (b),
                  @dump_mark, 1,
                  @b, pos, sizeof (dump_mark), move_err);
            move_err := e_ok; (* ignore error *)
            pos           := pos + sizeof (dump_mark);
            h_int.mapInt_sp00 := code20_b20all;
            b[pos]        := h_int.mapC2_sp00[1];
            b[pos + 1]    := h_int.mapC2_sp00[2];
            pos           := pos + 2;
            s20ch4 (bd20NextShrinkSegment, b, pos);
            pos           := pos + 4;
            s20ch4 (bd20TotalChangedPages, b, pos);
            pos           := pos + 4;
            END;
        (* *)
        (* --- DATACACHE VARIABLES --- *)
        (* *)
        (*ENDIF*) 
        IF  host_error = vf_ok
        THEN
            BEGIN
            dump_mark := mark5_b20vars;
            g10mv ('VBD20 ',   4,    
                  sizeof (dump_mark), sizeof (b),
                  @dump_mark, 1,
                  @b, pos, sizeof (dump_mark), move_err);
            move_err := e_ok; (* ignore error *)
            pos := pos + sizeof (dump_mark);
            h_int.mapInt_sp00 := code5_b20vars;
            b[pos]     := h_int.mapC2_sp00[1];
            b[pos + 1] := h_int.mapC2_sp00[2];
            pos := pos + 2;
            s20ch4 (RegOffset, b, pos);
            pos := pos + 4;
            s20ch4 (dc_SegmentSize, b, pos);
            pos := pos + 4;
&           ifdef AWE_USAGE
            s20ch4 (dc_SegmentSize - dc_UnMapAreaSize, b, pos);
            pos := pos + 4;
            s20ch4 (dc_UnMapAreaSize, b, pos);
            pos := pos + 4;
&           endif
            (* *)
            g10mv ('VBD20 ',   5,    
                  sizeof (dc_pFirstCBlock), sizeof (b),
                  @dc_pFirstCBlock, 1,
                  @b, pos, sizeof (dc_pFirstCBlock), move_err);
            move_err := e_ok; (* ignore error *)
            pos      := pos + sizeof (dc_pFirstCBlock);
            (* *)
            g10mv ('VBD20 ',   6,    
                  sizeof (dc_pLastCBlock), sizeof (b),
                  @dc_pLastCBlock, 1,
                  @b, pos, sizeof (dc_pLastCBlock), move_err);
            move_err := e_ok; (* ignore error *)
            pos      := pos + sizeof (dc_pLastCBlock);
            (* *)
            g10mv ('VBD20 ',   7,    
                  sizeof (dc_pFirstLRU), sizeof (b),
                  @dc_pFirstLRU, 1,
                  @b, pos, sizeof (dc_pFirstLRU), move_err);
            move_err := e_ok; (* ignore error *)
            pos      := pos + sizeof (dc_pFirstLRU);
            (* *)
            g10mv ('VBD20 ',   8,    
                  sizeof (dc_pLastLRU), sizeof (b),
                  @dc_pLastLRU, 1,
                  @b, pos, sizeof (dc_pLastLRU), move_err);
            move_err := e_ok; (* ignore error *)
            pos      := pos + sizeof (dc_pLastLRU);
            (* *)
            g10mv ('VBD20 ',   9,    
                  sizeof (dc_pMid), sizeof (b),
                  @dc_pMid, 1,
                  @b, pos, sizeof (dc_pMid), move_err);
            move_err := e_ok; (* ignore error *)
            pos      := pos + sizeof (dc_pMid);
            (* *)
            g10mv ('VBD20 ',  10,    
                  sizeof (dc_pIOMid), sizeof (b),
                  @dc_pIOMid, 1,
                  @b, pos, sizeof (dc_pIOMid), move_err);
            move_err := e_ok; (* ignore error *)
            pos      := pos + sizeof (dc_pIOMid);
            (* *)
&           ifdef AWE_USAGE
            g10mv ('VBD20 ',  11,    
                  sizeof (dc_pLastMappedCBlock), sizeof (b),
                  @dc_pLastMappedCBlock, 1,
                  @b, pos, sizeof (dc_pLastMappedCBlock), move_err);
            move_err := e_ok; (* ignore error *)
            pos      := pos + sizeof (dc_pLastMappedCBlock);
            (* *)
            g10mv ('VBD20 ',  12,    
                  sizeof (dc_pUnMapFreeList), sizeof (b),
                  @dc_pUnMapFreeList, 1,
                  @b, pos, sizeof (dc_pUnMapFreeList), move_err);
            move_err := e_ok; (* ignore error *)
            pos      := pos + sizeof (dc_pUnMapFreeList);
            (* *)
&           endif
            (* *)
            g10mv ('VBD20 ',  13,    
                  sizeof (dc_pFreeList), sizeof (b),
                  @dc_pFreeList, 1,
                  @b, pos, sizeof (dc_pFreeList), move_err);
            move_err := e_ok; (* ignore error *)
            pos      := pos + sizeof (dc_pFreeList);
            (* *)
            g10mv ('VBD20 ',  14,    
                  sizeof (dc_pFrameLessCBlocks), sizeof (b),
                  @dc_pFrameLessCBlocks, 1,
                  @b, pos, sizeof (dc_pFrameLessCBlocks), move_err);
            move_err := e_ok; (* ignore error *)
            pos      := pos + sizeof (dc_pFrameLessCBlocks);
            (* *)
            s20ch4 (dc_FreeCount, b, pos);
            pos := pos + 4;
            s20ch4 (dc_UnMapFreeCount, b, pos);
            pos := pos + 4;
            s20ch4 (dc_FrameLessCBlockCnt, b, pos);
            pos := pos + 4;
            s20ch4 (dc_HeadListSize, b, pos);
            pos := pos + 4;
            s20ch4 (dc_SVPElems, b, pos);
            pos := pos + 4;
            s20ch4 (dc_IOElems, b, pos);
            pos := pos + 4;
            s20ch4 (dc_NumSplitLocks, b, pos);
            pos := pos + 4;
            s20ch4 (dc_OldOccupants, b, pos);
            pos := pos + 4;
            s20ch4 (dc_IOAreaSize, b, pos);
            pos := pos + 4;
            s20ch4 (dc_RecAreaSize, b, pos);
            pos := pos + 4;
            s20ch4 (dc_IOAreaFlushCnt, b, pos);
            pos := pos + 4;
            s20ch4 (dc_LruTailFlushCnt, b, pos);
            pos := pos + 4;
            s20ch4 (dc_UndoFilePageCnt, b, pos);
            pos := pos + 4;
            s20ch4 (dc_OmsDataPageCnt, b, pos);
            pos := pos + 4;
            s20ch4 (dc_SqlDataPageCnt, b, pos);
            pos := pos + 4;
            (* *)
            g10mv ('VBD20 ',  15,    
                  sizeof (dc_pIOQueueHead1), sizeof (b),
                  @dc_pIOQueueHead1, 1,
                  @b, pos, sizeof (dc_pIOQueueHead1), move_err);
            move_err := e_ok; (* ignore error *)
            pos      := pos + sizeof (dc_pIOQueueHead1);
            (* *)
            g10mv ('VBD20 ',  16,    
                  sizeof (dc_pIOQueueHead2), sizeof (b),
                  @dc_pIOQueueHead2, 1,
                  @b, pos, sizeof (dc_pIOQueueHead2), move_err);
            move_err := e_ok; (* ignore error *)
            pos      := pos + sizeof (dc_pIOQueueHead2);
            (* *)
            g10mv ('VBD20 ',  17,    
                  sizeof (dc_pIOQueueTail1), sizeof (b),
                  @dc_pIOQueueTail1, 1,
                  @b, pos, sizeof (dc_pIOQueueTail1), move_err);
            move_err := e_ok; (* ignore error *)
            pos      := pos + sizeof (dc_pIOQueueTail1);
            (* *)
            g10mv ('VBD20 ',  18,    
                  sizeof (dc_pIOQueueTail2), sizeof (b),
                  @dc_pIOQueueTail2, 1,
                  @b, pos, sizeof (dc_pIOQueueTail2), move_err);
            move_err := e_ok; (* ignore error *)
            pos      := pos + sizeof (dc_pIOQueueTail2);
            (* *)
            p.pid_queue_addr := dc_pOverflowTaskQueue;
            g10mv ('VBD20 ',  19,    
                  sizeof (p.cblockaddr), sizeof (b),
                  @p.cblockaddr, 1,
                  @b, pos, sizeof (p.cblockaddr), move_err);
            move_err := e_ok; (* ignore error *)
            pos      := pos + sizeof (p.cblockaddr);
            (* *)
            p.pid_queue_addr := dc_pSvpEndTaskQueue;
            g10mv ('VBD20 ',  20,    
                  sizeof (p.cblockaddr), sizeof (b),
                  @p.cblockaddr, 1,
                  @b, pos, sizeof (p.cblockaddr), move_err);
            move_err := e_ok; (* ignore error *)
            pos      := pos + sizeof (p.cblockaddr);
            (* *)
            p.pid_queue_addr := dc_pTaskQueueHead;
            g10mv ('VBD20 ',  21,    
                  sizeof (p.cblockaddr), sizeof (b),
                  @p.cblockaddr, 1,
                  @b, pos, sizeof (p.cblockaddr), move_err);
            move_err := e_ok; (* ignore error *)
            pos      := pos + sizeof (p.cblockaddr);
            (* *)
            p.pid_queue_addr := dc_pTaskQueueFree;
            g10mv ('VBD20 ',  22,    
                  sizeof (p.cblockaddr), sizeof (b),
                  @p.cblockaddr, 1,
                  @b, pos, sizeof (p.cblockaddr), move_err);
            move_err := e_ok; (* ignore error *)
            pos      := pos + sizeof (p.cblockaddr);
            (* *)
            b [pos]     := chr (ord (dc_SegmentActive));
            b [pos + 1] := chr (ord (dc_SVPActive));
            b [pos + 2] := chr (ord (dc_PreventSplit));
            b [pos + 3] := chr (ord (dc_IOSwitch));
            pos         := pos + 4;
            IF  host_error = vf_ok
            THEN
                g01new_dump_page (hostfile, b, dump_pno, pos, host_error, errtext);
            (*ENDIF*) 
            END;
        (* *)
        (* --- HASHLIST --- *)
        (* *)
        (*ENDIF*) 
        IF  (dc_SegmentSize > 0)
        THEN
            BEGIN
            IF  dc_pHeadList <> NIL
            THEN
                BEGIN
                dump_mark := mark1_b20hdlis;
                g10mv ('VBD20 ',  23,    
                      sizeof (dump_mark), sizeof (b),
                      @dump_mark, 1,
                      @b, pos, sizeof (dump_mark), move_err);
                move_err := e_ok; (* ignore error *)
                pos           := pos + sizeof (dump_mark);
                h_int.mapInt_sp00 := code1_b20hdlis;
                b[pos]        := h_int.mapC2_sp00[1];
                b[pos + 1]    := h_int.mapC2_sp00[2];
                pos           := pos + 2;
                s20ch4 (dc_HeadListSize, b, pos);
                pos           := pos + 4;
                i             := 0;
                hd_elem_count := 0;
                WHILE i < dc_HeadListSize DO
                    BEGIN
                    IF  dc_pHeadList^ [i].he_cb <> NIL
                    THEN
                        hd_elem_count := succ (hd_elem_count);
                    (*ENDIF*) 
                    i := i + 1;
                    END;
                (*ENDWHILE*) 
                s20ch4 (hd_elem_count, b, pos);
                pos           := pos + 4;
                elems_pos     := pos;
                pos           := pos + 3;
                elems_on_page := 0;
                i             := 0;
                WHILE (host_error = vf_ok) AND (i < dc_HeadListSize) DO
                    IF  dc_pHeadList^ [i].he_cb <> NIL
                    THEN
                        IF  pos + hd_elem_len <= sizeof (b)
                        THEN
                            WITH dc_pHeadList^ [i] DO
                                BEGIN
                                elems_on_page := succ (elems_on_page);
                                s20ch4 (i, b, pos);
                                pos := pos + 4;
                                g10mv ('VBD20 ',  24,    
                                      sizeof (he_cb), sizeof (b),
                                      @he_cb, 1,
                                      @b, pos, sizeof (he_cb), move_err);
                                move_err := e_ok; (* ignore error *)
                                pos      := pos + sizeof (he_cb);
                                s20ch4 (he_old_occ_cnt, b, pos);
                                pos := pos + 4;
&                               ifdef BIT64
                                s20ch4 (he_fill, b, pos);
                                pos := pos + 4;
&                               endif
                                i := i + 1;
                                END
                            (*ENDWITH*) 
                        ELSE
                            BEGIN
                            h_int.mapInt_sp00 := elems_on_page;
                            b [elems_pos]     := h_int.mapC2_sp00 [1];
                            b [elems_pos + 1] := h_int.mapC2_sp00 [2];
                            b [elems_pos + 2] := chr (ord (false));
                            g01new_dump_page (hostfile, b, dump_pno, pos, host_error, errtext);
                            IF  host_error = vf_ok
                            THEN
                                BEGIN
                                dump_mark := mark2_b20hdlfo;
                                g10mv ('VBD20 ',  25,    
                                      sizeof (dump_mark), sizeof (b),
                                      @dump_mark, 1,
                                      @b, pos, sizeof (dump_mark), move_err);
                                move_err := e_ok; (* ignore error *)
                                pos := pos + sizeof (dump_mark);
                                h_int.mapInt_sp00 := code2_b20hdlfo;
                                b[pos]     := h_int.mapC2_sp00[1];
                                b[pos + 1] := h_int.mapC2_sp00[2];
                                pos        := pos + 2;
                                elems_pos  := pos;
                                pos        := pos + 3;
                                elems_on_page := 0
                                END
                            (*ENDIF*) 
                            END
                        (*ENDIF*) 
                    ELSE
                        i := i + 1;
                    (*ENDIF*) 
                (*ENDWHILE*) 
                IF  (host_error = vf_ok)
                THEN
                    BEGIN
                    h_int.mapInt_sp00 := elems_on_page;
                    b [elems_pos]     := h_int.mapC2_sp00 [1];
                    b [elems_pos + 1] := h_int.mapC2_sp00 [2];
                    b [elems_pos + 2] := chr (ord (true));
                    g01new_dump_page (hostfile, b, dump_pno, pos, host_error, errtext)
                    END
                (*ENDIF*) 
                END;
            (* *)
            (* --- CONTROLBLOCKS --- *)
            (* *)
            (*ENDIF*) 
            IF  host_error = vf_ok
            THEN
                BEGIN
                dump_mark := mark3_b20cbloc;
                g10mv ('VBD20 ',  26,    
                      sizeof (dump_mark), sizeof (b),
                      @dump_mark, 1,
                      @b, pos, sizeof (dump_mark), move_err);
                move_err := e_ok; (* ignore error *)
                pos := pos + sizeof (dump_mark);
                h_int.mapInt_sp00 := code3_b20cbloc;
                b[pos]     := h_int.mapC2_sp00[1];
                b[pos + 1] := h_int.mapC2_sp00[2];
                pos := pos + 2;
                END;
            (*ENDIF*) 
            elems_pos     := pos;
            pos           := pos + 3;
            elems_on_page := 0;
            act_block     := dc_pFirstCBlock;
            WHILE (host_error = vf_ok) AND (act_block <> NIL) DO
                BEGIN
                IF  pos + cb_len <= sizeof (b)
                THEN
                    BEGIN
                    WITH act_block^ DO
                        BEGIN
                        elems_on_page := succ (elems_on_page);
                        (* *)
                        g10mv ('VBD20 ',  27,    
                              sizeof (act_block), sizeof (b),
                              @act_block, 1,
                              @b, pos, sizeof (act_block), move_err);
                        move_err := e_ok; (* ignore error *)
                        pos      := pos + sizeof (act_block);
                        (* *)
                        s20ch4 (dcb_occupant, b, pos);
                        pos := pos + 4;
                        (* *)
                        p.nodeaddr := dcb_pFrame_bd02;
                        g10mv ('VBD20 ',  28,    
                              sizeof (p.cblockaddr), sizeof (b),
                              @p.cblockaddr, 1,
                              @b, pos, sizeof (p.cblockaddr), move_err);
                        move_err := e_ok; (* ignore error *)
                        pos      := pos + sizeof (p.cblockaddr);
                        (* *)
                        IF  dcb_pFrame_bd02 <> NIL
                        THEN
                            BEGIN
                            s20ch4 (dcb_pFrame_bd02^.nd_id, b, pos);
                            pos := pos + 4;
                            s20ch4 (dcb_pFrame_bd02^.nd_root, b, pos);
                            END
                        ELSE
                            BEGIN
                            s20ch4 (-1, b, pos);
                            pos := pos + 4;
                            s20ch4 (NIL_PAGE_NO_GG00, b, pos);
                            END;
                        (*ENDIF*) 
                        pos := pos + 4;
                        (* *)
                        s20ch4 (dcb_LastOwner_bd02, b, pos);
                        pos := pos + 4;
                        (* *)
                        s20ch4 (dcb_OldOccupant_bd02, b, pos);
                        pos := pos + 4;
                        (* *)
                        g10mv ('VBD20 ',  29,    
                              sizeof (dcb_FixedNext_bd02), sizeof (b),
                              @dcb_FixedNext_bd02, 1,
                              @b, pos, sizeof (dcb_FixedNext_bd02), move_err);
                        move_err := e_ok; (* ignore error *)
                        pos      := pos + sizeof (dcb_FixedNext_bd02);
                        (* *)
                        g10mv ('VBD20 ',  30,    
                              sizeof (dcb_VarNext_bd02), sizeof (b),
                              @dcb_VarNext_bd02, 1,
                              @b, pos, sizeof (dcb_VarNext_bd02), move_err);
                        move_err := e_ok; (* ignore error *)
                        pos      := pos + sizeof (dcb_VarNext_bd02);
                        (* *)
                        g10mv ('VBD20 ',  31,    
                              sizeof (dcb_lru_next), sizeof (b),
                              @dcb_lru_next, 1,
                              @b, pos, sizeof (dcb_lru_next), move_err);
                        move_err := e_ok; (* ignore error *)
                        pos      := pos + sizeof (dcb_lru_next);
                        (* *)
                        g10mv ('VBD20 ',  32,    
                              sizeof (dcb_lru_prev), sizeof (b),
                              @dcb_lru_prev, 1,
                              @b, pos, sizeof (dcb_lru_prev), move_err);
                        move_err := e_ok; (* ignore error *)
                        pos      := pos + sizeof (dcb_lru_prev);
                        (* *)
                        p.pid_queue_addr := dcb_queue_occ;
                        g10mv ('VBD20 ',  33,    
                              sizeof (p.cblockaddr), sizeof (b),
                              @p.cblockaddr, 1,
                              @b, pos, sizeof (p.cblockaddr), move_err);
                        move_err := e_ok; (* ignore error *)
                        pos      := pos + sizeof (p.cblockaddr);
                        (* *)
                        p.pid_queue_addr := dcb_queue_old_occ;
                        g10mv ('VBD20 ',  34,    
                              sizeof (p.cblockaddr), sizeof (b),
                              @p.cblockaddr, 1,
                              @b, pos, sizeof (p.cblockaddr), move_err);
                        move_err := e_ok; (* ignore error *)
                        pos      := pos + sizeof (p.cblockaddr);
                        (* *)
                        p.pid_queue_addr := dcb_lock_req_head;
                        g10mv ('VBD20 ',  35,    
                              sizeof (p.cblockaddr), sizeof (b),
                              @p.cblockaddr, 1,
                              @b, pos, sizeof (p.cblockaddr), move_err);
                        move_err := e_ok; (* ignore error *)
                        pos      := pos + sizeof (p.cblockaddr);
                        (* *)
                        p.pid_queue_addr := dcb_lock_req_tail;
                        g10mv ('VBD20 ',  36,    
                              sizeof (p.cblockaddr), sizeof (b),
                              @p.cblockaddr, 1,
                              @b, pos, sizeof (p.cblockaddr), move_err);
                        move_err := e_ok; (* ignore error *)
                        pos      := pos + sizeof (p.cblockaddr);
                        (* *)
                        g10mv ('VBD20 ',  37,    
                              sizeof (dcb_io_prev), sizeof (b),
                              @dcb_io_prev, 1,
                              @b, pos, sizeof (dcb_io_prev), move_err);
                        move_err := e_ok; (* ignore error *)
                        pos      := pos + sizeof (dcb_io_prev);
                        (* *)
                        g10mv ('VBD20 ',  38,    
                              sizeof (dcb_io_next), sizeof (b),
                              @dcb_io_next, 1,
                              @b, pos, sizeof (dcb_io_next), move_err);
                        move_err := e_ok; (* ignore error *)
                        pos      := pos + sizeof (dcb_io_next);
                        (* *)
                        h_int.mapInt_sp00 := dcb_UsageCnt_bd02;
                        b [pos]       := h_int.mapC2_sp00 [1];
                        b [pos + 1]   := h_int.mapC2_sp00 [2];
                        pos           := pos + 2;
                        (* *)
                        b [pos]       := chr (ord (dcb_ChangedState_bd02));
                        b [pos + 1]   := chr (ord (dcb_io_state));
                        pos           := pos + 2;
                        (* *)
                        b [pos]       := chr (ord (dcb_lru_rechain));
                        b [pos + 1]   := chr (ord (dcb_tfn));
                        pos           := pos + 2;
                        (* *)
                        b [pos]       := chr (ord (dcb_IsSourceOfACopy_bd02));
                        b [pos + 1]   := chr (ord (dcb_ExclusiveLocked_bd02));
                        pos           := pos + 2;
                        (* *)
                        b [pos]       := chr (dcb_OldRecMode_bd02);
                        pos           := pos + 1;
                        (* *)
                        b [pos]       := chr (dcb_dw_io_area);
                        pos           := pos + 1;
                        (* *)
                        b [pos]       := chr (dcb_copy_no);
                        pos           := pos + 1;
                        (* *)
                        b [pos]       := chr (dcb_RecMode_bd02);
                        pos           := pos + 1;
                        (* *)
&                       ifdef AWE_USAGE
                        s20ch4 (dcb_AWE_BlockNo_bd02, b, pos);
                        pos           := pos + 4;
&                       endif
                        (* *)
                        act_block     := act_block^.dcb_FixedNext_bd02;
                        END
                    (*ENDWITH*) 
                    END
                ELSE
                    BEGIN
                    h_int.mapInt_sp00 := elems_on_page;
                    b [elems_pos]     := h_int.mapC2_sp00 [1];
                    b [elems_pos + 1] := h_int.mapC2_sp00 [2];
                    b [elems_pos + 2] := chr (ord (false));
                    g01new_dump_page (hostfile, b, dump_pno, pos,
                          host_error, errtext);
                    IF  host_error = vf_ok
                    THEN
                        BEGIN
                        dump_mark := mark4_b20cblfo;
                        g10mv ('VBD20 ',  39,    
                              sizeof (dump_mark), sizeof (b),
                              @dump_mark, 1,
                              @b, pos, sizeof (dump_mark), move_err);
                        move_err := e_ok; (* ignore error *)
                        pos              := pos + sizeof (dump_mark);
                        h_int.mapInt_sp00:= code4_b20cblfo;
                        b[pos]           := h_int.mapC2_sp00[1];
                        b[pos + 1]       := h_int.mapC2_sp00[2];
                        pos              := pos + 2;
                        elems_pos        := pos;
                        pos              := pos + 3;
                        elems_on_page    := 0
                        END
                    (*ENDIF*) 
                    END
                (*ENDIF*) 
                END;
            (*ENDWHILE*) 
            IF  (host_error = vf_ok)
            THEN
                BEGIN
                h_int.mapInt_sp00 := elems_on_page;
                b [elems_pos]     := h_int.mapC2_sp00 [1];
                b [elems_pos + 1] := h_int.mapC2_sp00 [2];
                b [elems_pos + 2] := chr (ord (true));
                g01new_dump_page (hostfile, b, dump_pno, pos,
                      host_error, errtext)
                END;
            (* *)
            (* --- TASK QUEUE ELEMS --- *)
            (* *)
            (*ENDIF*) 
            IF  host_error = vf_ok
            THEN
                BEGIN
                dump_mark := mark6_b20quele;
                g10mv ('VBD20 ',  40,    
                      sizeof (dump_mark), sizeof (b),
                      @dump_mark, 1,
                      @b, pos, sizeof (dump_mark), move_err);
                move_err := e_ok; (* ignore error *)
                pos           := pos + sizeof (dump_mark);
                h_int.mapInt_sp00 := code6_b20quele;
                b[pos]        := h_int.mapC2_sp00[1];
                b[pos + 1]    := h_int.mapC2_sp00[2];
                pos           := pos + 2;
                END;
            (*ENDIF*) 
            elems_pos      := pos;
            pos            := pos + 3;
            elems_on_page  := 0;
            i              := 0;
            act_pid_queue  := dc_pTaskQueueHead;
            queue_elem_len := sizeof (tbd02_TaskQueueItem) +
                  sizeof (tbd02_pTaskQueueItem);
            WHILE (host_error = vf_ok) AND (act_pid_queue <> NIL) DO
                BEGIN
                IF  pos + queue_elem_len <= sizeof (b)
                THEN
                    BEGIN
                    WITH act_pid_queue^ DO
                        BEGIN
                        IF  tqiTaskId_bd02 <> 0
                        THEN
                            BEGIN
                            elems_on_page := succ (elems_on_page);
                            p.pid_queue_addr := act_pid_queue;
                            g10mv ('VBD20 ',  41,    
                                  sizeof (p.cblockaddr), sizeof (b),
                                  @p.cblockaddr, 1,
                                  @b, pos, sizeof (p.cblockaddr), move_err);
                            move_err := e_ok; (* ignore error *)
                            pos := pos + sizeof (p.cblockaddr);
                            p.pid_queue_addr := tqiFixedNext_bd02;
                            g10mv ('VBD20 ',  42,    
                                  sizeof (p.cblockaddr), sizeof (b),
                                  @p.cblockaddr, 1,
                                  @b, pos, sizeof (p.cblockaddr), move_err);
                            move_err := e_ok; (* ignore error *)
                            pos := pos + sizeof (p.cblockaddr);
                            p.pid_queue_addr := tqiVarNext_bd02;
                            g10mv ('VBD20 ',  43,    
                                  sizeof (p.cblockaddr), sizeof (b),
                                  @p.cblockaddr, 1,
                                  @b, pos, sizeof (p.cblockaddr), move_err);
                            move_err := e_ok; (* ignore error *)
                            pos := pos + sizeof (p.cblockaddr);
                            s20ch4 (tqiTaskId_bd02, b, pos);
                            pos           := pos + 4;
                            b [pos]       := chr (tqiReason_bd02);
                            pos           := pos + 1;
                            b [pos]       := chr (tqiFiller1_bd02);
                            pos           := pos + 1;
                            h_int.mapInt_sp00 := tqiFiller2_bd02;
                            b [pos]       := h_int.mapC2_sp00 [1];
                            b [pos + 1]   := h_int.mapC2_sp00 [2];
                            pos           := pos + 2;
                            END;
                        (*ENDIF*) 
                        act_pid_queue := act_pid_queue^.tqiFixedNext_bd02
                        END
                    (*ENDWITH*) 
                    END
                ELSE
                    BEGIN
                    h_int.mapInt_sp00 := elems_on_page;
                    b [elems_pos]     := h_int.mapC2_sp00 [1];
                    b [elems_pos + 1] := h_int.mapC2_sp00 [2];
                    b [elems_pos + 2] := chr (ord (false));
                    g01new_dump_page (hostfile, b, dump_pno, pos,
                          host_error, errtext);
                    IF  host_error = vf_ok
                    THEN
                        BEGIN
                        dump_mark := mark7_b20qufol;
                        g10mv ('VBD20 ',  44,    
                              sizeof (dump_mark), sizeof (b),
                              @dump_mark, 1,
                              @b, pos, sizeof (dump_mark), move_err);
                        move_err      := e_ok; (* ignore error *)
                        pos           := pos + sizeof (dump_mark);
                        h_int.mapInt_sp00 := code7_b20qufol;
                        b[pos]        := h_int.mapC2_sp00[1];
                        b[pos + 1]    := h_int.mapC2_sp00[2];
                        pos           := pos + 2;
                        elems_pos     := pos;
                        pos           := pos + 3;
                        elems_on_page := 0
                        END
                    (*ENDIF*) 
                    END
                (*ENDIF*) 
                END;
            (*ENDWHILE*) 
            IF  (host_error = vf_ok)
            THEN
                BEGIN
                h_int.mapInt_sp00 := elems_on_page;
                b [elems_pos]     := h_int.mapC2_sp00 [1];
                b [elems_pos + 1] := h_int.mapC2_sp00 [2];
                b [elems_pos + 2] := chr (ord (true));
                g01new_dump_page (hostfile, b, dump_pno, pos, host_error, errtext)
                END
            (*ENDIF*) 
            END
        (*ENDIF*) 
        END;
    (* *)
    (* --- FILL REMAINING  DUMPPAGE --- *)
    (* *)
    (*ENDIF*) 
    IF  host_error = vf_ok
    THEN
        g01new_dump_page (hostfile, b, dump_pno, pos, host_error, errtext)
    (*ENDIF*) 
    END
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      bd20DumpDataCacheFrames (
            VAR hostfile   : tgg00_VfFileref;
            VAR b          : tsp00_Page;
            VAR dump_pno   : tsp00_Int4;
            VAR pos        : integer;
            VAR host_error : tsp00_VfReturn;
            VAR errtext    : tsp00_ErrText);
 
VAR
      RegOffset : tsp00_Int4;
 
BEGIN
RegOffset := 0;
WHILE (host_error = vf_ok) AND (RegOffset <= bd20RegionCount - 1) DO
    BEGIN
    bd20_DumpDataCacheFrames (bd20DataCacheList [RegOffset],
          hostfile, b, dump_pno, pos, host_error, errtext);
    RegOffset := succ (RegOffset)
    END;
(*ENDWHILE*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      bd20_DumpDataCacheFrames (
            VAR DataCache   : t_datacache;
            VAR HostFile    : tgg00_VfFileref;
            VAR DumpPage    : tsp00_Page;
            VAR DumpPageNo  : tsp00_Int4;
            VAR PagePos     : integer;
            VAR HostError   : tsp00_VfReturn;
            VAR ErrorText   : tsp00_ErrText);
 
VAR
      AuxError  : tgg00_BasisError;
      pDumpPage : tsp00_VfBufaddr;
      pCBlock   : tbd02_pDataCBlock;
 
BEGIN
AuxError   := e_ok;
pDumpPage  := @DumpPage;
WITH DataCache DO
    BEGIN
    IF  (dc_SegmentSize > 0)
    THEN
        BEGIN
        (* *)
        (* --- FILL PREVIOUS DUMPPAGE --- *)
        (* *)
        IF  HostError = vf_ok
        THEN
            g01new_dump_page (HostFile, DumpPage, DumpPageNo, PagePos, HostError, ErrorText);
        (*ENDIF*) 
        IF  HostError = vf_ok
        THEN
            BEGIN
            PagePos := 1;
            pCBlock := dc_pFirstCBlock;
            WHILE (HostError = vf_ok) AND (pCBlock <> NIL) DO
                BEGIN
                WITH pCBlock^ DO
                    IF  (dcb_pFrame_bd02 <> NIL) AND (dcb_occupant <> NIL_PAGE_NO_GG00)
                    THEN
                        BEGIN
                        g10mv ('VBD20 ',  45,    
                              sizeof (dcb_pFrame_bd02^), sizeof (DumpPage),
                              @dcb_pFrame_bd02^, 1,
                              @DumpPage, 1, sizeof (dcb_pFrame_bd02^), AuxError);
                        AuxError := e_ok; (* ignore error *)
                        vfwrite (HostFile.no, pDumpPage, HostError, ErrorText)
                        END;
                    (*ENDIF*) 
                (*ENDWITH*) 
                vtracewriter_alive;
                pCBlock := pCBlock^.dcb_FixedNext_bd02
                END
            (*ENDWHILE*) 
            END;
        (* *)
        (* --- FILL REMAINING  DUMPPAGE --- *)
        (* *)
        (*ENDIF*) 
        IF  HostError = vf_ok
        THEN
            g01new_dump_page (HostFile, DumpPage, DumpPageNo, PagePos, HostError, ErrorText)
        (*ENDIF*) 
        END
    (*ENDIF*) 
    END
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
FUNCTION
      bd20ExclusiveLocks (TaskId : tsp00_TaskId) : boolean;
 
VAR
      bLockFound : boolean;
      RegOffset  : tsp00_Int4;
 
BEGIN
RegOffset  := 0;
bLockFound := false;
WHILE (RegOffset <= bd20RegionCount - 1) AND NOT bLockFound DO
    BEGIN
    vbegexcl (TaskId, g08data1 + RegOffset);
    WITH bd20DataCacheList [RegOffset] DO
        BEGIN
        bLockFound := dc_NumSplitLocks > 0;
        (* PTS 1106254 TS 2000-04-04 *)
        IF  (dc_NumSplitLocks < 0) OR (dc_NumSplitLocks > dc_SegmentSize)
        THEN
            g01abort (csp3_bd_msg, csp3_n_datacache, 'Num split locks wrong   ',
                  dc_NumSplitLocks);
        (* PTS 1106254 *)
        (*ENDIF*) 
        END;
    (*ENDWITH*) 
    vendexcl (TaskId, g08data1 + RegOffset);
    RegOffset := succ (RegOffset)
    END;
(*ENDWHILE*) 
bd20ExclusiveLocks := bLockFound
END;
 
(*------------------------------*) 
 
PROCEDURE
      bd20LockPageForFree (
            TaskId               : tsp00_TaskId;
            VAR TrError          : tgg00_BasisError;
            VAR FileId           : tgg00_FileId;
            PageNo               : tsp00_PageNo;
            recMode              : tbd02_RecoveryMode;
            FirstCall            : boolean;
            VAR PageLockedToFree : boolean;
            VAR PageState        : tbd02_CachePageState;
            VAR nptr             : tbd_nodeptr;
            VAR cbptr            : tbd02_pDataCBlock);
 
VAR
      RegOffset     : integer;
      old_occs      : integer;
      ChangedCnt    : tsp00_Int4;
      HashIndex     : tsp00_Int4;
      OldHashIndex  : tsp00_Int4;
      pred          : tbd02_pDataCBlock;
      there         : tbd02_pDataCBlock;
      pSourceCBlock : tbd02_pDataCBlock;
 
BEGIN
nptr        := NIL;
cbptr       := NIL;
ChangedCnt  := 0;
RegOffset   := PageNo MOD bd20RegionCount;
HashIndex   := PageNo MOD bd20DataCacheList [RegOffset].dc_HeadListSize;
(* *)
vbegexcl (TaskId, g08data1 + RegOffset);
(* *)
WITH bd20DataCacheList [RegOffset], PageState DO
    BEGIN
    IF  NOT dc_SegmentActive
    THEN
        TrError := e_shutdown
    ELSE
        BEGIN
        bd20c_search_in_chain_incl_copy (bd20DataCacheList [RegOffset],
              HashIndex, PageNo, recMode, there, pred, cpsFound_bd02, pSourceCBlock);
        IF  cpsFound_bd02
        THEN
            BEGIN
            IF  pSourceCBlock <> NIL
            THEN
                BEGIN
                there := pSourceCBlock;
                cpsWaitForWrite_bd02 := (NOT cpsIoDone_bd02) AND
                      ((there^.dcb_UsageCnt_bd02 <> 0) OR (there^.dcb_io_state <> iosNone_ebd02));
                END
            ELSE
                cpsWaitForWrite_bd02 :=
                      (there^.dcb_io_state = iosServerIO_ebd02)
                      OR
                      ((there^.dcb_io_state = iosUserIO_ebd02) AND FirstCall);
            (*ENDIF*) 
            WITH there^ DO
                IF  cpsWaitForWrite_bd02
                THEN
                    bd20_InsertOccupant (TaskId, FileId, bd20DataCacheList [RegOffset], there)
                ELSE
                    BEGIN
                    cpsDirty_bd02 :=  (NOT cpsIoDone_bd02) AND
                          (dcb_ChangedState_bd02 = cstSvpRelevant_ebd02);
                    IF  cpsDirty_bd02
                    THEN
                        BEGIN
&                       ifdef AWE_USAGE
                        IF  dcb_pFrame_bd02 = NIL
                        THEN
                            bd20_ReMapFrame (TaskId, TrError, FileId, bd20DataCacheList [RegOffset], there);
&                       endif
                        (*ENDIF*) 
                        IF  TrError = e_ok (* caused by AWE *)
                        THEN
                            BEGIN
                            dcb_io_state := iosUserIO_ebd02;
                            nptr         := dcb_pFrame_bd02;
                            cbptr        := there
                            END
                        (*ENDIF*) 
                        END
                    ELSE
                        BEGIN
                        IF  pSourceCBlock <> NIL
                        THEN
                            BEGIN
                            IF  dcb_queue_occ <> NIL
                            THEN
                                bd20_ResumeOccupant (bd20DataCacheList [RegOffset], MSG_LOCK_FREE, there);
                            (*ENDIF*) 
                            bd20_FreeCBlock (bd20DataCacheList [RegOffset], HashIndex, pred, there);
                            cpsIoDone_bd02 := false
                            END
                        ELSE
                            BEGIN
                            PageLockedToFree    := true;
                            there^.dcb_io_state := iosUserIO_ebd02;
                            nptr                := dcb_pFrame_bd02;
                            cbptr               := there;
                            END
                        (*ENDIF*) 
                        END
                    (*ENDIF*) 
                    END
                (*ENDIF*) 
            (*ENDWITH*) 
            END
        ELSE (* NOT bFound *)
            BEGIN
            IF  dc_pHeadList^ [HashIndex].he_old_occ_cnt > 0
            THEN
                BEGIN
                old_occs := dc_OldOccupants;
                there    := dc_pFirstLRU;
                WHILE (NOT cpsWaitForWrite_bd02) AND (there <> NIL) AND (old_occs > 0) DO
                    BEGIN
                    WITH there^ DO
                        BEGIN
                        IF  (dcb_OldOccupant_bd02 = PageNo) AND (dcb_OldRecMode_bd02 = recMode)
                        THEN
                            BEGIN
                            cpsWaitForWrite_bd02 := true;
                            bd20_InsertOldOccupant( TaskId, FileId, bd20DataCacheList [RegOffset], there )
                            END
                        ELSE
                            BEGIN
                            IF  dcb_OldOccupant_bd02 <> NIL_PAGE_NO_GG00
                            THEN
                                old_occs := old_occs - 1;
                            (*ENDIF*) 
                            there := there^.dcb_lru_next;
                            END
                        (*ENDIF*) 
                        END
                    (*ENDWITH*) 
                    END
                (*ENDWHILE*) 
                END;
            (*ENDIF*) 
            IF  NOT cpsWaitForWrite_bd02
            THEN
                BEGIN
                bd20_GetFrameFromLRU (TaskId, TrError, FileId, bd20DataCacheList [RegOffset],
                      NOT IGNORE_DIRTY_PAGES_BD20, there, ChangedCnt);
                IF  TrError = e_ok
                THEN
                    BEGIN
                    WITH there^ DO
                        BEGIN
                        cpsDirty_bd02 := dcb_ChangedState_bd02 = cstChanged_ebd02;
                        dcb_io_state  := iosUserIO_ebd02;
                        IF  cpsDirty_bd02
                        THEN
                            BEGIN
                            bd20unset_changed (bd20DataCacheList [RegOffset], there);
                            dcb_OldOccupant_bd02 := dcb_occupant;
                            dcb_OldRecMode_bd02  := dcb_RecMode_bd02;
                            OldHashIndex         := dcb_OldOccupant_bd02 MOD dc_HeadListSize;
                            WITH  dc_pHeadList^ [OldHashIndex] DO
                                BEGIN
                                he_old_occ_cnt   := succ (he_old_occ_cnt);
                                dc_OldOccupants := succ (dc_OldOccupants)
                                END
                            (*ENDWITH*) 
                            END;
                        (*ENDIF*) 
                        dcb_occupant     := PageNo;
                        dcb_RecMode_bd02 := recMode;
                        dcb_tfn          := FileId.fileTfn_gg00;
                        bd20add_to_chain (bd20DataCacheList [RegOffset], HashIndex, there);
                        cbptr := there;
                        nptr  := dcb_pFrame_bd02;
                        END
                    (*ENDWITH*) 
                    END
                (*ENDIF*) 
                END
            (*ENDIF*) 
            END;
        (*ENDIF*) 
        IF  bd20DataCacheList [RegOffset].dc_MemoryProtection
        THEN
            BEGIN
            IF  cpsDirty_bd02 AND (TrError = e_ok)
            THEN
                bd20_ReadWriteAccessToFrame (bd20DataCacheList [RegOffset], nptr);
            (*ENDIF*) 
            END;
        (*ENDIF*) 
        IF  g01glob.datacachecheck
&           ifdef TEST_AWE
            OR
            (dc_UnMapAreaSize > 0)
&           endif
        THEN
            bd20_CheckLRUList (bd20DataCacheList [RegOffset])
        (*ENDIF*) 
        END
    (*ENDIF*) 
    END;
(*ENDWITH*) 
(* *)
vendexcl (TaskId, g08data1 + RegOffset);
(* *)
END;
 
(*------------------------------*) 
 
PROCEDURE
      bd20FlushDataCache (VAR Trans : tgg00_TransContext);
 
VAR
&     ifdef AWE_USAGE
      bUseAuxBuffer : boolean;
&     endif
      RegOffset     : tsp00_Int4;
      pCBlock       : tbd02_pDataCBlock;
 
BEGIN
RegOffset          := 0;
Trans.trError_gg00 := e_ok;
WHILE (Trans.trError_gg00 = e_ok) AND (RegOffset <= bd20RegionCount - 1) DO
    BEGIN
    vbegexcl (Trans.trTaskId_gg00, g08data1 + RegOffset);
    WITH Trans, bd20DataCacheList [RegOffset] DO
        BEGIN
        pCBlock := dc_pFirstCBlock;
        WHILE (trError_gg00 = e_ok) AND (pCBlock <> NIL) DO
            WITH pCBlock^  DO
                BEGIN
                IF  (dcb_occupant          <> NIL_PAGE_NO_GG00) AND
                    (dcb_ChangedState_bd02 <> cstNone_ebd02   ) AND
                    (dcb_RecMode_bd02      <> rmTemp_ebd02    )
                THEN
                    BEGIN
                    IF  (dcb_IsSourceOfACopy_bd02) OR (dcb_copy_no <> 0)
                    THEN
                        g01abort (csp3_bd_msg, csp3_n_datacache,
                              'B20FLUSH: copies exist! ', dcb_occupant);
                    (*ENDIF*) 
                    dcb_io_state := iosUserIO_ebd02;
&                   ifdef AWE_USAGE
                    bUseAuxBuffer := (dcb_pFrame_bd02 = NIL);
                    IF  bUseAuxBuffer
                    THEN
                        bd20_GetFromAWEFramePool( trTaskId_gg00, dcb_AWE_BlockNo_bd02, dcb_pFrame_bd02 );
&                   endif
                    (* *)
                    (*ENDIF*) 
                    IF  bd20DataCacheList [RegOffset].dc_MemoryProtection
                    THEN
                        bd20_ReadWriteAccessToFrame (bd20DataCacheList [RegOffset], dcb_pFrame_bd02);
                    (*ENDIF*) 
                    vendexcl (trTaskId_gg00, g08data1 + RegOffset);
                    (* *)
                    (* *)
                    bd999WriteDataPage (Trans, dcb_pFrame_bd02);
                    (* *)
                    (* *)
                    vbegexcl (trTaskId_gg00, g08data1 + RegOffset);
                    (* *)
&                   ifdef AWE_USAGE
                    IF  bUseAuxBuffer
                    THEN
                        bd20_ReleaseToAWEFramePool( trTaskId_gg00, dcb_pFrame_bd02 );
&                   endif
                    (*ENDIF*) 
                    IF  trError_gg00 = e_ok
                    THEN
                        BEGIN
                        bd20unset_changed (bd20DataCacheList [RegOffset], pCBlock);
                        dcb_io_state := iosNone_ebd02;
                        IF  dcb_queue_occ <> NIL
                        THEN
                            bd20_ResumeOccupant (bd20DataCacheList [RegOffset], MSG_FLUSH, pCBlock);
                        (*ENDIF*) 
                        IF  dcb_IsSourceOfACopy_bd02 AND (dcb_UsageCnt_bd02 = 0)
                        THEN
                            bd20_FreeCBlock (bd20DataCacheList [RegOffset], c_nil_hash, NIL, pCBlock);
                        (*ENDIF*) 
                        IF  bd20DataCacheList [RegOffset].dc_MemoryProtection
                        THEN
                            bd20_ReadAccessToFrame (bd20DataCacheList [RegOffset], dcb_pFrame_bd02);
                        (*ENDIF*) 
                        END;
                    (*ENDIF*) 
                    END;
                (*ENDIF*) 
                pCBlock := pCBlock^.dcb_FixedNext_bd02
                END;
            (*ENDWITH*) 
        (*ENDWHILE*) 
        END;
    (*ENDWITH*) 
    vendexcl (Trans.trTaskId_gg00, g08data1 + RegOffset);
    RegOffset := succ (RegOffset)
    END
(*ENDWHILE*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      bd20ForcedIODone (
            pCBlock : tbd02_pDataCBlock;
            TaskId  : tsp00_TaskId);
 
VAR
      RegOffset : integer;
 
BEGIN
RegOffset := pCBlock^.dcb_occupant MOD bd20RegionCount;
vbegexcl (TaskId, g08data1 + RegOffset);
bd20unset_changed (bd20DataCacheList [RegOffset], pCBlock);
vendexcl (TaskId, g08data1 + RegOffset)
END;
 
(*------------------------------*) 
 
PROCEDURE
      bd20FullestDataCacheSegment (
            TaskId       : tsp00_TaskId;
            VAR CacheNo : integer);
 
VAR
      RegOffset     : integer;
      total_io_elems : tsp00_Int4;
 
BEGIN
CacheNo        := 0;
total_io_elems := 0;
FOR RegOffset := 0 TO bd20RegionCount - 1 DO
    BEGIN
    vbegexcl (TaskId, g08data1 + RegOffset);
    IF  total_io_elems < bd20DataCacheList [RegOffset].dc_IOElems
    THEN
        BEGIN
        total_io_elems := bd20DataCacheList [RegOffset].dc_IOElems;
        CacheNo        := RegOffset
        END;
    (*ENDIF*) 
    vendexcl (TaskId, g08data1 + RegOffset)
    END
(*ENDFOR*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      bd20FreePage (
            TaskId              : tsp00_TaskId;
            PageNo              : tsp00_PageNo;
            recMode             : tbd02_RecoveryMode;
            VAR TrError         : tgg00_BasisError;
            VAR ExclFileLockCnt : tsp00_Int2);
 
VAR
      bFound    : boolean;
      RegOffset : integer;
      HashIndex : tsp00_Int4;
      pred      : tbd02_pDataCBlock;
      there     : tbd02_pDataCBlock;
 
BEGIN
bFound    := false;
RegOffset := PageNo MOD bd20RegionCount;
HashIndex := PageNo MOD bd20DataCacheList [RegOffset].dc_HeadListSize;
vbegexcl (TaskId, g08data1 + RegOffset);
WITH bd20DataCacheList [RegOffset] DO
    BEGIN
    IF  NOT dc_SegmentActive
    THEN
        TrError := e_shutdown
    ELSE
        BEGIN
        bd20_SearchInChain (bd20DataCacheList [RegOffset],
              HashIndex, PageNo, recMode, there, pred, bFound);
        IF  bFound
        THEN
            WITH there^ DO
                BEGIN
                IF  dcb_queue_occ <> NIL
                THEN
                    bd20_ResumeOccupant (bd20DataCacheList [RegOffset], MSG_FREE, there);
                (*ENDIF*) 
                IF  (dcb_lock_req_head <> NIL)
                THEN
                    bd20_ResumeLockRequest (TaskId, bd20DataCacheList [RegOffset], there, RESUME_ALL_BD20);
                (*ENDIF*) 
                IF  (dc_pOverflowTaskQueue <> NIL)
                THEN
                    bd20_ResumeOverflow (bd20DataCacheList [RegOffset], 1);
                (*ENDIF*) 
                IF  dcb_ExclusiveLocked_bd02
                THEN
                    BEGIN
                    dcb_ExclusiveLocked_bd02 := false;
                    dc_NumSplitLocks         := dc_NumSplitLocks - 1;
                    ExclFileLockCnt          := ExclFileLockCnt - 1;
                    END;
                (*ENDIF*) 
                bd20_FreeCBlock (bd20DataCacheList [RegOffset], HashIndex, pred, there)
                END;
            (*ENDWITH*) 
        (*ENDIF*) 
        IF  g01glob.datacachecheck
&           ifdef TEST_AWE
            OR
            (dc_UnMapAreaSize > 0)
&           endif
        THEN
            bd20_CheckLRUList (bd20DataCacheList [RegOffset])
        (*ENDIF*) 
        END
    (*ENDIF*) 
    END;
(*ENDWITH*) 
vendexcl (TaskId, g08data1 + RegOffset);
END;
 
(*------------------------------*) 
 
PROCEDURE
      bd20_GenerateTaskQueue (
            VAR trError      : tgg00_BasisError;
            VAR head_ptr     : tbd02_pTaskQueueItem;
            VAR free_ptr     : tbd02_pTaskQueueItem;
            alloc_msg_all    : tsp00_C24;
            alloc_msg_elem   : tsp00_C24;
            VAR SumDynPool   : tsp00_Int4);
 
VAR
      ok            : boolean;
      i             : tsp00_Int4;
      task_cnt      : tsp00_Int4;
      p             : b20ptr;
      act_chain_ptr : tbd02_pTaskQueueItem;
 
BEGIN
task_cnt := g01maxuser + g01maxservertask + g01maxdatawriter + 8;
vmalloc (task_cnt * sizeof (tbd02_TaskQueueItem), p.cblockaddr, ok);
(* *)
IF  alloc_msg_all <> bsp_c24
THEN
    BEGIN
    g01allocate_msg (csp3_n_dynpool, alloc_msg_all,
          task_cnt * sizeof (tbd02_TaskQueueItem));
    g01allocate_msg (csp3_n_dynpool, 'US + SV + DW +  8      :',
          task_cnt);
    g01allocate_msg (csp3_n_dynpool, alloc_msg_elem,
          sizeof (tbd02_TaskQueueItem))
    END;
(* *)
(*ENDIF*) 
IF  NOT ok
THEN
    trError := e_sysbuf_storage_exceeded
ELSE
    BEGIN
    SumDynPool    := SumDynPool + task_cnt * sizeof (tbd02_TaskQueueItem);
    act_chain_ptr := p.pid_queue_addr;
    head_ptr      := act_chain_ptr;
    free_ptr      := act_chain_ptr;
    FOR i := 1 TO task_cnt DO
        BEGIN
        IF  (i < task_cnt)
        THEN
            act_chain_ptr^.tqiFixedNext_bd02 := @p.aux_chain_addr^ [i + 1]
        ELSE
            act_chain_ptr^.tqiFixedNext_bd02 := NIL;
        (*ENDIF*) 
        act_chain_ptr^.tqiVarNext_bd02 := act_chain_ptr^.tqiFixedNext_bd02;
        act_chain_ptr^.tqiTaskId_bd02  := 0;
        act_chain_ptr^.tqiReason_bd02  := tqrNil_ebd02;
        act_chain_ptr^.tqiFiller1_bd02 := false;
        act_chain_ptr^.tqiFiller2_bd02 := 0;
        act_chain_ptr                  := act_chain_ptr^.tqiFixedNext_bd02
        END
    (*ENDFOR*) 
    END
(*ENDIF*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      bd20GetPage (
            TaskId              : tsp00_TaskId;
            VAR WaitContext     : tgg00_WaitContext;
            VAR TrError         : tgg00_BasisError;
            VAR ExclFileLockCnt : tsp00_Int2;
            VAR FileId          : tgg00_FileId;
            PageNo              : tsp00_PageNo;
            recMode             : tbd02_RecoveryMode;
            NodeRequest         : tbd_node_request;
            VAR nptr            : tbd_nodeptr;
            VAR cbptr           : tbd02_pDataCBlock;
            VAR PageState       : tbd02_CachePageState);
 
VAR
      RegOffset         : integer;
      old_occs          : integer;
      ChangedCnt        : tsp00_Int4;
      HashIndex         : tsp00_Int4;
      OldHashIndex      : tsp00_Int4;
      there             : tbd02_pDataCBlock;
      pred              : tbd02_pDataCBlock;
      new_cb            : tbd02_pDataCBlock;
 
BEGIN
RegOffset := PageNo MOD bd20RegionCount;
HashIndex := PageNo MOD bd20DataCacheList [RegOffset].dc_HeadListSize;
WITH PageState, bd20DataCacheList [RegOffset], FileId DO
    BEGIN
    TrError              := e_ok;
    cpsWaitForWrite_bd02 := false;
    new_cb               := NIL;
    cbptr                := NIL;
    ChangedCnt           := 0;
    (* *)
    vbegexcl (TaskId, g08data1 + RegOffset);
    (* *)
    IF  cpsSynchSvpAndTreeSplits_bd02 = synchCheckPreventSplit_ebd02
    THEN
        IF  dc_PreventSplit AND (0 = ExclFileLockCnt) (* PTS 1109891 UH 2001-04-02 *)
        THEN
            BEGIN
            bd20_SearchAndResumeLockRequest( TaskId, bd20DataCacheList [RegOffset],
                  HashIndex, PageNo, recMode ); (* PTS 1113035 TS 2002-01-31 *)
            kb560InsertToWaitForPrepare(TaskId, WaitContext);
            cpsSynchSvpAndTreeSplits_bd02 := synchWait_ebd02
            END
        ELSE
            cpsSynchSvpAndTreeSplits_bd02 := synchUpdateExclCbFlag_ebd02;
        (*ENDIF*) 
    (*ENDIF*) 
    IF  NOT dc_SegmentActive
    THEN
        TrError := e_shutdown;
    (*ENDIF*) 
    IF  (TrError = e_ok) AND (cpsSynchSvpAndTreeSplits_bd02 <> synchWait_ebd02)
    THEN
        BEGIN
        bd20_SearchInChain (bd20DataCacheList [RegOffset],
              HashIndex, PageNo, recMode, there, pred, cpsFound_bd02);
        IF  cpsFound_bd02
        THEN
            BEGIN
            cpsDirty_bd02 := false;
            IF  (NodeRequest = nr_for_update)
                AND
                (
                (there^.dcb_io_state = iosServerIO_ebd02) OR
                (
                (there^.dcb_ChangedState_bd02 =  cstSvpRelevant_ebd02) AND
                (there^.dcb_io_state         <> iosUserIO_ebd02      ) (* see bd20LockPageForFree *)
                )
                )
            THEN
                BEGIN
                IF  (there^.dcb_UsageCnt_bd02 = 0)
                THEN
                    BEGIN
                    bd20_CopyCBlock (TaskId, FileId, bd20DataCacheList [RegOffset],
                          HashIndex, there, new_cb, TrError);
                    IF  TrError = e_ok
                    THEN
                        BEGIN
                        IF  cpsSynchSvpAndTreeSplits_bd02 = synchUpdateExclCbFlag_ebd02
                        THEN
                            BEGIN
                            new_cb^.dcb_ExclusiveLocked_bd02 := true;
                            dc_NumSplitLocks                 := dc_NumSplitLocks + 1;
                            ExclFileLockCnt                  := ExclFileLockCnt + 1;
                            cpsSynchSvpAndTreeSplits_bd02    := synchNone_ebd02;
                            END;
                        (*ENDIF*) 
                        nptr  := new_cb^.dcb_pFrame_bd02;
                        cbptr := new_cb
                        END
                    (*ENDIF*) 
                    END
                ELSE
                    BEGIN
                    IF  (there^.dcb_LastOwner_bd02 = TaskId    ) AND
                        (there^.dcb_io_state = iosBlocked_ebd02)
                    THEN
                        bd20_Abort (FileId, csp3_b20x1_illegal_request,
                              'Second Req  ', there^.dcb_occupant, there);
                    (*ENDIF*) 
                    IF  cpsIntendToWaitForLock_bd02
                    THEN
                        BEGIN
                        bd20_InsertLockRequest (TaskId, FileId,
                              bd20DataCacheList [RegOffset],
                              tqrExclusiveLock_ebd02, there);
                        cpsHaveToWaitForLock_bd02 := true
                        END
                    ELSE
                        TrError := e_bd_page_collision
                    (*ENDIF*) 
                    END
                (*ENDIF*) 
                END
            ELSE (* not tried to copy control block *)
                WITH there^ DO
                    BEGIN
                    IF  (dcb_io_state = iosUserIO_ebd02)
&                       ifdef AWE_USAGE
                        OR
                        ((dc_UnMapAreaSize > 0) AND (dcb_io_state = iosServerIO_ebd02))
&                       endif
                    THEN
                        BEGIN
                        (* IF AWE is used and the wanted CBlock is in state serverIO  *)
                        (* the pFrame is probability from the AWEFramePool. After the *)
                        (* IO the pFrame is given back to the pool and the CBlock has *)
                        (* no mapping! Therefore the caller has to wait until the IO  *)
                        (* is finished before accessing the CBlock again and getting  *)
                        (* an unused pFrame.                                          *)
                        cpsDirty_bd02 := true;
                        cbptr         := there;
                        bd20_InsertOccupant (TaskId, FileId, bd20DataCacheList [RegOffset], there)
                        END
                    ELSE
                        BEGIN
&                       ifdef AWE_USAGE
                        IF  dcb_pFrame_bd02 = NIL
                        THEN
                            bd20_ReMapFrame (TaskId, TrError, FileId, bd20DataCacheList [RegOffset], there);
&                       endif
                        (*ENDIF*) 
                        IF  TrError = e_ok
                        THEN
                            BEGIN
                            IF  NodeRequest = nr_for_upd_ret_if_blocked
                            THEN
                                BEGIN
                                (* Reason: devspace balancing *)
                                bd20set_changed (bd20DataCacheList [RegOffset], there, ADD_TMP_TO_IO_CHAIN_BD20)
                                END
                            ELSE
                                BEGIN
                                dcb_UsageCnt_bd02 := dcb_UsageCnt_bd02 + 1;
                                nptr              := dcb_pFrame_bd02;
                                cbptr             := there
                                END
                            (*ENDIF*) 
                            END;
                        (*ENDIF*) 
                        IF  NodeRequest <> nr_for_upd_ret_if_blocked
                        THEN
                            BEGIN
                            IF  TrError = e_ok
                            THEN
                                BEGIN
                                IF  NodeRequest = nr_for_update (* mutual exclusive access *)
                                THEN
                                    BEGIN
                                    IF  dcb_UsageCnt_bd02 > 1
                                    THEN
                                        BEGIN
                                        IF  (dcb_LastOwner_bd02 = TaskId    ) AND
                                            (dcb_io_state = iosBlocked_ebd02)
                                        THEN
                                            bd20_Abort (FileId, csp3_b20x4_illegal_request,
                                                  'Illegal Req ', dcb_occupant , there);
                                        (*ENDIF*) 
                                        IF  cpsIntendToWaitForLock_bd02
                                        THEN
                                            BEGIN
                                            bd20_InsertLockRequest (TaskId, FileId,
                                                  bd20DataCacheList [RegOffset],
                                                  tqrExclusiveLock_ebd02, cbptr);
                                            cpsHaveToWaitForLock_bd02 := true
                                            END
                                        ELSE
                                            TrError := e_bd_page_collision;
                                        (*ENDIF*) 
                                        dcb_UsageCnt_bd02 := dcb_UsageCnt_bd02 - 1;
                                        nptr              := NIL
                                        END
                                    ELSE
                                        BEGIN
                                        dcb_io_state       := iosBlocked_ebd02;
                                        dcb_LastOwner_bd02 := TaskId;
                                        IF  cpsSynchSvpAndTreeSplits_bd02 = synchUpdateExclCbFlag_ebd02
                                        THEN
                                            BEGIN
                                            dcb_ExclusiveLocked_bd02      := true;
                                            dc_NumSplitLocks              := dc_NumSplitLocks + 1;
                                            ExclFileLockCnt               := ExclFileLockCnt + 1;
                                            cpsSynchSvpAndTreeSplits_bd02 := synchNone_ebd02;
                                            END
                                        (*ENDIF*) 
                                        END
                                    (*ENDIF*) 
                                    END
                                ELSE (* mutual access *)
                                    BEGIN
                                    IF  (dcb_io_state = iosBlocked_ebd02) AND (dcb_UsageCnt_bd02 > 1)
                                    THEN
                                        BEGIN
                                        IF  (dcb_LastOwner_bd02 <> TaskId)
                                        THEN
                                            BEGIN
                                            IF  cpsIntendToWaitForLock_bd02
                                            THEN
                                                BEGIN
                                                bd20_InsertLockRequest (TaskId, FileId,
                                                      bd20DataCacheList [RegOffset],
                                                      tqrShareLock_ebd02, cbptr);
                                                cpsHaveToWaitForLock_bd02 := true;
                                                END
                                            ELSE
                                                TrError := e_bd_page_collision;
                                            (*ENDIF*) 
                                            dcb_UsageCnt_bd02 := dcb_UsageCnt_bd02 - 1;
                                            nptr              := NIL
                                            END
                                        (*ENDIF*) 
                                        END
                                    ELSE
                                        BEGIN
                                        IF  (dcb_lock_req_head <> NIL ) AND
                                            ((NOT cpsTaskRescheduled_bd02) OR (PageNo = fileRoot_gg00))
                                        THEN
                                            BEGIN
                                            (* Reschedule reader task to avoid starvation of writer *)
                                            bd20_InsertLockRequest (TaskId, FileId,
                                                  bd20DataCacheList [RegOffset],
                                                  tqrShareLock_ebd02, cbptr);
                                            cpsHaveToWaitForLock_bd02 := true;
                                            cpsTaskRescheduled_bd02   := true;
                                            dcb_UsageCnt_bd02         := dcb_UsageCnt_bd02 - 1;
                                            nptr                      := NIL;
                                            END
                                        ELSE
                                            dcb_LastOwner_bd02 := dcb_LastOwner_bd02 + TaskId; (* PTS 1124301 *)
                                        (*ENDIF*) 
                                        END
                                    (*ENDIF*) 
                                    END
                                (*ENDIF*) 
                                END
                            (*ENDIF*) 
                            END;
                        (*ENDIF*) 
                        IF  dcb_lru_rechain
                        THEN
                            bd20_PutFirstLRUList (bd20DataCacheList [RegOffset], there)
                        (*ENDIF*) 
                        END
                    (*ENDIF*) 
                    END
                (*ENDWITH*) 
            (*ENDIF*) 
            END
        ELSE (* Not bFound *)
            BEGIN
            IF  dc_pHeadList^ [HashIndex].he_old_occ_cnt > 0
            THEN
                BEGIN (* is requested page in write io *)
                old_occs := dc_OldOccupants;
                there    := dc_pFirstLRU;
                WHILE (NOT cpsWaitForWrite_bd02) AND (there <> NIL) AND (old_occs > 0) DO
                    BEGIN
                    WITH there^ DO
                        BEGIN
                        IF  (dcb_OldOccupant_bd02 = PageNo) AND (dcb_OldRecMode_bd02 = recMode)
                        THEN
                            BEGIN
                            cpsWaitForWrite_bd02 := true;
                            bd20_InsertOldOccupant( TaskId, FileId, bd20DataCacheList [RegOffset], there )
                            END
                        ELSE
                            BEGIN
                            IF  dcb_OldOccupant_bd02 <> NIL_PAGE_NO_GG00
                            THEN
                                old_occs := old_occs - 1;
                            (*ENDIF*) 
                            there := there^.dcb_lru_next;
                            END
                        (*ENDIF*) 
                        END
                    (*ENDWITH*) 
                    END
                (*ENDWHILE*) 
                END;
            (*ENDIF*) 
            IF  NOT cpsWaitForWrite_bd02
            THEN
                BEGIN
                bd20_GetFrameFromLRU (TaskId, TrError, FileId, bd20DataCacheList [RegOffset],
                      NOT IGNORE_DIRTY_PAGES_BD20, there, ChangedCnt);
                IF  TrError = e_ok
                THEN
                    BEGIN
                    WITH there^ DO
                        BEGIN
                        cpsDirty_bd02 := dcb_ChangedState_bd02 = cstChanged_ebd02;
                        dcb_io_state  := iosUserIO_ebd02;
                        IF  cpsDirty_bd02
                        THEN
                            BEGIN
                            bd20unset_changed (bd20DataCacheList [RegOffset], there);
                            dcb_OldOccupant_bd02 := dcb_occupant;
                            dcb_OldRecMode_bd02  := dcb_RecMode_bd02;
                            OldHashIndex         := dcb_OldOccupant_bd02 MOD dc_HeadListSize;
                            WITH  dc_pHeadList^ [OldHashIndex] DO
                                BEGIN
                                he_old_occ_cnt  := succ (he_old_occ_cnt);
                                dc_OldOccupants := succ (dc_OldOccupants)
                                END
                            (*ENDWITH*) 
                            END;
                        (*ENDIF*) 
                        dcb_occupant     := PageNo;
                        dcb_tfn          := fileTfn_gg00;
                        dcb_RecMode_bd02 := recMode;
                        IF  cpsSynchSvpAndTreeSplits_bd02 = synchUpdateExclCbFlag_ebd02
                        THEN
                            BEGIN
                            dcb_ExclusiveLocked_bd02      := true;
                            dc_NumSplitLocks              := dc_NumSplitLocks + 1;
                            ExclFileLockCnt               := ExclFileLockCnt + 1;
                            cpsSynchSvpAndTreeSplits_bd02 := synchNone_ebd02;
                            END;
                        (*ENDIF*) 
                        bd20add_to_chain (bd20DataCacheList [RegOffset], HashIndex, there);
                        cbptr := there;
                        nptr  := dcb_pFrame_bd02
                        END
                    (*ENDWITH*) 
                    END
                (*ENDIF*) 
                END
            (*ENDIF*) 
            END;
        (*ENDIF*) 
        IF  bd20DataCacheList [RegOffset].dc_MemoryProtection  AND (TrError = e_ok)
        THEN
            bd20_ReadWriteAccessToFrame (bd20DataCacheList [RegOffset], nptr);
        (*ENDIF*) 
        IF  g01glob.datacachecheck
&           ifdef TEST_AWE
            OR
            (dc_UnMapAreaSize > 0)
&           endif
        THEN
            bd20_CheckLRUList (bd20DataCacheList [RegOffset])
        (*ENDIF*) 
        END;
    (*ENDIF*) 
    bd20_MaintainCacheStatistic (bd20DataCacheList [RegOffset], cpsFound_bd02, fileTfn_gg00);
    (* *)
    vendexcl (TaskId, g08data1 + RegOffset);
    (* *)
    (* PTS 1106254 TS 2000-04-04 *)
    IF  cpsSynchSvpAndTreeSplits_bd02 = synchUpdateExclCbFlag_ebd02
    THEN
        cpsSynchSvpAndTreeSplits_bd02 := synchCheckPreventSplit_ebd02;
    (* PTS 1106254 *)
    (* *)
    (* In this case dirty read is not dangerous *)
    (* *)
    (*ENDIF*) 
    IF  TrError = e_ok
    THEN
        BEGIN
        IF  (NOT dc_SVPActive               ) AND
            (
            (dc_IOElems > dc_IOAreaFlushCnt ) OR
            (ChangedCnt > dc_LruTailFlushCnt)
            )
        THEN
            bd999ResumeOneDataWriter (TaskId, RegOffset);
        (*ENDIF*) 
        END;
    (*ENDIF*) 
    END
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      bd20GetPageForIO (
            TaskId           : tsp00_TaskId;
            RegOffset        : integer;
            VAR TrError      : tgg00_BasisError;
            VAR FlushElems   : tsp00_Int2;
            VAR NodePtrList  : tbd00_NodePtrList;
            VAR CBlockList   : tbd2_data_cb_flush_list;
            VAR Completed    : boolean;
            VAR IsSequential : boolean);
 
VAR
      MaxFlushElems : tsp00_Int2;
      Index         : tsp00_Int4;
      pCBlock       : tbd02_pDataCBlock;
 
BEGIN
MaxFlushElems := FlushElems;
FlushElems    := 0;
(* *)
vbegexcl (TaskId, g08data1 + RegOffset);
(* *)
WITH bd20DataCacheList [RegOffset] DO
    IF  NOT dc_SegmentActive
    THEN
        TrError := e_shutdown
    ELSE
        BEGIN
&       ifdef TRACE
        IF  t01trace (bd_ioqueue)
        THEN
            bd20print_io_chain (bd20DataCacheList [RegOffset]);
&       endif
        (*ENDIF*) 
        IF  ((dc_SVPActive AND (dc_SVPElems > 0))
            OR
            (NOT dc_SVPActive AND (dc_IOElems > 0)))
        THEN
            BEGIN
            IF  (dc_SVPActive AND dc_IOSwitch        ) OR
                (NOT dc_SVPActive AND NOT dc_IOSwitch)
            THEN
                pCBlock := dc_pIOQueueTail1
            ELSE
                pCBlock := dc_pIOQueueTail2;
            (*ENDIF*) 
            WHILE (pCBlock <> NIL) AND (FlushElems < MaxFlushElems) DO
                WITH pCBlock^, CBlockList DO
                    BEGIN
                    IF  (dcb_copy_no  = 0) AND (dcb_io_state = iosNone_ebd02)
                    THEN
                        BEGIN
&                       ifdef AWE_USAGE
                        cbl_AuxBufUsed_bd02 [FlushElems+1] := (dcb_pFrame_bd02 = NIL);
                        IF  dcb_pFrame_bd02 = NIL
                        THEN
                            bd20_GetFromAWEFramePool( TaskId, dcb_AWE_BlockNo_bd02, dcb_pFrame_bd02 );
&                       endif
                        (*ENDIF*) 
                        IF  (bd20ForArchive AND (FlushElems > 0))
                            AND
                            (
                            (IsSequential AND ((NOT (pmArchive_egg00 IN dcb_pFrame_bd02^.nd_pmode)) OR
                            (dcb_pFrame_bd02^.nd_right = NIL_PAGE_NO_GG00)))
                            OR
                            ((NOT IsSequential) AND (pmArchive_egg00 IN dcb_pFrame_bd02^.nd_pmode) AND
                            (dcb_pFrame_bd02^.nd_right <> NIL_PAGE_NO_GG00))
                            )
                        THEN
                            BEGIN (* not relevant for io at this time *)
&                           ifdef AWE_USAGE
                            IF  cbl_AuxBufUsed_bd02 [FlushElems+1]
                            THEN
                                bd20_ReleaseToAWEFramePool( TaskId, dcb_pFrame_bd02 );
&                           endif
                            (*ENDIF*) 
                            END
                        ELSE
                            BEGIN
                            dcb_io_state                  := iosServerIO_ebd02;
                            FlushElems                    := FlushElems + 1;
                            cbl_pCBlock_bd02 [FlushElems] := pCBlock;
                            NodePtrList[FlushElems]       := dcb_pFrame_bd02;
                            IF  bd20DataCacheList [RegOffset].dc_MemoryProtection
                            THEN
                                bd20_ReadWriteAccessToFrame (bd20DataCacheList [RegOffset], dcb_pFrame_bd02);
                            (*ENDIF*) 
                            IF  bd20ForArchive AND (FlushElems = 1)
                            THEN
                                IsSequential:= (pmArchive_egg00 IN dcb_pFrame_bd02^.nd_pmode) AND
                                      (dcb_pFrame_bd02^.nd_right <> NIL_PAGE_NO_GG00)
                            (*ENDIF*) 
                            END
                        (*ENDIF*) 
                        END;
                    (*ENDIF*) 
                    pCBlock  := pCBlock^.dcb_io_prev
                    END
                (*ENDWITH*) 
            (*ENDWHILE*) 
            END;
        (*ENDIF*) 
        IF  (dc_SVPActive) AND (dc_SVPElems = 0)
        THEN
            BEGIN
            Completed := true;
            IF  g01glob.datacachecheck
            THEN
                bd20check_svp_chain (bd20DataCacheList [RegOffset])
            (*ENDIF*) 
            END
        (*ENDIF*) 
        END;
    (*ENDIF*) 
(*ENDWITH*) 
(* *)
vendexcl (TaskId, g08data1 + RegOffset);
(* *)
FOR Index := 1 TO FlushElems DO
    WITH CBlockList.cbl_pCBlock_bd02 [Index]^  DO
        bd73DataIOStatistic (dcb_pFrame_bd02^.nd_level,
              dcb_tfn, NOT IS_VIRTUAL_IO_BD20, NOT IS_READ_IO_BD20);
    (*ENDWITH*) 
(*ENDFOR*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      bd20InitDataCache (
            TaskId          : tsp00_TaskId;
            VAR TrError     : tgg00_BasisError;
            TotalFreeFrames : tsp00_Int4;
            TotalDataPages  : tsp00_Int4);
 
VAR
      RegOffset     : integer;
      Buffers       : tsp00_Int4;
      UnMapAreaSize : tsp00_Int4;
      SegmentSize   : tsp00_Int4;
      SumDynData    : tsp00_Int4;
      SumDynPool    : tsp00_Int4;
 
BEGIN
RegOffset                := 0;
SumDynPool               := 0;
SumDynData               := 0;
bd20ForArchive           := g01is_archive;
bd20RegionCount          := g01region_cnt (rgnData_egg00);
bd20TotalChangedPages    := 0;
bd20NextShrinkSegment    := 0;
(* *)
IF  (bd20RegionCount < (FIRST_SEGMENT_BD20 + 1)) OR
    (bd20RegionCount > (LAST_SEGMENT_BD20 + 1))
THEN
    g01abort (csp3_b20x1_invalid_region_cnt, csp3_n_config,
          'DATA_REGIONS invalid   :', bd20RegionCount);
(* *)
(* --- INITIALIZATION OF CONTROLBLOCK DEFAULT STRUCTURE --- *)
(* *)
(*ENDIF*) 
WITH bd20CBlockInit DO
    BEGIN
    dcbi_lru_next             := NIL;
    dcbi_lru_prev             := NIL;
    dcbi_io_next              := NIL;
    dcbi_io_prev              := NIL;
    dcbi_queue_occ            := NIL;
    dcbi_queue_old_occ        := NIL;
    dcbi_lock_req_head        := NIL;
    dcbi_lock_req_tail        := NIL;
    dcbi_occupant             := NIL_PAGE_NO_GG00;
    dcbi_OldOccupant_bd02     := NIL_PAGE_NO_GG00;
    dcbi_LastOwner_bd02       := cgg_nil_pid;
    dcbi_UsageCnt_bd02        := 0;
    dcbi_tfn                  := tfnNil_egg00;
    dcbi_lru_rechain          := false;
    dcbi_ChangedState_bd02    := cstNone_ebd02;
    dcbi_io_state             := iosNone_ebd02;
    dcbi_ExclusiveLocked_bd02 := false;
    dcbi_IsSourceOfACopy_bd02 := false;
    dcbi_OldRecMode_bd02      := rmNone_ebd02;
    dcbi_copy_no              := 0;
    dcbi_dw_io_area           := false;
    dcbi_RecMode_bd02         := rmNone_ebd02;
    END;
(*ENDWITH*) 
IF  TotalDataPages < TotalFreeFrames
THEN
    Buffers := TotalDataPages (* more cache pages than space on devspace is stupied *)
ELSE
    Buffers := TotalFreeFrames;
(*ENDIF*) 
IF  RTEMem_AWEAvailable
THEN
    BEGIN
    (* *)
    g01opmsg (sp3p_knldiag, sp3m_info, csp3_bd_msg, csp3_n_datacache,
          'AWE PhysicalPages       ', RTEMem_AWENumOfPhysicalPages);
    g01opmsg (sp3p_knldiag, sp3m_info, csp3_bd_msg, csp3_n_datacache,
          'AWE MapAreaPages        ', RTEMem_AWENumOfMapAreaPages);
    (* *)
&   ifdef AWE_USAGE
    bd20_InitAWEFramePool( TaskId, Buffers );
&   endif
    UnMapAreaSize := RTEMem_AWENumOfPhysicalPages - RTEMem_AWENumOfMapAreaPages;
    IF  ( Buffers + UnMapAreaSize > TotalDataPages )
    THEN
        BEGIN
        g01opmsg (sp3p_knldiag, sp3m_warning, csp3_bd_msg, csp3_n_datacache,
              'AWE Unused PhysicalPages', UnMapAreaSize - ( TotalDataPages - Buffers ));
        UnMapAreaSize := TotalDataPages - Buffers
        END;
    (*ENDIF*) 
    UnMapAreaSize := UnMapAreaSize DIV bd20RegionCount
    END
ELSE
    UnMapAreaSize := 0;
(*ENDIF*) 
IF  UnMapAreaSize > 0
THEN
    SegmentSize := (( Buffers DIV bd20RegionCount ) + UnMapAreaSize) -1 (* -1 because of dc_pAWE *)
ELSE
    SegmentSize := ( Buffers DIV bd20RegionCount ) + UnMapAreaSize;
(*ENDIF*) 
(* *)
IF  (SegmentSize < c_rechain_frac)
THEN
    g01abort (csp3_b20x1_buffer_to_small, csp3_n_config,
          'SegmentSize < 10       :', SegmentSize);
(*ENDIF*) 
g01allocate_msg (csp3_n_dynpool, 'DATA_CACHE_REGIONS     :', bd20RegionCount);
(* *)
WHILE (TrError = e_ok) AND (RegOffset <= bd20RegionCount - 1) DO
    BEGIN
    bd20_InitDataCache (TaskId, SegmentSize, UnMapAreaSize, RegOffset,
          SumDynPool, SumDynData, TrError);
    RegOffset := RegOffset + 1;
    END;
(*ENDWHILE*) 
g01allocate_msg (csp3_n_dynpool, 'DYNP_B20_DATACACHE     :', SumDynPool);
g01allocate_msg (csp3_n_dyndata, 'DYND_B20_DATACACHE     :', SumDynData);
END;
 
(*------------------------------*) 
 
PROCEDURE
      bd20_InitDataCache (
            TaskId         : tsp00_TaskId;
            SegmentSize    : tsp00_Int4;
            UnMapAreaSize  : tsp00_Int4;
            RegOffset      : integer;
            VAR SumDynPool : tsp00_Int4;
            VAR SumDynData : tsp00_Int4;
            VAR TrError    : tgg00_BasisError);
 
VAR
      ok        : boolean;
      Index     : tsp00_Int4;
      act_block : tbd02_pDataCBlock;
      p         : b20ptr;
 
BEGIN
(* *)
(* --- INITIALIZATION OF DATACACHE --- *)
(* *)
WITH bd20DataCacheList[ RegOffset ] DO
    BEGIN
    dc_pFirstCBlock       := NIL;
    dc_pLastCBlock        := NIL;
    dc_pFreeList          := NIL;
    dc_pFirstLRU          := NIL;
    dc_pLastLRU           := NIL;
    dc_pLastMappedCBlock  := NIL;
    dc_pMid               := NIL;
    dc_pIOMid             := NIL;
    dc_pIOQueueHead1      := NIL;
    dc_pIOQueueHead2      := NIL;
    dc_pIOQueueTail1      := NIL;
    dc_pIOQueueTail2      := NIL;
    dc_pOverflowTaskQueue := NIL;
    dc_pSvpEndTaskQueue   := NIL;
    dc_pFrameLessCBlocks  := NIL;
    dc_pUnMapFreeList     := NIL;
    (* *)
    dc_SegmentId          := RegOffset;
    dc_SegmentSize        := 0;
    dc_SVPElems           := 0;
    dc_IOElems            := 0;
    dc_FreeCount          := 0;
    dc_OldOccupants       := 0;
    dc_NumSplitLocks      := 0;
    dc_FrameLessCBlockCnt := 0;
    (* *)
    dc_UndoFilePageCnt    := 0;
    dc_OmsTempPageCnt     := 0;
    dc_OmsDataPageCnt     := 0;
    dc_SqlDataPageCnt     := 0;
    dc_UnMapFreeCount     := 0;
    dc_UnMapAreaSize      := 0;
    (* *)
    dc_UndoFileHit        := 0;
    dc_UndoFileMiss       := 0;
    dc_OmsDataHit         := 0;
    dc_OmsDataMiss        := 0;
    dc_SqlDataHit         := 0;
    dc_SqlDataMiss        := 0;
    (* *)
    dc_SVPActive          := false;
    dc_PreventSplit       := false;
    dc_IOSwitch           := false;
    dc_MemoryProtection   := false;
    (* *)
&   ifdef AWE_USAGE
    IF  UnMapAreaSize > 0
    THEN
        BEGIN
        g01opmsg (sp3p_knldiag, sp3m_info, csp3_bd_msg, csp3_n_datacache,
              'AWE FreePhysicalPages   ', RTEMem_AWENumOfFreePhysicalPages);
        g01opmsg (sp3p_knldiag, sp3m_info, csp3_bd_msg, csp3_n_datacache,
              'AWE FreeMapAreaPages    ', RTEMem_AWENumOfFreeMapAreaPages);
        END;
&   endif
    (* *)
    (* --- INITIALIZATION OF HEADLIST  --- *)
    (* *)
    (*ENDIF*) 
    dc_HeadListSize := SegmentSize * 4;
    g01next_prim_number (dc_HeadListSize);
    IF  dc_HeadListSize < c_hl_lower_lim
    THEN
        dc_HeadListSize := c_hl_lower_lim
    ELSE
        IF  dc_HeadListSize > c_hl_upper_lim
        THEN
            dc_HeadListSize := c_hl_upper_lim;
        (* *)
        (*ENDIF*) 
    (*ENDIF*) 
    vmalloc (dc_HeadListSize * sizeof (t_head_list_elem), p.cblockaddr, ok);
    (* *)
    IF  RegOffset = 0
    THEN
        BEGIN
        g01allocate_msg (csp3_n_dynpool, 'B20_DATACACHE_HEAD     :',
              dc_HeadListSize * sizeof (t_head_list_elem));
        g01allocate_msg (csp3_n_dynpool, 'DATACACHE head num item:',
              dc_HeadListSize);
        g01allocate_msg (csp3_n_dynpool, 'DATACACHE head item siz:',
              sizeof (t_head_list_elem))
        END;
    (* *)
    (*ENDIF*) 
    IF  NOT ok
    THEN
        TrError := e_sysbuf_storage_exceeded
    ELSE
        BEGIN
        dc_pHeadList := p.aux_hl_addr;
        SumDynPool   := SumDynPool + dc_HeadListSize * sizeof (t_head_list_elem);
        END;
    (*ENDIF*) 
    IF  TrError = e_ok
    THEN
        BEGIN
        FOR Index := 0 TO dc_HeadListSize - 1 DO
            WITH dc_pHeadList^ [Index] DO
                BEGIN
                he_cb          := NIL;
                he_old_occ_cnt := 0;
&               ifdef BIT64
                he_fill        := 0;
&               endif
                END
            (*ENDWITH*) 
        (*ENDFOR*) 
        END;
    (* *)
    (* --- INITIALIZATION OF TASK QUEUE --- *)
    (* *)
    (*ENDIF*) 
    IF  TrError = e_ok
    THEN
        BEGIN
        IF  RegOffset = 0
        THEN
            BEGIN
            bd20_GenerateTaskQueue (TrError, dc_pTaskQueueHead, dc_pTaskQueueFree,
                  'DATACACHE task queue   :', 'DATACACHE taskq elem   :', SumDynPool);
            g01allocate_msg (csp3_n_dynpool,  'B20_DATACACHE_TASKQ    :', SumDynPool)
            END
        ELSE
            bd20_GenerateTaskQueue (TrError, dc_pTaskQueueHead, dc_pTaskQueueFree,
                  bsp_c24, bsp_c24, SumDynPool)
        (*ENDIF*) 
        END;
    (* *)
    (* --- INITIALIZATION OF CONTROLBLOCKS AND FRAMES --- *)
    (* *)
    (*ENDIF*) 
    IF  TrError = e_ok
    THEN
        BEGIN
        IF  RegOffset = 0
        THEN
            BEGIN
            g01allocate_msg (csp3_n_dyndata, 'DATA_CACHE_PAGES       :', SegmentSize);
            IF  UnMapAreaSize > 0
            THEN
                BEGIN
                g01allocate_msg (csp3_n_dyndata, 'DATA_CACHE_PAGES (MAP) :', SegmentSize - UnMapAreaSize);
                g01allocate_msg (csp3_n_dyndata, 'DATA_CACHE_PAGES (UMAP):', UnMapAreaSize)
                END;
            (*ENDIF*) 
            g01allocate_msg (csp3_n_dynpool, 'B20_DATACACHE_CB       :',
                  SegmentSize * sizeof (tbd02_DataCBlock));
            g01allocate_msg (csp3_n_dynpool, 'DATACACHE num cblocks  :', SegmentSize);
            g01allocate_msg (csp3_n_dynpool, 'DATACACHE cblock size  :', sizeof (tbd02_DataCBlock))
            END;
        (* *)
        (* --- ALLOCATE MEMORY FOR THE CONTROL BLOCKS --- *)
        (* *)
        (*ENDIF*) 
        vmalloc (SegmentSize * sizeof (tbd02_DataCBlock), p.cblockaddr, ok);
        (* *)
        IF  NOT ok
        THEN
            TrError := e_sysbuf_storage_exceeded
        ELSE
            BEGIN
            SumDynPool      := SumDynPool + SegmentSize * sizeof (tbd02_DataCBlock);
            dc_pFirstCBlock := p.cblockaddr
            END;
        (*ENDIF*) 
        IF  ((TrError = e_ok) AND (UnMapAreaSize > 0))
        THEN
            dc_pAWEAuxBuffer := bd999GetFrame( TaskId )
        ELSE
            dc_pAWEAuxBuffer := NIL;
        (*ENDIF*) 
        IF  TrError = e_ok
        THEN
            BEGIN
            Index     := 0;
            act_block := dc_pFirstCBlock;
            REPEAT
                WITH act_block^ DO
                    BEGIN
                    IF  Index < (SegmentSize -1)
                    THEN
                        dcb_FixedNext_bd02 := @p.aux_cb_addr^[ Index + 1 ]
                    ELSE
                        BEGIN
                        dcb_FixedNext_bd02 := NIL;
                        dc_pLastCBlock     := act_block
                        END;
                    (*ENDIF*) 
                    dcb_Init_bd02 := bd20CBlockInit;
                    IF  (Index >= (SegmentSize - UnMapAreaSize))
                    THEN
                        BEGIN
                        dcb_pFrame_bd02 := NIL;
&                       ifdef AWE_USAGE
                        RTEMem_AWEReservePhysPage( dcb_AWE_BlockNo_bd02 );
&                       endif
                        END
                    ELSE
                        BEGIN
&                       ifdef AWE_USAGE
                        IF  UnMapAreaSize > 0
                        THEN
                            bd999GetAWEFrame( TaskId, dcb_pFrame_bd02, dcb_AWE_BlockNo_bd02 )
                        ELSE
                            BEGIN
                            dcb_pFrame_bd02      := bd999GetFrame( TaskId );
                            dcb_AWE_BlockNo_bd02 := NIL_AWE_HANDLE_BD20;
                            END;
                        (*ENDIF*) 
&                       else
                        dcb_pFrame_bd02 := bd999GetFrame( TaskId );
&                       endif
                        SumDynData := SumDynData + 1;
                        END;
                    (*ENDIF*) 
                    bd20_FreeFrame (bd20DataCacheList[ RegOffset ], act_block);
                    act_block  := act_block^.dcb_FixedNext_bd02;
                    Index      := Index + 1;
                    END
                (*ENDWITH*) 
            UNTIL
                act_block = NIL;
            (*ENDREPEAT*) 
            dc_SegmentSize   := SegmentSize;
            dc_UnMapAreaSize := UnMapAreaSize;
            dc_RecAreaSize   := (dc_SegmentSize + 1) DIV c_rechain_frac;
            IF  dc_SegmentSize < 100
            THEN
                BEGIN
                dc_IOAreaSize      := (dc_SegmentSize + 1) DIV c_p50_percent;
                dc_IOAreaFlushCnt  := trunc (((dc_SegmentSize+1)/10) * 2);
                (* NOTE: dc_LruTailFlushCnt MUST BE LESS EQUAL THAN dc_RecAreaSize! *)
                dc_LruTailFlushCnt := trunc ((dc_RecAreaSize+1)/2);
                END
            ELSE
                BEGIN
                dc_IOAreaSize      := trunc (((dc_SegmentSize + 1) / 100)* g01dw_io_area_size);
                dc_IOAreaFlushCnt  := trunc (((dc_SegmentSize+1)/100) * g01dw_io_area_flush);
                dc_LruTailFlushCnt := trunc (((dc_RecAreaSize+1)/100) * g01dw_lru_tail_flush);
                END
            (*ENDIF*) 
            END
        (*ENDIF*) 
        END;
    (*ENDIF*) 
    dc_SegmentActive := (TrError = e_ok)
    END
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
FUNCTION
      bd20IOElemCount (
            TaskId    : tsp00_TaskId;
            RegOffset : integer) : tsp00_Int4;
 
BEGIN
vbegexcl (TaskId, g08data1 + RegOffset);
bd20IOElemCount := bd20DataCacheList [RegOffset].dc_IOElems;
vendexcl (TaskId, g08data1 + RegOffset);
END;
 
(*------------------------------*) 
 
PROCEDURE
      bd20ResetIOState (
            TaskId     : tsp00_TaskId;
            RegOffset  : integer;
            FlushElems : tsp00_Int2;
            CBlockList : tbd2_data_cb_flush_list);
 
VAR
      Index : tsp00_Int4;
 
BEGIN
(* *)
vbegexcl (TaskId, g08data1 + RegOffset);
(* *)
WITH bd20DataCacheList [RegOffset] DO
    IF  dc_SegmentActive
    THEN
        BEGIN
        FOR Index := 1 TO FlushElems DO
            BEGIN
            IF  CBlockList.cbl_pCBlock_bd02 [Index] = NIL
            THEN
                g01abort (csp3_b20x1_nil_cbptr, csp3_n_datacache,
                      'B20IRES: NIL addr       ', 0);
            (*ENDIF*) 
            WITH CBlockList, cbl_pCBlock_bd02 [Index]^ DO
                BEGIN
&               ifdef AWE_USAGE
                IF  cbl_AuxBufUsed_bd02 [Index]
                THEN
                    bd20_ReleaseToAWEFramePool( TaskId, dcb_pFrame_bd02 );
&               endif
                (*ENDIF*) 
                IF  dcb_io_state = iosServerIO_ebd02
                THEN
                    BEGIN
                    dcb_io_state := iosNone_ebd02;
                    IF  dcb_queue_occ <> NIL
                    THEN
                        bd20_ResumeOccupant (bd20DataCacheList [RegOffset],
                              MSG_RESET_IO_STATE, cbl_pCBlock_bd02 [Index]);
                    (*ENDIF*) 
                    END;
&               ifdef TRACE
                (*ENDIF*) 
                IF  t01trace (bd_ioqueue)
                THEN
                    BEGIN
                    t01int4 (bd_ioqueue, '==> page no ', dcb_occupant);
                    t01int4 (bd_ioqueue, '==> dcb_tfn ', ord(dcb_tfn))
                    END;
&               endif
                (*ENDIF*) 
                bd20unset_changed (bd20DataCacheList [RegOffset], cbl_pCBlock_bd02 [Index]);
                IF  dcb_IsSourceOfACopy_bd02 AND (dcb_UsageCnt_bd02 = 0)
                THEN
                    bd20_FreeCBlock (bd20DataCacheList [RegOffset],
                          c_nil_hash, NIL, cbl_pCBlock_bd02 [Index]);
                (*ENDIF*) 
                IF  bd20DataCacheList [RegOffset].dc_MemoryProtection
                THEN
                    BEGIN
                    IF  dcb_UsageCnt_bd02 = 0
                    THEN
                        bd20_ReadAccessToFrame (bd20DataCacheList [RegOffset], dcb_pFrame_bd02)
                    ELSE
                        bd20_ReadWriteAccessToFrame (bd20DataCacheList [RegOffset], dcb_pFrame_bd02)
                    (*ENDIF*) 
                    END;
                (*ENDIF*) 
                END;
            (*ENDWITH*) 
&           ifdef TRACE
            IF  t01trace (bd_ioqueue)
            THEN
                bd20print_io_chain (bd20DataCacheList [RegOffset]);
            (*ENDIF*) 
            IF  g01glob.datacachecheck
            THEN
                bd20check_io_chain (bd20DataCacheList [RegOffset]);
&           endif
            (*ENDIF*) 
            END;
        (*ENDFOR*) 
        IF  (dc_pOverflowTaskQueue <> NIL)
        THEN
            bd20_ResumeOverflow (bd20DataCacheList [RegOffset], FlushElems);
        (*ENDIF*) 
        END;
    (* *)
    (*ENDIF*) 
(*ENDWITH*) 
vendexcl (TaskId, g08data1 + RegOffset);
(* *)
END;
 
(*------------------------------*) 
 
FUNCTION
      bd20IsPageChanged (
            pCBlock : tbd02_pDataCBlock) : boolean;
 
BEGIN
bd20IsPageChanged := (pCBlock^.dcb_ChangedState_bd02 = cstChanged_ebd02) OR
      (pCBlock^.dcb_ChangedState_bd02 = cstSvpRelevant_ebd02);
END;
 
(*------------------------------*) 
 
FUNCTION
      bd20IsPageExclusiveLocked (
            pCBlock : tbd02_pDataCBlock) : boolean;
 
BEGIN
bd20IsPageExclusiveLocked := pCBlock^.dcb_io_state = iosBlocked_ebd02;
END;
 
(*------------------------------*) 
 
FUNCTION
      bd20IsPageShareLocked (
            pCBlock : tbd02_pDataCBlock) : boolean;
 
BEGIN
bd20IsPageShareLocked :=
      (pCBlock^.dcb_io_state = iosNone_ebd02) AND (pCBlock^.dcb_UsageCnt_bd02 > 0)
END;
 
(*------------------------------*) 
 
FUNCTION
      bd20GetPageUsageCount (
            pCBlock : tbd02_pDataCBlock) : tsp00_Int2;
 
BEGIN
bd20GetPageUsageCount := pCBlock^.dcb_UsageCnt_bd02;
END;
 
(*------------------------------*) 
 
PROCEDURE
      bd20NewPage (
            TaskId        : tsp00_TaskId;
            VAR TrError   : tgg00_BasisError;
            VAR FileId    : tgg00_FileId;
            PageNo        : tsp00_PageNo;
            recMode       : tbd02_RecoveryMode;
            VAR nptr      : tbd_nodeptr;
            VAR cbptr     : tbd02_pDataCBlock;
            VAR PageState : tbd02_CachePageState);
 
VAR
      bFound        : boolean;
      RegOffset     : integer;
      ChangedCnt    : tsp00_Int4;
      HashIndex     : tsp00_Int4;
      OldHashIndex  : tsp00_Int4;
      there         : tbd02_pDataCBlock;
      pred          : tbd02_pDataCBlock;
 
BEGIN
ChangedCnt := 0;
RegOffset  := PageNo MOD bd20RegionCount;
HashIndex  := PageNo MOD bd20DataCacheList [RegOffset].dc_HeadListSize;
WITH bd20DataCacheList [RegOffset], PageState DO
    BEGIN
    (* *)
    vbegexcl (TaskId, g08data1 + RegOffset);
    (* *)
    IF  NOT dc_SegmentActive
    THEN
        TrError := e_shutdown;
    (*ENDIF*) 
    IF  TrError = e_ok
    THEN
        BEGIN
        bd20_SearchInChain (bd20DataCacheList [RegOffset], HashIndex, PageNo,
              recMode, there, pred, bFound);
        IF  bFound
        THEN
            IF  there^.dcb_io_state = iosUserIO_ebd02
            THEN
                BEGIN
                cpsWaitForWrite_bd02 := true;
                cbptr                := there;
                bd20_InsertOccupant (TaskId, FileId, bd20DataCacheList [RegOffset], there)
                END
            ELSE
                bd20_Abort (FileId, csp3_b20x1_pno_found, 'NewPno Found', PageNo, there)
            (*ENDIF*) 
        ELSE (* not bFound *)
            BEGIN
            there := NIL;
            bd20_GetFrameFromLRU (TaskId, TrError, FileId, bd20DataCacheList [RegOffset],
                  NOT IGNORE_DIRTY_PAGES_BD20, there, ChangedCnt);
            IF  TrError = e_ok
            THEN
                BEGIN
                WITH there^ DO
                    BEGIN
                    cpsDirty_bd02 := dcb_ChangedState_bd02 = cstChanged_ebd02;
                    IF  cpsDirty_bd02
                    THEN
                        BEGIN
                        bd20unset_changed (bd20DataCacheList [RegOffset], there);
                        dcb_io_state         := iosUserIO_ebd02;
                        dcb_OldOccupant_bd02 := dcb_occupant;
                        dcb_OldRecMode_bd02  := dcb_RecMode_bd02;
                        OldHashIndex         := dcb_OldOccupant_bd02 MOD dc_HeadListSize;
                        WITH  dc_pHeadList^ [OldHashIndex] DO
                            BEGIN
                            he_old_occ_cnt  := he_old_occ_cnt + 1;
                            dc_OldOccupants := dc_OldOccupants +1;
                            END
                        (*ENDWITH*) 
                        END
                    ELSE
                        BEGIN
                        dcb_UsageCnt_bd02  := 1;
                        dcb_io_state       := iosBlocked_ebd02;
                        dcb_LastOwner_bd02 := TaskId
                        END;
                    (*ENDIF*) 
                    dcb_occupant      := PageNo;
                    dcb_RecMode_bd02  := recMode;
                    dcb_tfn           := FileId.fileTfn_gg00;
                    (* dcb_UsageCnt_bd02 := 1; PTS 1124301 *)
                    bd20add_to_chain (bd20DataCacheList [RegOffset], HashIndex, there);
                    cbptr := there;
                    nptr  := dcb_pFrame_bd02;
                    IF  bd20DataCacheList [RegOffset].dc_MemoryProtection
                    THEN
                        bd20_ReadWriteAccessToFrame (bd20DataCacheList [RegOffset], nptr);
                    (*ENDIF*) 
                    END
                (*ENDWITH*) 
                END
            (*ENDIF*) 
            END;
        (*ENDIF*) 
        IF  g01glob.datacachecheck
&           ifdef TEST_AWE
            OR
            (dc_UnMapAreaSize > 0)
&           endif
        THEN
            bd20_CheckLRUList (bd20DataCacheList [RegOffset])
        (*ENDIF*) 
        END;
    (* *)
    (*ENDIF*) 
    vendexcl (TaskId, g08data1 + RegOffset);
    (* *)
    (* In this case dirty read is not dangerous *)
    (* *)
    IF  (TrError = e_ok                 ) AND
        (NOT dc_SVPActive               ) AND
        (
        (dc_IOElems > dc_IOAreaFlushCnt ) OR
        (ChangedCnt > dc_LruTailFlushCnt)
        )
    THEN
        bd999ResumeOneDataWriter (TaskId, RegOffset);
    (*ENDIF*) 
    END
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      bd20PreDisplaceIO (
            TaskId           : tsp00_TaskId;
            RegOffset        : integer;
            VAR TrError      : tgg00_BasisError;
            VAR UseIOChain   : boolean;
            VAR FlushElems   : tsp00_Int2;
            VAR NodePtrList  : tbd00_NodePtrList;
            VAR CBlockList   : tbd2_data_cb_flush_list;
            VAR IsSequential : boolean);
 
VAR
      bStop         : boolean;
      MaxFlushElems : tsp00_Int2;
      Index         : tsp00_Int4;
      pCBlock       : tbd02_pDataCBlock;
 
BEGIN
MaxFlushElems := FlushElems;
FlushElems    := 0;
bStop         := false;
(* *)
vbegexcl (TaskId, g08data1 + RegOffset);
(* *)
WITH bd20DataCacheList [RegOffset] DO
    BEGIN
    IF  NOT dc_SegmentActive
    THEN
        TrError := e_shutdown
    ELSE
        BEGIN
        IF  UseIOChain
        THEN
            BEGIN
            IF  dc_IOSwitch
            THEN
                pCBlock := dc_pIOQueueTail2
            ELSE
                pCBlock := dc_pIOQueueTail1
            (*ENDIF*) 
            END
        ELSE
            pCBlock := dc_pLastLRU;
        (*ENDIF*) 
        (* *)
        WHILE (pCBlock   <> NIL          ) AND
              (FlushElems < MaxFlushElems) AND
              NOT bStop                    DO
            WITH pCBlock^ DO
                BEGIN
                IF  (dcb_ChangedState_bd02 <> cstNone_ebd02) AND
                    (dcb_copy_no          =  0             ) AND
                    (dcb_io_state         =  iosNone_ebd02 )
                THEN
                    WITH CBlockList DO
                        BEGIN
&                       ifdef AWE_USAGE
                        cbl_AuxBufUsed_bd02 [FlushElems+1] := (dcb_pFrame_bd02 = NIL);
                        IF  dcb_pFrame_bd02 = NIL
                        THEN
                            bd20_GetFromAWEFramePool( TaskId, dcb_AWE_BlockNo_bd02, dcb_pFrame_bd02 );
&                       endif
                        (*ENDIF*) 
                        IF  (bd20ForArchive AND (FlushElems > 0))
                            AND
                            (
                            (IsSequential AND ((NOT (pmArchive_egg00 IN dcb_pFrame_bd02^.nd_pmode)) OR
                            (dcb_pFrame_bd02^.nd_right = NIL_PAGE_NO_GG00)))
                            OR
                            ((NOT IsSequential) AND (pmArchive_egg00 IN dcb_pFrame_bd02^.nd_pmode) AND
                            (dcb_pFrame_bd02^.nd_right <> NIL_PAGE_NO_GG00))
                            )
                        THEN
                            BEGIN (* not relevant for io at this time *)
&                           ifdef AWE_USAGE
                            IF  cbl_AuxBufUsed_bd02 [FlushElems+1]
                            THEN
                                bd20_ReleaseToAWEFramePool( TaskId, dcb_pFrame_bd02 );
&                           endif
                            (*ENDIF*) 
                            END
                        ELSE
                            BEGIN;
                            dcb_io_state                  := iosServerIO_ebd02;
                            FlushElems                    := FlushElems + 1;
                            cbl_pCBlock_bd02 [FlushElems] := pCBlock;
                            NodePtrList [FlushElems]      := dcb_pFrame_bd02;
                            IF  bd20DataCacheList [RegOffset].dc_MemoryProtection
                            THEN
                                bd20_ReadWriteAccessToFrame (bd20DataCacheList [RegOffset], dcb_pFrame_bd02);
                            (*ENDIF*) 
                            IF  bd20ForArchive AND (FlushElems = 1)
                            THEN
                                IsSequential:= (pmArchive_egg00 IN dcb_pFrame_bd02^.nd_pmode) AND
                                      (dcb_pFrame_bd02^.nd_right <> NIL_PAGE_NO_GG00)
                            (*ENDIF*) 
                            END
                        (*ENDIF*) 
                        END;
                    (*ENDWITH*) 
                (*ENDIF*) 
                IF  UseIOChain
                THEN
                    BEGIN
                    pCBlock := pCBlock^.dcb_io_prev;
                    IF  pCBlock <> NIL
                    THEN
                        bStop := (NOT pCBlock^.dcb_dw_io_area)
                    (*ENDIF*) 
                    END
                ELSE
                    BEGIN
                    pCBlock := pCBlock^.dcb_lru_prev;
                    IF  pCBlock <> NIL
                    THEN
                        IF  NOT pCBlock^.dcb_lru_rechain
                        THEN
                            BEGIN
                            UseIOChain := true;
                            IF  dc_IOSwitch
                            THEN
                                pCBlock := dc_pIOQueueTail2
                            ELSE
                                pCBlock := dc_pIOQueueTail1
                            (*ENDIF*) 
                            END
                        (*ENDIF*) 
                    (*ENDIF*) 
                    END
                (*ENDIF*) 
                END
            (*ENDWITH*) 
        (*ENDWHILE*) 
        END
    (*ENDIF*) 
    END;
(*ENDWITH*) 
(* *)
vendexcl (TaskId, g08data1 + RegOffset);
(* *)
FOR Index := 1 TO FlushElems DO
    WITH CBlockList.cbl_pCBlock_bd02 [Index]^  DO
        bd73DataIOStatistic (dcb_pFrame_bd02^.nd_level, dcb_tfn,
              NOT IS_VIRTUAL_IO_BD20, NOT IS_READ_IO_BD20);
    (*ENDWITH*) 
(*ENDFOR*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      bd20ProtectDataCacheFrames (
            TaskId : tsp00_TaskId;
            Enable : boolean);
 
CONST
      msgEnable  = 'ENABLE MEMORY PROTECTION                ';
      msgDisable = 'DISABLE MEMORY PROTECTION               ';
 
VAR
      RegOffset : tsp00_Int4;
      pCBlock   : tbd02_pDataCBlock;
 
BEGIN
IF  Enable
THEN
    g01optextmsg (sp3p_knldiag, sp3m_info, csp3_bd_msg, csp3_n_datacache, msgEnable)
ELSE
    g01optextmsg (sp3p_knldiag, sp3m_info, csp3_bd_msg, csp3_n_datacache, msgDisable);
(*ENDIF*) 
FOR RegOffset := 0 TO bd20RegionCount - 1 DO
    BEGIN
    (* *)
    vbegexcl (TaskId, g08data1 + RegOffset);
    (* *)
    WITH bd20DataCacheList [RegOffset] DO
        BEGIN
        IF  dc_UnMapAreaSize = 0
        THEN
            BEGIN
            pCBlock := dc_pFirstCBlock;
            WHILE  pCBlock <> NIL DO
                WITH pCBlock^ DO
                    BEGIN
                    IF  dcb_pFrame_bd02 <> NIL
                    THEN
                        BEGIN
                        IF  (dcb_UsageCnt_bd02 = 0) AND (dcb_io_state = iosNone_ebd02) AND Enable
                        THEN
                            bd20_ReadAccessToFrame (
                                  bd20DataCacheList [RegOffset], dcb_pFrame_bd02)
                        ELSE
                            bd20_ReadWriteAccessToFrame (
                                  bd20DataCacheList [RegOffset], dcb_pFrame_bd02);
                        (*ENDIF*) 
                        END;
                    (*ENDIF*) 
                    pCBlock := pCBlock^.dcb_FixedNext_bd02
                    END;
                (*ENDWITH*) 
            (*ENDWHILE*) 
            dc_MemoryProtection := Enable;
            END
        (*ENDIF*) 
        END;
    (*ENDWITH*) 
    (* *)
    vendexcl (TaskId, g08data1 + RegOffset);
    (* *)
    END
(*ENDFOR*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      bd20PrepareSavepoint (
            TaskId           : tsp00_TaskId;
            ConverterVersion : tsp00_Int4);
 
VAR
      RegOffset : tsp00_Int4;
 
BEGIN
g01opmsg (sp3p_knldiag, sp3m_info, csp3_b20_prepare_savepoint,
      csp3_n_savepoint, 'B20PREPARE_SVP          ', ConverterVersion);
(* *)
FOR RegOffset := 0 TO bd20RegionCount - 1 DO
    vbegexcl (TaskId, g08data1 + RegOffset);
(*ENDFOR*) 
(* *)
FOR RegOffset := 0 TO bd20RegionCount - 1 DO
    bd20prepare_savepoint (RegOffset);
(*ENDFOR*) 
(* *)
FOR RegOffset := bd20RegionCount - 1 DOWNTO 0 DO
    vendexcl (TaskId, g08data1 + RegOffset);
(*ENDFOR*) 
(* *)
END;
 
(*------------------------------*) 
 
PROCEDURE
      bd20prepare_savepoint (RegOffset : tsp00_Int4);
 
CONST
      MSG_NOT_ACTIVE     = 'Is not active           ';
      MSG_ELEMS_EXIST    = 'SVP Elems exist         ';
      MSG_QUEUE_1_EMPTY  = 'I/O QUEUE1 is not empty ';
      MSG_QUEUE_2_EMPTY  = 'I/O QUEUE2 is not empty ';
      MSG_ITEM_UNCHANGED = 'IOQueue Item not changed';
 
VAR
      pCBlock : tbd02_pDataCBlock;
 
BEGIN
WITH bd20DataCacheList[ RegOffset ] DO
    BEGIN
    IF  NOT dc_SegmentActive
    THEN
        g01abort (csp3_bd_msg, csp3_n_datacache, MSG_NOT_ACTIVE, 0);
    (*ENDIF*) 
    IF  0 <> dc_SVPElems
    THEN
        g01abort (BD20_SVP_ITEMS_EXIST_SP03, csp3_n_datacache, MSG_ELEMS_EXIST, dc_SVPElems);
    (*ENDIF*) 
    dc_SVPActive := true;
    dc_IOSwitch  := NOT dc_IOSwitch;
    dc_SVPElems  := 0;
    IF  dc_IOSwitch
    THEN
        BEGIN
        pCBlock := dc_pIOQueueHead1;
        IF  (NIL <> dc_pIOQueueHead2) OR (NIL <> dc_pIOQueueTail2)
        THEN
            g01abort (BD20_IO_QUEUE_IS_NOT_EMPTY_SP03, csp3_n_datacache, MSG_QUEUE_2_EMPTY, 0);
        (*ENDIF*) 
        END
    ELSE
        BEGIN
        pCBlock := dc_pIOQueueHead2;
        IF  (NIL <> dc_pIOQueueHead1) OR (NIL <> dc_pIOQueueTail1)
        THEN
            g01abort (BD20_IO_QUEUE_IS_NOT_EMPTY_SP03, csp3_n_datacache, MSG_QUEUE_1_EMPTY, 0 );
        (*ENDIF*) 
        END;
    (*ENDIF*) 
    WHILE (pCBlock <> NIL) DO
        BEGIN
        IF  pCBlock^.dcb_ChangedState_bd02 <> cstChanged_ebd02
        THEN
            g01abort (BD20_ITEM_NOT_CHANGED_SP03, csp3_n_datacache, MSG_ITEM_UNCHANGED, 0);
        (*ENDIF*) 
        dc_SVPElems                     := succ (dc_SVPElems);
        pCBlock^.dcb_ChangedState_bd02 := cstSvpRelevant_ebd02;
        pCBlock                        := pCBlock^.dcb_io_next
        END;
    (*ENDWHILE*) 
    IF  g01glob.datacachecheck
    THEN
        bd20check_svp_chain (bd20DataCacheList[ RegOffset ]);
    (*ENDIF*) 
    END
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      bd20RReleasePage (
            TaskId              : tsp00_TaskId;
            VAR ExclFileLockCnt : tsp00_Int2;
            VAR FileId          : tgg00_FileId;
            VAR nptr            : tbd_nodeptr;
            VAR cbptr           : tbd02_pDataCBlock;
            recMode             : tbd02_RecoveryMode;
            LruInfo             : tbd_lru_info);
 
VAR
      bFound     : boolean;
      RegOffset  : integer;
      HashIndex  : tsp00_Int4;
      there      : tbd02_pDataCBlock;
      pred       : tbd02_pDataCBlock;
 
BEGIN
RegOffset := nptr^.nd_id MOD bd20RegionCount;
IF  cbptr <> NIL
THEN
    HashIndex := c_nil_hash
ELSE
    HashIndex := nptr^.nd_id MOD bd20DataCacheList [RegOffset].dc_HeadListSize;
(*ENDIF*) 
(* *)
vbegexcl (TaskId, g08data1 + RegOffset);
(* *)
IF  bd20DataCacheList [RegOffset].dc_SegmentActive
THEN
    BEGIN
    IF  cbptr = NIL
    THEN
        bd20_SearchInChain (bd20DataCacheList [RegOffset], HashIndex,
              nptr^.nd_id, recMode, there, pred, bFound)
    ELSE
        BEGIN
        IF  cbptr^.dcb_occupant <> nptr^.nd_id
        THEN
            bd20_Abort (FileId, csp3_b20x5_pno_not_found,
                  'Occup <> Id ', nptr^.nd_id, cbptr);
        (*ENDIF*) 
        there  := cbptr;
        bFound := true;
        pred   := NIL
        END;
    (*ENDIF*) 
    IF  bFound
    THEN
        WITH bd20DataCacheList [RegOffset], there^ DO
            BEGIN
            IF  dcb_UsageCnt_bd02 = 0
            THEN
                bd20_Abort (FileId, csp3_b20x1_usage_is_zero,
                      'Usage = 0   ', there^.dcb_occupant, there);
            (* *)
            (*ENDIF*) 
            dcb_UsageCnt_bd02 := dcb_UsageCnt_bd02 - 1;
            IF  dcb_io_state = iosNone_ebd02
            THEN
                dcb_LastOwner_bd02 := dcb_LastOwner_bd02 - TaskId; (* PTS 1124301 *)
            (* *)
            (*ENDIF*) 
            IF  dcb_UsageCnt_bd02 = 0
            THEN
                BEGIN
                IF  (dcb_lock_req_head <> NIL)
                THEN
                    bd20_ResumeLockRequest (TaskId, bd20DataCacheList [RegOffset],
                          there, NOT RESUME_ALL_BD20);
                (*ENDIF*) 
                IF  (dc_pOverflowTaskQueue <> NIL)
                THEN
                    bd20_ResumeOverflow (bd20DataCacheList [RegOffset], 1);
                (*ENDIF*) 
                IF  dcb_ExclusiveLocked_bd02
                THEN
                    BEGIN
                    dcb_ExclusiveLocked_bd02 := false;
                    dc_NumSplitLocks         := dc_NumSplitLocks - 1;
                    ExclFileLockCnt          := ExclFileLockCnt - 1;
                    END;
                (*ENDIF*) 
                dcb_LastOwner_bd02 := cgg_nil_pid; (* PTS 1124301 *)
                IF  dcb_io_state = iosBlocked_ebd02
                THEN
                    dcb_io_state := iosNone_ebd02;
                (*ENDIF*) 
                END;
            (*ENDIF*) 
            IF  (dcb_IsSourceOfACopy_bd02                     ) AND
                (dcb_UsageCnt_bd02 = 0                        ) AND
                (dcb_io_state = iosNone_ebd02                 ) AND
                (dcb_ChangedState_bd02 <> cstSvpRelevant_ebd02)
            THEN (* -> COULD NOT HAPPEN ? *)
                bd20_FreeCBlock (bd20DataCacheList [RegOffset], HashIndex, pred, there)
            ELSE
                BEGIN
                IF  (g01default_lru               ) AND
                    (LruInfo <> lru_normal        ) AND
                    (dcb_UsageCnt_bd02 = 0        ) AND
                    (there <> dc_pLastLRU         ) AND
                    (dc_FreeCount < dc_RecAreaSize) AND
                    (dc_UnMapAreaSize = 0         )
                THEN
                    IF  LruInfo = lru_last
                    THEN
                        bd20_PutLastLRUList (bd20DataCacheList [RegOffset], there)
                    ELSE
                        bd20_PutMidLRUList (bd20DataCacheList [RegOffset], there)
                    (*ENDIF*) 
                (*ENDIF*) 
                END;
            (*ENDIF*) 
            IF  bd20DataCacheList [RegOffset].dc_MemoryProtection
            THEN
                BEGIN
                IF  (dcb_UsageCnt_bd02 = 0) AND (dcb_io_state = iosNone_ebd02)
                THEN
                    bd20_ReadAccessToFrame (bd20DataCacheList [RegOffset], nptr);
                (*ENDIF*) 
                END;
            (*ENDIF*) 
            IF  g01glob.datacachecheck
&               ifdef TEST_AWE
                OR
                (dc_UnMapAreaSize > 0)
&               endif
            THEN
                bd20_CheckLRUList (bd20DataCacheList [RegOffset])
            (*ENDIF*) 
            END
        (*ENDWITH*) 
    (*ENDIF*) 
    END;
(* *)
(*ENDIF*) 
vendexcl (TaskId, g08data1 + RegOffset);
(* *)
nptr  := NIL;
cbptr := NIL
END;
 
(*------------------------------*) 
 
PROCEDURE
      bd20WReleasePage (
            TaskId              : tsp00_TaskId;
            VAR FileId          : tgg00_FileId;
            VAR ExclFileLockCnt : tsp00_Int2;
            VAR nptr            : tbd_nodeptr;
            VAR cbptr           : tbd02_pDataCBlock;
            VAR IoState         : tbd02_SwapState;
            recMode             : tbd02_RecoveryMode);
 
VAR
      bFound    : boolean;
      RegOffset : integer;
      HashIndex : tsp00_Int4;
      pred      : tbd02_pDataCBlock;
      there     : tbd02_pDataCBlock;
 
BEGIN
RegOffset := nptr^.nd_id MOD bd20RegionCount;
IF  cbptr <> NIL
THEN
    HashIndex := c_nil_hash
ELSE
    HashIndex := nptr^.nd_id MOD bd20DataCacheList [RegOffset].dc_HeadListSize;
(*ENDIF*) 
(* *)
vbegexcl (TaskId, g08data1 + RegOffset);
(* *)
IF  bd20DataCacheList [RegOffset].dc_SegmentActive
THEN
    BEGIN
    IF  (cbptr <> NIL)
    THEN
        BEGIN
        IF  cbptr^.dcb_occupant <> nptr^.nd_id
        THEN
            bd20_Abort (FileId, csp3_b20x6_pno_not_found,
                  'Occup <> Id ', nptr^.nd_id, cbptr);
        (*ENDIF*) 
        there  := cbptr;
        bFound := true;
        pred   := NIL
        END
    ELSE
        BEGIN
        bd20_SearchInChain (bd20DataCacheList [RegOffset], HashIndex,
              nptr^.nd_id, recMode, there, pred, bFound);
        IF  bFound
        THEN
            cbptr := there
        ELSE
            g01abort (csp3_b20x1_pno_not_found, csp3_n_datacache,
                  'B20REL: pno not found  :', nptr^.nd_id)
        (*ENDIF*) 
        END;
    (*ENDIF*) 
    WITH bd20DataCacheList [RegOffset], there^ DO
        BEGIN
        IF  dcb_UsageCnt_bd02 = 0
        THEN
            bd20_Abort (FileId, csp3_b20x2_usage_is_zero,
                  'Usage = 0   ', nptr^.nd_id, there);
        (*ENDIF*) 
        IF  (dcb_io_state          = iosBlocked_ebd02    ) AND
            (dcb_ChangedState_bd02 = cstSvpRelevant_ebd02) AND
            (dcb_copy_no           = 0                   ) AND
            (IoState               = swsTestIo_ebd02     )
        THEN
            IoState  := swsDoIo_ebd02;
        (*ENDIF*) 
        IF  IoState  = swsIoDone_ebd02
        THEN
            BEGIN
            dcb_io_state          := iosNone_ebd02;
            dcb_ChangedState_bd02 := cstNone_ebd02;
            IF  dcb_queue_occ <> NIL
            THEN
                bd20_ResumeOccupant (bd20DataCacheList [RegOffset], MSG_WRELEASE, there);
            (*ENDIF*) 
            END;
        (*ENDIF*) 
        IF  IoState <> swsDoIo_ebd02
        THEN
            BEGIN
            (* *)
            dcb_UsageCnt_bd02 := dcb_UsageCnt_bd02 - 1;
            IF  dcb_io_state = iosNone_ebd02
            THEN
                dcb_LastOwner_bd02 := dcb_LastOwner_bd02 - TaskId; (* PTS 1124301 *)
            (* *)
            (*ENDIF*) 
            IF  (dcb_IsSourceOfACopy_bd02                     ) AND
                (dcb_UsageCnt_bd02 = 0                        ) AND
                (dcb_io_state = iosNone_ebd02                 ) AND
                (dcb_ChangedState_bd02 <> cstSvpRelevant_ebd02)
            THEN (* -> COULD NOT HAPPEN ? *)
                bd20_FreeCBlock (bd20DataCacheList [RegOffset], HashIndex, pred, there)
            ELSE
                BEGIN
                IF  dcb_UsageCnt_bd02 = 0
                THEN
                    BEGIN
                    IF  (dcb_lock_req_head <> NIL)
                    THEN
                        bd20_ResumeLockRequest (TaskId, bd20DataCacheList [RegOffset],
                              there, NOT RESUME_ALL_BD20);
                    (*ENDIF*) 
                    IF  (dc_pOverflowTaskQueue <> NIL)
                    THEN
                        bd20_ResumeOverflow (bd20DataCacheList [RegOffset], 1);
                    (*ENDIF*) 
                    IF  dcb_ExclusiveLocked_bd02
                    THEN
                        BEGIN
                        dcb_ExclusiveLocked_bd02 := false;
                        dc_NumSplitLocks         := dc_NumSplitLocks - 1;
                        ExclFileLockCnt          := ExclFileLockCnt - 1;
                        END;
                    (*ENDIF*) 
                    dcb_LastOwner_bd02 := cgg_nil_pid; (* PTS 1124301 *)
                    IF  dcb_io_state = iosBlocked_ebd02
                    THEN
                        dcb_io_state := iosNone_ebd02;
                    (*ENDIF*) 
                    END;
                (*ENDIF*) 
                IF  IoState = swsIoDone_ebd02
                THEN
                    bd20unset_changed (bd20DataCacheList [RegOffset], there)
                ELSE
                    bd20set_changed (bd20DataCacheList [RegOffset], there,
                          NOT ADD_TMP_TO_IO_CHAIN_BD20);
                (*ENDIF*) 
                END;
            (*ENDIF*) 
            IF  bd20DataCacheList [RegOffset].dc_MemoryProtection  AND (dcb_UsageCnt_bd02 = 0)
            THEN
                bd20_ReadAccessToFrame (bd20DataCacheList [RegOffset], nptr);
            (*ENDIF*) 
            END
        (*ENDIF*) 
        END
    (*ENDWITH*) 
    END;
(* *)
(*ENDIF*) 
vendexcl (TaskId, g08data1 + RegOffset);
(* *)
IF  (IoState <> swsDoIo_ebd02)
THEN
    BEGIN
    nptr  := NIL;
    cbptr := NIL
    END
(*ENDIF*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      bd20ReplaceOldOccupant (
            TaskId               : tsp00_TaskId;
            VAR TrError          : tgg00_BasisError;
            PageNo               : tsp00_PageNo;
            recMode              : tbd02_RecoveryMode;
            cbptr                : tbd02_pDataCBlock;
            setBlockedForNewNode : boolean);
 
VAR
      bFound       : boolean;
      RegOffset    : integer;
      HashIndex    : tsp00_Int4;
      OldHashIndex : tsp00_Int4;
      there        : tbd02_pDataCBlock;
 
BEGIN
bFound    := false;
RegOffset := PageNo MOD bd20RegionCount;
HashIndex := PageNo MOD bd20DataCacheList [RegOffset].dc_HeadListSize;
(* *)
vbegexcl (TaskId, g08data1 + RegOffset);
(* *)
WITH bd20DataCacheList [RegOffset] DO
    BEGIN
    IF  NOT dc_SegmentActive
    THEN
        TrError := e_shutdown
    ELSE
        BEGIN
        IF  (cbptr <> NIL                     ) AND
            (cbptr^.dcb_occupant = PageNo     ) AND
            (cbptr^.dcb_RecMode_bd02 = recMode)
        THEN
            BEGIN
            bFound := true;
            there  := cbptr;
            END
        ELSE
            BEGIN
            there := dc_pHeadList^ [HashIndex].he_cb;
            IF  there <> NIL
            THEN
                REPEAT
                    WITH there^ DO
                        BEGIN
                        IF  (dcb_occupant  = PageNo    ) AND
                            (dcb_RecMode_bd02 = recMode)
                        THEN
                            bFound := true
                        ELSE
                            there := dcb_VarNext_bd02
                        (*ENDIF*) 
                        END
                    (*ENDWITH*) 
                UNTIL
                    bFound OR (there = NIL);
                (*ENDREPEAT*) 
            (*ENDIF*) 
            END;
        (*ENDIF*) 
        IF  NOT  bFound
        THEN
            g01abort (csp3_b20x3_pno_not_found, csp3_n_datacache,
                  'B20REP: pno not found   ', PageNo)
        ELSE
            WITH there^ DO
                BEGIN
                OldHashIndex         := dcb_OldOccupant_bd02 MOD dc_HeadListSize;
                dcb_OldOccupant_bd02 := NIL_PAGE_NO_GG00;
                dcb_OldRecMode_bd02  := rmTemp_ebd02;
                IF  setBlockedForNewNode
                THEN
                    BEGIN
                    dcb_io_state       := iosBlocked_ebd02;
                    dcb_LastOwner_bd02 := TaskId;
                    dcb_UsageCnt_bd02  := 1; (* PTS 1124301 *)
                    END;
                (*ENDIF*) 
                dcb_ChangedState_bd02 := cstNone_ebd02;
                IF  dcb_queue_old_occ <> NIL
                THEN
                    bd20_ResumeOldOccupant (bd20DataCacheList [RegOffset], MSG_REPLACE, there);
                (*ENDIF*) 
                WITH  dc_pHeadList^ [OldHashIndex] DO
                    BEGIN
                    he_old_occ_cnt   := he_old_occ_cnt - 1;
                    dc_OldOccupants  := dc_OldOccupants - 1;
                    IF  he_old_occ_cnt < 0
                    THEN
                        he_old_occ_cnt := 0;
                    (*ENDIF*) 
                    IF  dc_OldOccupants < 0
                    THEN
                        dc_OldOccupants := 0
                    (*ENDIF*) 
                    END
                (*ENDWITH*) 
                END
            (*ENDWITH*) 
        (*ENDIF*) 
        END
    (*ENDIF*) 
    END;
(*ENDWITH*) 
(* *)
vendexcl (TaskId, g08data1 + RegOffset);
(* *)
END;
 
(*------------------------------*) 
 
PROCEDURE
      bd20SetPreventSplit (TaskId : tsp00_TaskId);
 
BEGIN
bd20_SetPreventSplit( TaskId, true );
END;
 
(*------------------------------*) 
 
PROCEDURE
      bd20UnSetPreventSplit (TaskId : tsp00_TaskId);
 
BEGIN
bd20_SetPreventSplit( TaskId, false );
END;
 
(*------------------------------*) 
 
PROCEDURE
      bd20ShutdownDataCache (
            TaskId             : tsp00_TaskId;
            emergency_shutdown : boolean);
 
VAR
      RegOffset : integer;
      pCBlock   : tbd02_pDataCBlock;
      p         : b20ptr;
 
BEGIN
FOR RegOffset := 0 TO bd20RegionCount - 1 DO
    BEGIN
    (* *)
    vbegexcl (TaskId, g08data1 + RegOffset);
    (* *)
    WITH bd20DataCacheList [RegOffset] DO
        BEGIN
        dc_SegmentActive := false;
        pCBlock          := dc_pFirstCBlock;
        WHILE pCBlock <> NIL DO
            BEGIN
            WITH pCBlock^  DO
                BEGIN
                IF  bd20DataCacheList [RegOffset].dc_MemoryProtection
                THEN
                    bd20_ReadWriteAccessToFrame (bd20DataCacheList [RegOffset], dcb_pFrame_bd02);
                (*ENDIF*) 
                IF  ((dcb_pFrame_bd02 <> NIL) AND (NOT emergency_shutdown))
                THEN
                    BEGIN
                    bd999ReleaseFrame( TaskId, dcb_pFrame_bd02 );
                    dcb_pFrame_bd02 := NIL;
                    END
                ELSE
                    IF  (dcb_pFrame_bd02 = NIL) AND (dc_UnMapAreaSize > 0)
                    THEN
                        BEGIN
&                       ifdef AWE_USAGE
                        IF  (dcb_AWE_BlockNo_bd02 <> NIL_AWE_HANDLE_BD20)
                        THEN
                            RTEMem_AWEReleasePhysPage( dcb_AWE_BlockNo_bd02 );
&                       endif
                        (*ENDIF*) 
                        END;
                    (*ENDIF*) 
                (*ENDIF*) 
                IF  dcb_queue_occ <> NIL
                THEN
                    bd20_ResumeOccupant (bd20DataCacheList [RegOffset], MSG_SHUTDOWN, pCBlock);
                (*ENDIF*) 
                IF  dcb_queue_old_occ <> NIL
                THEN
                    bd20_ResumeOldOccupant (bd20DataCacheList [RegOffset], MSG_SHUTDOWN, pCBlock);
                (*ENDIF*) 
                IF  (dcb_lock_req_head <> NIL)
                THEN
                    bd20_ResumeLockRequest (TaskId, bd20DataCacheList [RegOffset],
                          pCBlock, RESUME_ALL_BD20);
                (*ENDIF*) 
                dcb_occupant         := NIL_PAGE_NO_GG00;
                dcb_OldOccupant_bd02 := NIL_PAGE_NO_GG00;
&               ifdef AWE_USAGE
                dcb_AWE_BlockNo_bd02 := NIL_AWE_HANDLE_BD20;
&               endif
                END;
            (*ENDWITH*) 
            pCBlock := pCBlock^.dcb_FixedNext_bd02
            END;
        (*ENDWHILE*) 
        (* *)
        (* --- WAKE UP TASKS FROM OVERLOW QUEUE --- *)
        (* *)
        bd20_ResumeOverflow (bd20DataCacheList [RegOffset], MAX_INT4_SP00);
        (* *)
        IF  NOT emergency_shutdown
        THEN
            BEGIN
            (* *)
            (* --- SET DATA CACHE SEGMENT SIZE TO ZERO --- *)
            (* *)
            dc_SegmentSize := 0;
            (* *)
            (* --- FREE CONTROL BLOCK MEMORY -- *)
            (* *)
            vmfree( dc_pFirstCBlock );
            dc_pFirstCBlock := NIL;
            (* *)
            (* --- FREE HEADLIST MEMORY -- *)
            (* *)
            p.aux_hl_addr := dc_pHeadList;
            vmfree( p.cblockaddr );
            dc_pHeadList := NIL;
            (* dc_HeadListSize := 0; *)
            (* Do not set the Size to zero, because the following line of code *)
            (* HashIndex := PageNo MOD dc_HeadListSize is not protected by a   *)
            (* datacache region to raise performance. So the modulo always     *)
            (* works but the subsequent call of dc_SegmentActive == TRUE will  *)
            (* fail in case of an shutdown.                                    *)
            (* *)
            (* --- FREE TASK QUEUE MEMORY -- *)
            (* *)
            p.pid_queue_addr := dc_pTaskQueueHead;
            vmfree( p.cblockaddr );
            dc_pTaskQueueHead := NIL;
            END
        (*ENDIF*) 
        END;
    (*ENDWITH*) 
    (* *)
    vendexcl (TaskId, g08data1 + RegOffset);
    (* *)
&   ifdef AWE_USAGE
    IF  RTEMem_AWEAvailable
    THEN
        bd20_ShutdownAWEFramePool (TaskId);
&   endif
    (*ENDIF*) 
    END
(*ENDFOR*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      bd20UsePage (
            TaskId        : tsp00_TaskId;
            VAR TrError   : tgg00_BasisError;
            PageNo        : tsp00_PageNo;
            recMode       : tbd02_RecoveryMode;
            cbptr         : tbd02_pDataCBlock;
            NodeRequest   : tbd_node_request;
            VAR nptr      : tbd_nodeptr);
 
VAR
      bFound     : boolean;
      RegOffset : integer;
      HashIndex : tsp00_Int4;
      there     : tbd02_pDataCBlock;
 
BEGIN
bFound    := false;
RegOffset := PageNo MOD bd20RegionCount;
HashIndex := PageNo MOD bd20DataCacheList [RegOffset].dc_HeadListSize;
(* *)
vbegexcl (TaskId, g08data1 + RegOffset);
(* *)
WITH bd20DataCacheList [RegOffset] DO
    BEGIN
    IF  NOT dc_SegmentActive
    THEN
        TrError := e_shutdown
    ELSE
        BEGIN
        IF  (cbptr <> NIL                     ) AND
            (cbptr^.dcb_occupant = PageNo     ) AND
            (cbptr^.dcb_RecMode_bd02 = recMode)
        THEN
            BEGIN
            bFound := true;
            there := cbptr
            END
        ELSE
            BEGIN
            there := dc_pHeadList^ [HashIndex].he_cb;
            IF  there <> NIL
            THEN
                REPEAT
                    WITH there^ DO
                        BEGIN
                        IF  (dcb_occupant = PageNo     ) AND
                            (dcb_RecMode_bd02 = recMode)
                        THEN
                            bFound := true
                        ELSE
                            there := dcb_VarNext_bd02
                        (*ENDIF*) 
                        END
                    (*ENDWITH*) 
                UNTIL
                    bFound OR (there = NIL);
                (*ENDREPEAT*) 
            (*ENDIF*) 
            END;
        (*ENDIF*) 
        IF  NOT  bFound
        THEN
            g01abort (csp3_b20x4_pno_not_found, csp3_n_datacache,
                  'B20USE: pno not found   ', PageNo);
        (*ENDIF*) 
        WITH there^ DO
            BEGIN
            IF  TrError = e_bd_leaf_unlocked
            THEN
                BEGIN
                dcb_LastOwner_bd02 := cgg_nil_pid; (* PTS 1124301 *)
                dcb_UsageCnt_bd02  := 0;
                nptr               := NIL
                END
            ELSE
                BEGIN
                dcb_LastOwner_bd02 := TaskId;
                dcb_UsageCnt_bd02  := 1;
                nptr               := dcb_pFrame_bd02
                END;
            (*ENDIF*) 
            IF  NodeRequest = nr_for_update
            THEN
                dcb_io_state := iosBlocked_ebd02
            ELSE
                dcb_io_state := iosNone_ebd02;
            (*ENDIF*) 
            IF  NodeRequest = nr_for_upd_ret_if_blocked
            THEN
                BEGIN
                (* Reason: devspace balancing *)
                bd20set_changed (bd20DataCacheList [RegOffset], there,
                      ADD_TMP_TO_IO_CHAIN_BD20);
                dcb_UsageCnt_bd02  := 0;
                dcb_LastOwner_bd02 := cgg_nil_pid; (* PTS 1124301 *)
                nptr               := NIL
                END
            ELSE
                bd20unset_changed (bd20DataCacheList [RegOffset], there);
            (*ENDIF*) 
            IF  dcb_queue_occ <> NIL
            THEN
                bd20_ResumeOccupant (bd20DataCacheList [RegOffset], MSG_USE_PAGE, there);
            (*ENDIF*) 
            END
        (*ENDWITH*) 
        END
    (*ENDIF*) 
    END;
(*ENDWITH*) 
(* *)
vendexcl (TaskId, g08data1 + RegOffset);
(* *)
END;
 
(*------------------------------*) 
 
PROCEDURE
      bd20add_to_chain (VAR datacache : t_datacache;
            HashIndex : tsp00_Int4;
            there     : tbd02_pDataCBlock);
 
BEGIN
WITH datacache DO
    BEGIN
    there^.dcb_VarNext_bd02         := dc_pHeadList^ [HashIndex].he_cb;
    dc_pHeadList^ [HashIndex].he_cb := there
    END
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      bd20_FreeCBlock (
            VAR DataCache : t_datacache;
            HashIndex     : integer;
            pPrevCBlock   : tbd02_pDataCBlock;
            pCBlock       : tbd02_pDataCBlock);
 
VAR
&     ifdef AWE_USAGE
      bUseAuxBuffer    : boolean;
&     endif
      ConverterVersion : tsp00_Int4;
      pCurrCBlock      : tbd02_pDataCBlock;
 
BEGIN
WITH DataCache DO
    BEGIN
    bd20_DelFromLRUList (DataCache, pCBlock);
    WITH pCBlock^ DO
        BEGIN
        IF  (dcb_queue_occ <> NIL    ) OR (dcb_queue_old_occ <> NIL) OR
            (dcb_lock_req_head <> NIL) OR (dcb_lock_req_tail <> NIL)
        THEN
            bd20_Abort2 (csp3_b20x1_pid_queue_not_empty, 'TaskQ <> 0  ', dcb_occupant, pCBlock);
        (*ENDIF*) 
        IF  DataCache.dc_MemoryProtection
        THEN
            bd20_ReadWriteAccessToFrame (DataCache, dcb_pFrame_bd02);
        (*ENDIF*) 
        IF  (HashIndex = c_nil_hash) OR dcb_IsSourceOfACopy_bd02
        THEN
            BEGIN
            HashIndex := dcb_occupant MOD dc_HeadListSize;
            IF  dc_pHeadList^ [HashIndex].he_cb <> pCBlock
            THEN
                BEGIN
                pCurrCBlock := dc_pHeadList^ [HashIndex].he_cb;
                (* *)
&               ifdef AWE_USAGE
                bUseAuxBuffer := (dcb_pFrame_bd02 = NIL);
                IF  bUseAuxBuffer
                THEN
                    bd20_MapAuxBuffer( DataCache, dcb_AWE_BlockNo_bd02, dcb_pFrame_bd02 );
                (*ENDIF*) 
                ConverterVersion := dcb_pFrame_bd02^.nd_conv_version;
                IF  bUseAuxBuffer
                THEN
                    bd20_UnMapAuxBuffer( DataCache, dcb_pFrame_bd02 );
&               else
                (*ENDIF*) 
                ConverterVersion := dcb_pFrame_bd02^.nd_conv_version;
&               endif
                (* *)
                REPEAT
                    IF  (pCurrCBlock^.dcb_occupant       = dcb_occupant  ) AND
                        (pCurrCBlock^.dcb_RecMode_bd02 = dcb_RecMode_bd02) AND
                        (dcb_IsSourceOfACopy_bd02                        )
                    THEN
                        BEGIN
                        IF  pCurrCBlock^.dcb_copy_no = 0
                        THEN
                            bd20_Abort2( csp3_b20x1_copy_no_not_zero, 'CopyNo = 0  ',
                                  dcb_occupant, pCurrCBlock);
&                       ifdef AWE_USAGE
                        (*ENDIF*) 
                        bUseAuxBuffer := (pCurrCBlock^.dcb_pFrame_bd02 = NIL);
                        IF  bUseAuxBuffer
                        THEN
                            bd20_MapAuxBuffer( DataCache, pCurrCBlock^.dcb_AWE_BlockNo_bd02,
                                  pCurrCBlock^.dcb_pFrame_bd02 );
&                       endif
                        (*ENDIF*) 
                        IF  DataCache.dc_MemoryProtection
                        THEN
                            bd20_ReadWriteAccessToFrame (DataCache, pCurrCBlock^.dcb_pFrame_bd02);
                        (*ENDIF*) 
                        pCurrCBlock^.dcb_pFrame_bd02^.nd_conv_version := ConverterVersion;
                        pCurrCBlock^.dcb_copy_no                      := pCurrCBlock^.dcb_copy_no - 1;
                        IF  DataCache.dc_MemoryProtection
                        THEN
                            BEGIN
                            IF  (pCurrCBlock^.dcb_UsageCnt_bd02 = 0) AND (pCurrCBlock^.dcb_io_state = iosNone_ebd02)
                            THEN
                                bd20_ReadAccessToFrame (DataCache, pCurrCBlock^.dcb_pFrame_bd02);
                            (*ENDIF*) 
                            END;
&                       ifdef AWE_USAGE
                        (*ENDIF*) 
                        IF  bUseAuxBuffer
                        THEN
                            bd20_UnMapAuxBuffer( DataCache, pCurrCBlock^.dcb_pFrame_bd02 );
&                       endif
                        (*ENDIF*) 
                        END;
                    (*ENDIF*) 
                    IF  pCurrCBlock^.dcb_VarNext_bd02 = pCBlock
                    THEN
                        pPrevCBlock := pCurrCBlock;
                    (*ENDIF*) 
                    pCurrCBlock := pCurrCBlock^.dcb_VarNext_bd02;
                UNTIL
                    pCurrCBlock = pCBlock
                (*ENDREPEAT*) 
                END
            (*ENDIF*) 
            END;
        (*ENDIF*) 
        bd20unset_changed (DataCache, pCBlock);
        bd20_DecrementWorkloadCounter (DataCache, dcb_tfn); (* CR 1105627 TS 2000-02-15 *)
        IF  (dcb_UsageCnt_bd02 = 0) AND (dcb_LastOwner_bd02 <> cgg_nil_pid)
        THEN
            bd20_Abort2 (csp3_bd_msg, 'TaskId <> 0 ', pCBlock^.dcb_occupant, pCBlock);
        (*ENDIF*) 
        dcb_Init_bd02            := bd20CBlockInit;
        IF  dcb_pFrame_bd02 <> NIL
        THEN
            dcb_pFrame_bd02^.nd_root := NIL_PAGE_NO_GG00;
        (*ENDIF*) 
        END;
    (*ENDWITH*) 
    bd20del_from_chain (DataCache, HashIndex, pCBlock, pPrevCBlock);
    bd20_FreeFrame (DataCache, pCBlock)
    END
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      bd20_CheckLRUList( VAR DataCache : t_datacache );
 
VAR
      bEnterIOArea      : boolean;
      bEnterRechainArea : boolean;
      bEnterUnMapArea   : boolean;
      bFound            : boolean;
      CBlocksInUse      : tsp00_Int4;
      LoopCount         : tsp00_Int4;
      pCBlock           : tbd02_pDataCBlock;
      pAux1CBlock       : tbd02_pDataCBlock;
      pAux2CBlock       : tbd02_pDataCBlock;
 
BEGIN
WITH DataCache DO
    BEGIN
    LoopCount         := 0;
    CBlocksInUse      := dc_SegmentSize - dc_FreeCount - dc_UnMapFreeCount;
    bEnterIOArea      := false;
    bEnterRechainArea := false;
    pCBlock           := dc_pFirstLRU;
    IF  dc_pFirstLRU <> NIL
    THEN
        BEGIN
        bEnterUnMapArea  := dc_pFirstLRU^.dcb_pFrame_bd02 = NIL;
        IF  dc_pFirstLRU^.dcb_lru_prev <> NIL
        THEN
            bd20_Abort2 (csp3_b20x2_check_lru, 'Wrong LRUFst',
                  dc_pFirstLRU^.dcb_occupant, dc_pFirstLRU);
        (*ENDIF*) 
        END
    ELSE
        bEnterUnMapArea := false;
    (*ENDIF*) 
    IF  dc_pLastLRU <> NIL
    THEN
        IF  dc_pLastLRU^.dcb_lru_next <> NIL
        THEN
            bd20_Abort2( csp3_b20x2_check_lru, 'Wrong LRULst',
                  dc_pLastLRU^.dcb_occupant, dc_pLastLRU);
        (*ENDIF*) 
    (*ENDIF*) 
    IF  (dc_FreeCount + dc_UnMapFreeCount) <= dc_IOAreaSize
    THEN
        BEGIN
        bd20_AssertState( ASSERT_ID_16_BD20, dc_SegmentId, dc_pIOMid <> NIL );
        bd20_AssertState( ASSERT_ID_17_BD20, dc_SegmentId, NOT dc_pIOMid^.dcb_lru_prev^.dcb_dw_io_area );
        IF  dc_pIOMid^.dcb_lru_next <> NIL
        THEN
            bd20_AssertState( ASSERT_ID_18_BD20, dc_SegmentId, dc_pIOMid^.dcb_lru_next^.dcb_dw_io_area );
        (*ENDIF*) 
        END
    ELSE
        bd20_AssertState( ASSERT_ID_15_BD20, dc_SegmentId, dc_pIOMid = NIL );
    (*ENDIF*) 
    IF  (dc_SegmentSize - dc_UnMapAreaSize) = dc_FreeCount
    THEN
        bd20_AssertState( ASSERT_ID_8_BD20, dc_SegmentId, dc_pLastMappedCBlock = NIL )
    ELSE
        BEGIN
        IF  dc_UnMapAreaSize > 0
        THEN
            BEGIN
            bd20_AssertState( ASSERT_ID_13_BD20, dc_SegmentId, dc_pLastMappedCBlock <> NIL );
            bd20_AssertState( ASSERT_ID_14_BD20, dc_SegmentId, dc_pLastMappedCBlock^.dcb_pFrame_bd02 <> NIL )
            END
        (*ENDIF*) 
        END;
    (*ENDIF*) 
&   if $KIND = SLOW
    WHILE( pCBlock <> NIL ) DO
        WITH pCBlock^ DO
            BEGIN
            IF  dcb_lru_next <> NIL
            THEN
                IF  dcb_lru_next^.dcb_lru_prev <> pCBlock
                THEN
                    bd20_Abort2( csp3_b20x1_check_lru, 'Prev != Next',
                          dcb_occupant, pCBlock );
                (*ENDIF*) 
            (*ENDIF*) 
            IF  (
                (bEnterIOArea AND NOT dcb_dw_io_area) OR
                (NOT bEnterIOArea AND dcb_dw_io_area)
                )
            THEN
                bd20_Abort2( csp3_b20x2_check_lru,
                      'Wrong IOMid ', dcb_occupant, pCBlock);
            (*ENDIF*) 
            IF  (
                (bEnterRechainArea AND NOT dcb_lru_rechain) OR
                (NOT bEnterRechainArea AND dcb_lru_rechain)
                )
            THEN
                bd20_Abort2( csp3_b20x2_check_lru,
                      'Wrong Mid   ', dcb_occupant, pCBlock);
            (*ENDIF*) 
            IF  (
                (bEnterUnMapArea AND (dcb_pFrame_bd02 <> NIL) AND
                (dcb_io_state <> iosServerIO_ebd02))
                OR
                (NOT bEnterUnMapArea AND (dcb_pFrame_bd02 = NIL))
                )
            THEN
                bd20_Abort2( csp3_b20x2_check_lru,
                      'Wrong MapMid', dcb_occupant, pCBlock);
            (*ENDIF*) 
            IF  bEnterUnMapArea AND
                (
                (dcb_UsageCnt_bd02 <> 0) OR (dcb_io_state = iosBlocked_ebd02)
                )
            THEN
                bd20_Abort2( csp3_b20x2_check_lru,
                      'Wrong state ', dcb_occupant, pCBlock);
            (*ENDIF*) 
            bEnterIOArea      := bEnterIOArea OR ( pCBlock = dc_pIOMid );
            bEnterRechainArea := bEnterRechainArea OR ( pCBlock = dc_pMid );
            bEnterUnMapArea   := bEnterUnMapArea OR ( pCBlock = dc_pLastMappedCBlock );
            (* *)
            bd20_SearchInChain( DataCache, ( dcb_occupant MOD dc_HeadListSize ), dcb_occupant,
                  dcb_RecMode_bd02, pAux1CBlock, pAux2CBlock, bFound );
            IF  NOT bFound
            THEN
                g01abort (csp3_bd_msg, csp3_n_datacache, MSG_CBLOCK_NOT_FOUND, dcb_occupant);
            (*ENDIF*) 
            IF  LoopCount > CBlocksInUse
            THEN
                g01abort (csp3_bd_msg, csp3_n_datacache, MSG_LOOP_OVERFLOW,
                      dc_pFirstLRU^.dcb_occupant MOD bd20RegionCount);
            (*ENDIF*) 
            LoopCount := LoopCount + 1;
            pCBlock   := pCBlock^.dcb_lru_next;
            END;
        (*ENDWITH*) 
    (*ENDWHILE*) 
    bd20_CheckFreeList( DataCache );
&   endif
    END
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      bd20_CheckFreeList( VAR DataCache : t_datacache );
 
VAR
      pCBlock : tbd02_pDataCBlock;
 
BEGIN
WITH  DataCache DO
    BEGIN
    pCBlock := dc_pFreeList;
    WHILE (pCBlock <> NIL) DO
        BEGIN
        IF  pCBlock^.dcb_pFrame_bd02 = NIL
        THEN
            bd20_Abort2( csp3_b20x1_check_lru,
                  'Frame = NIL ', pCBlock^.dcb_occupant, pCBlock );
        (*ENDIF*) 
        pCBlock := pCBlock^.dcb_VarNext_bd02;
        END;
    (*ENDWHILE*) 
    pCBlock := dc_pUnMapFreeList;
    WHILE (pCBlock <> NIL) DO
        BEGIN
        IF  pCBlock^.dcb_pFrame_bd02 <> NIL
        THEN
            bd20_Abort2( csp3_b20x1_check_lru,
                  'Frame <> NIL', pCBlock^.dcb_occupant, pCBlock );
        (*ENDIF*) 
        pCBlock := pCBlock^.dcb_VarNext_bd02;
        END
    (*ENDWHILE*) 
    END
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      bd20check_io_chain (VAR datacache : t_datacache);
 
VAR
      curr_block : tbd02_pDataCBlock;
 
BEGIN
&ifdef TESTONLY
WITH datacache DO
    BEGIN
    curr_block := dc_pFirstCBlock;
    WHILE (curr_block <> NIL) DO
        BEGIN
        IF  (curr_block^.dcb_ChangedState_bd02 <> cstNone_ebd02)
            AND
            (rmTemp_ebd02 <> curr_block^.dcb_RecMode_bd02)
        THEN
            BEGIN
            IF  NOT bd20check_io_chain3 (datacache, dc_pIOQueueHead1,
                curr_block)
            THEN
                IF  NOT bd20check_io_chain3 (datacache,
                    dc_pIOQueueHead2, curr_block)
                THEN
                    bd20_Abort2 (csp3_b20x2_check, 'IOCHAIN err ',
                          curr_block^.dcb_occupant,  curr_block);
                (*ENDIF*) 
            (*ENDIF*) 
            END;
        (*ENDIF*) 
        curr_block := curr_block^.dcb_FixedNext_bd02
        END
    (*ENDWHILE*) 
    END;
(*ENDWITH*) 
&endif
END;
 
&ifdef TESTONLY
(*------------------------------*) 
 
FUNCTION
      bd20check_io_chain3 (datacache : t_datacache;
            curr_io_ptr : tbd02_pDataCBlock;
            curr_block  : tbd02_pDataCBlock) : boolean;
 
VAR
      bFound        : boolean;
      io_chain_cnt : tsp00_Int4;
      prev_io_ptr  : tbd02_pDataCBlock;
 
BEGIN
bFound        := false;
io_chain_cnt := 0;
prev_io_ptr  := NIL;
WHILE NOT bFound                      AND
      (io_chain_cnt <= datacache.dc_SegmentSize - 1) AND
      (curr_io_ptr  <> NIL)          DO
    BEGIN
    IF  (prev_io_ptr <> curr_io_ptr^.dcb_io_prev)
    THEN
        bd20_Abort2 (csp3_b20x3_check, 'IOCHAIN err ', 0, curr_io_ptr);
    (*ENDIF*) 
    IF  (curr_io_ptr = curr_block)
    THEN
        bFound := true
    ELSE
        BEGIN
        io_chain_cnt := succ (io_chain_cnt);
        prev_io_ptr  := curr_io_ptr;
        curr_io_ptr  := curr_io_ptr^.dcb_io_next
        END
    (*ENDIF*) 
    END;
(*ENDWHILE*) 
bd20check_io_chain3 := bFound
END;
 
&endif
(*------------------------------*) 
 
PROCEDURE
      bd20check_svp_chain (VAR datacache : t_datacache);
 
VAR
      curr_block   : tbd02_pDataCBlock;
      svp_elem_cnt : tsp00_Int4;
 
BEGIN
WITH datacache DO
    BEGIN
    svp_elem_cnt     := 0;
    curr_block       := dc_pFirstCBlock;
    WHILE (curr_block <> NIL) DO
        WITH curr_block^ DO
            BEGIN
            IF  (dcb_ChangedState_bd02 = cstSvpRelevant_ebd02)
                AND
                (rmTemp_ebd02 <> curr_block^.dcb_RecMode_bd02)
            THEN
                svp_elem_cnt := succ (svp_elem_cnt);
            (*ENDIF*) 
            curr_block := curr_block^.dcb_FixedNext_bd02
            END;
        (*ENDWITH*) 
    (*ENDWHILE*) 
    IF  (svp_elem_cnt <> dc_SVPElems)
    THEN
        g01abort (csp3_b20x1_check_io_cnt, csp3_n_savepoint,
              'MISMATCH SVP COUNT      ', svp_elem_cnt);
    (*ENDIF*) 
    END
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      bd20_CopyCBlock (
            TaskId         : tsp00_TaskId;
            VAR FileId     : tgg00_FileId;
            VAR DataCache  : t_datacache;
            HashIndex      : tsp00_Int4;
            pOldCBlock     : tbd02_pDataCBlock;
            VAR pNewCBlock : tbd02_pDataCBlock;
            VAR TrError    : tgg00_BasisError);
 
VAR
&     ifdef AWE_USAGE
      bUseAuxBuffer : boolean;
&     endif
      ChangedCnt    : tsp00_Int4; (* dummy *)
 
BEGIN
WITH DataCache DO
    BEGIN
    IF  pOldCBlock^.dcb_copy_no = c_max_copies
    THEN
        BEGIN
        TrError := e_sysbuffer_overflow;
        g01opmsg (sp3p_knldiag, sp3m_warning, csp3_b20_copy_overflow,
              csp3_n_datacache, 'BD20COPY:  overflow     ', 0)
        END
    ELSE
        bd20_GetFrameFromLRU (TaskId, TrError, FileId, DataCache,
              IGNORE_DIRTY_PAGES_BD20, pNewCBlock, ChangedCnt);
    (*ENDIF*) 
    IF  TrError <> e_ok
    THEN
        pNewCBlock := NIL
    ELSE
        WITH pNewCBlock^ DO
            BEGIN
            IF  dcb_io_state <> iosNone_ebd02
            THEN
                bd20_Abort (FileId, csp3_b20x1_invalid_io_state,
                      'Illeg IoStat', dcb_occupant, pNewCBlock);
&           ifdef AWE_USAGE
            (*ENDIF*) 
            bUseAuxBuffer := (pOldCBlock^.dcb_pFrame_bd02 = NIL);
            IF  bUseAuxBuffer
            THEN
                bd20_MapAuxBuffer( DataCache, pOldCBlock^.dcb_AWE_BlockNo_bd02,
                      pOldCBlock^.dcb_pFrame_bd02 );
&           endif
            (*ENDIF*) 
            IF  DataCache.dc_MemoryProtection
            THEN
                BEGIN
                bd20_ReadWriteAccessToFrame (DataCache, pOldCBlock^.dcb_pFrame_bd02);
                bd20_ReadWriteAccessToFrame (DataCache, pNewCBlock^.dcb_pFrame_bd02);
                END;
            (*ENDIF*) 
            s10mv (sizeof (pOldCBlock^.dcb_pFrame_bd02^), sizeof (dcb_pFrame_bd02^),
                  @pOldCBlock^.dcb_pFrame_bd02^, 1, @dcb_pFrame_bd02^, 1,
                  sizeof (pOldCBlock^.dcb_pFrame_bd02^));
            IF  DataCache.dc_MemoryProtection AND (pOldCBlock^.dcb_io_state = iosNone_ebd02)
            THEN
                bd20_ReadAccessToFrame (DataCache, pOldCBlock^.dcb_pFrame_bd02);
&           ifdef AWE_USAGE
            (*ENDIF*) 
            IF  bUseAuxBuffer
            THEN
                bd20_UnMapAuxBuffer( DataCache, pOldCBlock^.dcb_pFrame_bd02 );
&           endif
            (*ENDIF*) 
            dcb_occupant       := pOldCBlock^.dcb_occupant;
            dcb_tfn            := pOldCBlock^.dcb_tfn;
            dcb_RecMode_bd02   := pOldCBlock^.dcb_RecMode_bd02;
            dcb_UsageCnt_bd02  := 1;
            dcb_copy_no        := pOldCBlock^.dcb_copy_no + 1;
            dcb_io_state       := iosBlocked_ebd02;
            dcb_LastOwner_bd02 := TaskId;
            bd20add_to_chain (DataCache, HashIndex, pNewCBlock);
            dcb_lock_req_head                    := pOldCBlock^.dcb_lock_req_head;
            dcb_lock_req_tail                    := pOldCBlock^.dcb_lock_req_tail;
            pOldCBlock^.dcb_lock_req_head        := NIL;
            pOldCBlock^.dcb_lock_req_tail        := NIL;
            pOldCBlock^.dcb_IsSourceOfACopy_bd02 := true;
            IF  dcb_pFrame_bd02^.nd_header.pageCheck_gg00 <> dcb_pFrame_bd02^.nd_trailer.pageCheck_gg00
            THEN
                BEGIN
                dcb_pFrame_bd02^.nd_header.pageCheck_gg00  := chckChecksumData_egg00;
                dcb_pFrame_bd02^.nd_trailer.pageCheck_gg00 := chckChecksumData_egg00
                END
            (*ENDIF*) 
            END
        (*ENDWITH*) 
    (*ENDIF*) 
    END
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      bd20c_search_in_chain_incl_copy (
            VAR DataCache     : t_datacache;
            HashIndex         : tsp00_Int4;
            PageNo            : tsp00_PageNo;
            recMode           : tbd02_RecoveryMode;
            VAR there         : tbd02_pDataCBlock;
            VAR pred          : tbd02_pDataCBlock;
            VAR bFound        : boolean;
            VAR pSourceCBlock : tbd02_pDataCBlock);
 
VAR
      act_cbptr : tbd02_pDataCBlock;
 
BEGIN
(* search for more than one control block for a single page: *)
(* the current control block referenced by THERE and         *)
(* the control block for a copy referenced by pSourceCBlock  *)
WITH DataCache DO
    BEGIN
    bFound        := false;
    pred          := NIL;
    there         := NIL;
    pSourceCBlock := NIL;
    act_cbptr     := dc_pHeadList^ [HashIndex].he_cb;
    IF  act_cbptr <> NIL
    THEN
        REPEAT
            IF  (act_cbptr^.dcb_occupant = PageNo     ) AND
                (act_cbptr^.dcb_RecMode_bd02 = recMode)
            THEN
                IF  act_cbptr^.dcb_IsSourceOfACopy_bd02
                THEN
                    pSourceCBlock := act_cbptr
                ELSE
                    BEGIN
                    there  := act_cbptr;
                    bFound := true
                    END;
                (*ENDIF*) 
            (*ENDIF*) 
            IF  NOT bFound
            THEN
                pred := act_cbptr;
            (*ENDIF*) 
            act_cbptr := act_cbptr^.dcb_VarNext_bd02
        UNTIL
            (act_cbptr = NIL)
        (*ENDREPEAT*) 
    (*ENDIF*) 
    END
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      bd20del_from_chain (
            VAR DataCache : t_datacache;
            HashIndex     : tsp00_Int4;
            pCBlock       : tbd02_pDataCBlock;
            pPrevCBlock   : tbd02_pDataCBlock);
 
VAR
      pNextCBlock : tbd02_pDataCBlock;
 
BEGIN
WITH DataCache DO
    BEGIN
    pNextCBlock := pCBlock^.dcb_VarNext_bd02;
    IF  dc_pHeadList^ [HashIndex].he_cb = pCBlock
    THEN
        dc_pHeadList^ [HashIndex].he_cb := pNextCBlock
    ELSE
        pPrevCBlock^.dcb_VarNext_bd02 := pNextCBlock
    (*ENDIF*) 
    END
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      bd20_DelFromLRUList (
            VAR DataCache : t_datacache;
            pCBlock       : tbd02_pDataCBlock);
 
VAR
      pPrevCBlock : tbd02_pDataCBlock;
      pNextCBlock : tbd02_pDataCBlock;
 
BEGIN
WITH DataCache DO
    BEGIN
    pPrevCBlock := pCBlock^.dcb_lru_prev;
    pNextCBlock := pCBlock^.dcb_lru_next;
    IF  pPrevCBlock <> NIL
    THEN
        pPrevCBlock^.dcb_lru_next := pNextCBlock
    ELSE
        dc_pFirstLRU := pNextCBlock;
    (*ENDIF*) 
    IF  pNextCBlock <> NIL
    THEN
        pNextCBlock^.dcb_lru_prev := pPrevCBlock
    ELSE
        dc_pLastLRU := pPrevCBlock;
    (*ENDIF*) 
    IF  (NOT pCBlock^.dcb_lru_rechain) AND (dc_pMid <> NIL)
    THEN
        BEGIN
        dc_pMid := dc_pMid^.dcb_lru_next;
        IF  dc_pMid <> NIL
        THEN
            dc_pMid^.dcb_lru_rechain := false
        (*ENDIF*) 
        END;
    (*ENDIF*) 
    IF  (NOT pCBlock^.dcb_dw_io_area) AND (dc_pIOMid <> NIL)
    THEN
        BEGIN
        dc_pIOMid := dc_pIOMid^.dcb_lru_next;
        IF  dc_pIOMid <> NIL
        THEN
            dc_pIOMid^.dcb_dw_io_area := false
        (*ENDIF*) 
        END;
&   ifdef AWE_USAGE
    (*ENDIF*) 
    IF  pCBlock = dc_pLastMappedCBlock
    THEN
        BEGIN
&       ifdef TEST_AWE
        bd20_AssertState( ASSERT_ID_7_BD20, dc_SegmentId,
              dc_pLastMappedCBlock^.dcb_pFrame_bd02 <> NIL );
&       endif
        dc_pLastMappedCBlock := dc_pLastMappedCBlock^.dcb_lru_prev;
&       ifdef TEST_AWE
        IF  dc_pLastMappedCBlock <> NIL
        THEN
            bd20_AssertState( ASSERT_ID_2_BD20, dc_SegmentId,
                  dc_pLastMappedCBlock^.dcb_pFrame_bd02 <> NIL );
&       endif
        (*ENDIF*) 
        END;
&   endif
    (*ENDIF*) 
    END
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      bd20_FreeFrame (
            VAR DataCache : t_datacache;
            pCBlock       : tbd02_pDataCBlock);
 
BEGIN
WITH DataCache DO
    BEGIN
    IF  pCBlock^.dcb_pFrame_bd02 = NIL
    THEN
        BEGIN (* AWE *)
        dc_UnMapFreeCount         := dc_UnMapFreeCount + 1;
        pCBlock^.dcb_VarNext_bd02 := dc_pUnMapFreeList;
        dc_pUnMapFreeList         := pCBlock
        END
    ELSE
        BEGIN
        dc_FreeCount              := dc_FreeCount + 1;
        pCBlock^.dcb_VarNext_bd02 := dc_pFreeList;
        dc_pFreeList              := pCBlock;
        IF  DataCache.dc_MemoryProtection
        THEN
            bd20_ReadAccessToFrame (DataCache, pCBlock^.dcb_pFrame_bd02)
        (*ENDIF*) 
        END
    (*ENDIF*) 
    END;
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      bd20_GetFrameFromLRU (
            TaskId            : tsp00_TaskId;
            VAR TrError       : tgg00_BasisError;
            VAR FileId        : tgg00_FileId;
            VAR DataCache     : t_datacache;
            bIgnoreDirtyPages : boolean;
            VAR pCBlock       : tbd02_pDataCBlock;
            VAR ChangedCnt    : tsp00_Int4);
 
VAR
&     ifdef AWE_USAGE
      bFoundAWE     : boolean;
&     endif
      bFound        : boolean;
      CBlockCnt     : tsp00_Int4; (* PTS 1126174 2003-12-10 *)
      HashIndex     : tsp00_Int4;
      pPrevCBlock   : tbd02_pDataCBlock;
      pUsableCBlock : tbd02_pDataCBlock;
 
BEGIN
WITH DataCache DO
    BEGIN
    IF  dc_pFreeList <> NIL
    THEN
        BEGIN
        dc_FreeCount := dc_FreeCount - 1;
        pCBlock      := dc_pFreeList;
        dc_pFreeList := pCBlock^.dcb_VarNext_bd02;
        bd20_PutNewIntoLRUList (DataCache, pCBlock);
        bd20_IncrementWorkloadCounter (DataCache, FileId.fileTfn_gg00);
        END
    ELSE
        BEGIN
        bFound        := false;
        CBlockCnt     := 0;
        pUsableCBlock := NIL;
        IF  dc_pLastMappedCBlock <> NIL
        THEN
            pCBlock := dc_pLastMappedCBlock
        ELSE
            pCBlock := dc_pLastLRU;
        (*ENDIF*) 
        REPEAT
            WITH  pCBlock^ DO
                BEGIN
                CBlockCnt := CBlockCnt + 1;
                IF  (dcb_UsageCnt_bd02 > 0         ) OR
                    (dcb_io_state <> iosNone_ebd02 ) OR
                    (dcb_IsSourceOfACopy_bd02      ) OR
                    (dcb_copy_no > 0               ) OR
                    (dcb_lock_req_head <> NIL      ) OR
                    (
                    (dcb_ChangedState_bd02 <> cstNone_ebd02) AND
                    ((bIgnoreDirtyPages) OR (dc_SVPActive AND (dcb_RecMode_bd02 <> rmTemp_ebd02)))
                    )
                THEN
                    BEGIN
                    IF  dcb_lru_rechain AND ((dcb_UsageCnt_bd02 > 0) OR (dcb_io_state = iosUserIO_ebd02))
                    THEN
                        BEGIN
                        pPrevCBlock := dcb_lru_prev;
                        bd20_PutFirstLRUList (DataCache, pCBlock);
                        pCBlock := pPrevCBlock;
                        END
                    ELSE
                        pCBlock := dcb_lru_prev;
                    (*ENDIF*) 
                    END
                ELSE (* Usable *)
                    BEGIN
                    IF  dcb_ChangedState_bd02 <> cstChanged_ebd02
                    THEN
                        bFound := true
                    ELSE
                        BEGIN
                        IF  pUsableCBlock = NIL
                        THEN
                            pUsableCBlock := pCBlock;
                        (*ENDIF*) 
                        IF  dcb_lru_rechain
                        THEN
                            ChangedCnt := ChangedCnt + 1;
                        (*ENDIF*) 
                        pCBlock := dcb_lru_prev
                        END
                    (*ENDIF*) 
                    END
                (*ENDIF*) 
                END
            (*ENDWITH*) 
        UNTIL
            bFound OR (pCBlock = NIL) OR (CBlockCnt > dc_SegmentSize); (* PTS 1126174 2003-12-10 *)
        (*ENDREPEAT*) 
        IF  (NOT bFound) AND (pUsableCBlock <> NIL)
        THEN
            BEGIN
            pCBlock := pUsableCBlock;
            bFound  := true
            END;
        (*ENDIF*) 
        IF  NOT bFound
        THEN
            BEGIN
            IF  dc_SVPActive
            THEN
                BEGIN
                TrError := e_no_more_temp_space;
                bd20_InsertOverflow (TaskId, FileId, DataCache)
                END
            ELSE
                TrError := e_sysbuffer_overflow;
            (*ENDIF*) 
            END
        ELSE (* Found mapped CBlock *)
            BEGIN
&           ifdef AWE_USAGE
            bFoundAWE := false;
            IF  dc_UnMapAreaSize > 0
            THEN
                bd20_SearchAndUseUnMappedFrame (DataCache, pCBlock, ChangedCnt, bFoundAWE);
            (*ENDIF*) 
            IF  NOT bFoundAWE
            THEN
&               endif
                WITH pCBlock^DO
                    BEGIN
                    (* *)
                    (* use the control block from map area and not from unmap *)
                    (* because unMapArea is not 'available'.                  *)
                    (* *)
                    HashIndex  := dcb_occupant MOD dc_HeadListSize;
                    bd20_SearchInChain (DataCache, HashIndex, dcb_occupant,
                          dcb_RecMode_bd02, pCBlock, pPrevCBlock, bFound);
&                   ifdef TEST_AWE
                    IF  NOT bFound
                    THEN
                        g01abort (csp3_bd_msg, csp3_n_datacache, MSG_CBLOCK_NOT_FOUND, dcb_occupant);
&                   endif
                    (*ENDIF*) 
                    bd20del_from_chain (DataCache, HashIndex, pCBlock, pPrevCBlock);
                    bd20_DecrementWorkloadCounter (DataCache, dcb_tfn);
                    IF  dcb_lru_rechain
                    THEN
                        bd20_PutFirstLRUList (DataCache, pCBlock)
                    (*ENDIF*) 
                    END;
                (*ENDWITH*) 
            (*ENDIF*) 
            bd20_IncrementWorkloadCounter (DataCache, FileId.fileTfn_gg00);
            END
        (*ENDIF*) 
        END
    (*ENDIF*) 
    END;
(*ENDWITH*) 
END;
 
&ifdef AWE_USAGE
(*------------------------------*) 
 
PROCEDURE
      bd20_SearchAndUseUnMappedFrame (
            VAR DataCache  : t_datacache;
            VAR pCBlock    : tbd02_pDataCBlock;
            VAR ChangedCnt : tsp00_Int4;
            VAR bFound     : boolean);
 
VAR
      HashIndex      : tsp00_Int4;
      pPrevAWECBlock : tbd02_pDataCBlock;
      pUnMapCBlock   : tbd02_pDataCBlock;
 
BEGIN
(* precondition: All CBlocks in mapped area are used. *)
(* bring control block from map area to unmap area    *)
WITH DataCache DO
    BEGIN
&   ifdef TEST_AWE
    bd20_AssertState( ASSERT_ID_4_BD20, dc_SegmentId, pCBlock^.dcb_pFrame_bd02 <> NIL );
&   endif
    IF  dc_pUnMapFreeList <> NIL
    THEN
        BEGIN
&       ifdef TEST_AWE
        bd20_AssertState( ASSERT_ID_5_BD20, dc_SegmentId, dc_UnMapFreeCount > 0 );
&       endif
        bFound                        := true;
        dc_UnMapFreeCount             := dc_UnMapFreeCount - 1;
        pUnMapCBlock                  := dc_pUnMapFreeList;
        dc_pUnMapFreeList             := pUnMapCBlock^.dcb_VarNext_bd02;
        pUnMapCBlock^.dcb_pFrame_bd02 := pCBlock^.dcb_pFrame_bd02;
        bd20_PutNewIntoLRUList( DataCache, pUnMapCBlock );
        END
    ELSE
        BEGIN
&       ifdef TEST_AWE
        bd20_AssertState( ASSERT_ID_6_BD20, dc_SegmentId, dc_UnMapFreeCount = 0 );
&       endif
        bFound       := false;
        pUnMapCBlock := dc_pLastLRU;
        REPEAT
            WITH  pUnMapCBlock^ DO
                IF  (dcb_ChangedState_bd02 <> cstNone_ebd02) OR
                    (dcb_io_state          <> iosNone_ebd02) OR
                    (dcb_IsSourceOfACopy_bd02              ) OR
                    (dcb_copy_no            > 0            ) OR
                    (dcb_lock_req_head     <> NIL          )
                THEN
                    BEGIN
                    IF  (dcb_ChangedState_bd02 = cstChanged_ebd02) AND dcb_lru_rechain
                    THEN
                        ChangedCnt := ChangedCnt + 1;
                    (*ENDIF*) 
                    pUnMapCBlock := dcb_lru_prev
                    END
                ELSE
                    BEGIN
                    bFound    := true;
                    HashIndex := dcb_occupant MOD dc_HeadListSize;
                    bd20_SearchInChain (DataCache, HashIndex, dcb_occupant,
                          dcb_RecMode_bd02, pUnMapCBlock, pPrevAWECBlock, bFound);
&                   ifdef TEST_AWE
                    IF  NOT bFound
                    THEN
                        g01abort (csp3_bd_msg, csp3_n_datacache, MSG_CBLOCK_NOT_FOUND, dcb_occupant);
&                   endif
                    (*ENDIF*) 
                    bd20del_from_chain (DataCache, HashIndex, pUnMapCBlock, pPrevAWECBlock);
                    pUnMapCBlock^.dcb_pFrame_bd02 := pCBlock^.dcb_pFrame_bd02;
                    bd20_PutFirstLRUList (DataCache, pUnMapCBlock);
                    bd20_DecrementWorkloadCounter (DataCache, dcb_tfn);
                    END;
                (*ENDIF*) 
            (*ENDWITH*) 
        UNTIL
            bFound OR (pUnMapCBlock = NIL) OR (pUnMapCBlock = dc_pLastMappedCBlock);
        (*ENDREPEAT*) 
        END;
    (*ENDIF*) 
    IF  bFound
    THEN
        BEGIN
        bd20_PutFromMapToUnMapList( DataCache, pCBlock );
        RTEMem_AWEMap( pUnMapCBlock^.dcb_pFrame_bd02, pUnMapCBlock^.dcb_AWE_BlockNo_bd02 );
        pCBlock^.dcb_pFrame_bd02 := NIL;
        pCBlock                  := pUnMapCBlock;
        END
    (*ENDIF*) 
    END;
(*ENDWITH*) 
END;
 
&endif
&ifdef AWE_USAGE
(*------------------------------*) 
 
PROCEDURE
      bd20_ReMapFrame (
            TaskId        : tsp00_TaskId;
            VAR TrError   : tgg00_BasisError;
            VAR FileId    : tgg00_FileId;
            VAR DataCache : t_datacache;
            pUnMapCBlock  : tbd02_pDataCBlock);
 
VAR
      bFound        : boolean;
      CBlockCnt     : tsp00_Int4; (* PTS 1126174 2003-12-10 *)
      pCBlock       : tbd02_pDataCBlock;
      pPrevCBlock   : tbd02_pDataCBlock;
 
BEGIN
(* precondition: pUnMapCBlock points to an unmapped control block. *)
(*               Put control block from unmap area to map area.    *)
WITH DataCache DO
    BEGIN
&   ifdef TEST_AWE
    bd20_AssertState( ASSERT_ID_9_BD20, dc_SegmentId, pUnMapCBlock^.dcb_pFrame_bd02 = NIL );
&   endif
    IF  dc_pFreeList <> NIL
    THEN
        BEGIN
        bFound                    := true;
        dc_FreeCount              := dc_FreeCount - 1;
        pCBlock                   := dc_pFreeList;
        dc_pFreeList              := pCBlock^.dcb_VarNext_bd02;
        (* *)
        dc_UnMapFreeCount         := dc_UnMapFreeCount + 1;
        pCBlock^.dcb_VarNext_bd02 := dc_pUnMapFreeList;
        dc_pUnMapFreeList         := pCBlock;
        END
    ELSE
        BEGIN
        bFound       := false;
        CBlockCnt    := 0;
        pCBlock      := dc_pLastMappedCBlock;
        REPEAT
            WITH  pCBlock^ DO
                BEGIN
                CBlockCnt := CBlockCnt + 1;
                IF  (dcb_UsageCnt_bd02 > 0        ) OR
                    (dcb_io_state <> iosNone_ebd02) OR
                    (dcb_IsSourceOfACopy_bd02     ) OR
                    (dcb_copy_no > 0              ) OR
                    (dcb_lock_req_head <> NIL     )
                THEN
                    BEGIN
                    pPrevCBlock := dcb_lru_prev;
                    pCBlock     := pPrevCBlock
                    END
                ELSE
                    bFound := true
                (*ENDIF*) 
                END
            (*ENDWITH*) 
        UNTIL
            bFound OR (pCBlock = NIL) OR (CBlockCnt > dc_SegmentSize); (* PTS 1126174 2003-12-10 *)
        (*ENDREPEAT*) 
        IF  NOT bFound
        THEN
            BEGIN
            IF  dc_SVPActive
            THEN
                BEGIN
                TrError := e_no_more_temp_space;
                bd20_InsertOverflow (TaskId, FileId, DataCache)
                END
            ELSE
                TrError := e_sysbuffer_overflow;
            (*ENDIF*) 
            END
        ELSE (* Found mapped CBlock *)
            BEGIN
            WITH pCBlock^ DO
                BEGIN
&               ifdef TEST_AWE
                bd20_SearchInChain (DataCache, ( dcb_occupant MOD dc_HeadListSize ),
                      dcb_occupant, dcb_RecMode_bd02, pCBlock, pPrevCBlock, bFound);
                IF  NOT bFound
                THEN
                    g01abort (csp3_bd_msg, csp3_n_datacache, MSG_CBLOCK_NOT_FOUND, dcb_occupant);
&               endif
                (*ENDIF*) 
                bd20_PutFromMapToUnMapList( DataCache, pCBlock );
                END
            (*ENDWITH*) 
            END
        (*ENDIF*) 
        END;
    (*ENDIF*) 
    IF  bFound
    THEN
        BEGIN
        pUnMapCBlock^.dcb_pFrame_bd02 := pCBlock^.dcb_pFrame_bd02;
        pCBlock^.dcb_pFrame_bd02      := NIL;
        RTEMem_AWEMap( pUnMapCBlock^.dcb_pFrame_bd02, pUnMapCBlock^.dcb_AWE_BlockNo_bd02 );
        bd20_PutFirstLRUList( DataCache, pUnMapCBlock )
        END
    (*ENDIF*) 
    END;
(*ENDWITH*) 
END;
 
&endif
(*------------------------------*) 
 
PROCEDURE
      bd20opmsg (msg_type  : tsp3_msg_type;
            msg_no : tsp00_Int4;
            msg_12 : tsp00_C12;
            pno    : tsp00_PageNo;
            cb_ptr : tbd02_pDataCBlock);
 
VAR
 
      cb_map_c8 : RECORD
            CASE boolean OF
                false :
                    (c8 : tsp00_C8);
                true  :
                    (cb : tbd02_pDataCBlock)
                END;
            (*ENDCASE*) 
 
      move_err : tgg00_BasisError;
      len      : integer;
      i        : integer;
      n        : tsp00_C12;
      msg      : tsp00_C40;
 
BEGIN
move_err     := e_ok;
msg          := bsp_c40;
cb_map_c8.cb := cb_ptr;
IF  (sizeof (cb_ptr) = 4) OR (cb_ptr = NIL) OR
    (pno = NIL_PAGE_NO_GG00)
THEN
    BEGIN
    g10mv ('VBD20 ',  46,    
          sizeof (msg_12), sizeof (msg),
          @msg_12, 1, @msg, 1, sizeof (msg_12), move_err);
    move_err := e_ok; (* ignore error *)
    len := 12
    END
ELSE
    BEGIN
    g10mv ('VBD20 ',  47,    
          sizeof (msg_12), sizeof (msg),
          @msg_12, 1, @msg, 1, 5, move_err);
    move_err := e_ok; (* ignore error *)
    len := 5
    END;
(*ENDIF*) 
IF  pno <> NIL_PAGE_NO_GG00
THEN
    BEGIN
    n   := ' PNO        ';
    g10mv ('VBD20 ',  48,    
          sizeof (n), sizeof (msg),
          @n, 1, @msg, len + 1, 5, move_err);
    move_err := e_ok; (* ignore error *)
    len := len + 5;
    g17trimint4_to_line (pno, len, msg)
    END;
(*ENDIF*) 
IF  (cb_ptr <> NIL) AND (len + 5 + 2 * sizeof (cb_ptr) < sizeof (msg))
THEN
    BEGIN
    n   := ' PTR        ';
    g10mv ('VBD20 ',  49,    
          sizeof (n), sizeof (msg),
          @n, 1, @msg, len + 1, 5, move_err);
    move_err := e_ok; (* ignore error *)
    len := len + 5;
    FOR i := 1 TO sizeof (tbd02_pDataCBlock) DO
        g17hexto_line (cb_map_c8.c8 [i], len, msg)
    (*ENDFOR*) 
    END;
(*ENDIF*) 
g01optextmsg (sp3p_knldiag, msg_type, msg_no, csp3_n_datacache, msg)
END;
 
&ifdef TRACE
(*------------------------------*) 
 
PROCEDURE
      bd20print_io_chain (VAR datacache : t_datacache);
 
VAR
      curr_block : tbd02_pDataCBlock;
 
BEGIN
WITH datacache DO
    BEGIN
    t01name   (bd_ioqueue, '=-=-=-=-=-=-=-=-=-');
    t01bool   (bd_ioqueue, 'io_switch   ', dc_IOSwitch);
    t01p2int4 (bd_ioqueue, 'svp_elems   ', dc_SVPElems
          ,                'io_elems    ', dc_IOElems);
    (* *)
    (* --- IO QUEUE --- *)
    (* *)
    IF  (dc_pIOQueueHead1 <> NIL) OR (dc_pIOQueueHead2 <> NIL)
    THEN
        BEGIN
        t01addr2 (bd_ioqueue, 'ioq_head_1  ', dc_pIOQueueHead1
              ,               'ioq_head_2  ', dc_pIOQueueHead2);
        t01addr2 (bd_ioqueue, 'ioq_tail_1  ', dc_pIOQueueTail1
              ,               'ioq_tail_2  ', dc_pIOQueueTail2);
        END;
    (* *)
    (* --- B20CHANGED CONTROLBLOCKS --- *)
    (* *)
    (*ENDIF*) 
    curr_block := dc_pFirstCBlock;
    WHILE (curr_block <> NIL) DO
        WITH curr_block^ DO
            BEGIN
            IF  (dcb_ChangedState_bd02 <> cstNone_ebd02)
                AND
                (rmTemp_ebd02 <> dcb_RecMode_bd02)
            THEN
                BEGIN
                t01int4_addr (bd_ioqueue, 'occupant    ', dcb_occupant
                      ,                   'address     ', curr_block);
                t01addr2     (bd_ioqueue, 'cb_io_prev  ', dcb_io_prev
                      ,                   'cb_io_next  ', dcb_io_next);
                t01int4      (bd_ioqueue, 'cb_tfn      ', ord (dcb_tfn));
                t01int4      (bd_ioqueue, 'cb_io_state ', ord (dcb_io_state));
                t01int4      (bd_ioqueue, 'ChangedState', ord (dcb_ChangedState_bd02));
                END;
            (*ENDIF*) 
            curr_block := curr_block^.dcb_FixedNext_bd02
            END
        (*ENDWITH*) 
    (*ENDWHILE*) 
    END
(*ENDWITH*) 
END;
 
&endif
&ifdef AWE_USAGE
(*------------------------------*) 
 
PROCEDURE
      bd20_PutFromMapToUnMapList(
            VAR DataCache : t_datacache;
            pCBlock       : tbd02_pDataCBlock);
 
BEGIN
WITH DataCache DO
    BEGIN
&   ifdef TEST_AWE
    bd20_AssertState( ASSERT_ID_12_BD20, dc_SegmentId, pCBlock^.dcb_pFrame_bd02 <> NIL );
&   endif
    IF  pCBlock = dc_pLastMappedCBlock
    THEN
        dc_pLastMappedCBlock := dc_pLastMappedCBlock^.dcb_lru_prev
    ELSE
        BEGIN
        (* *)
        (* Update dc_pIOMid and dc_pMid, if neccessary *)
        (* *)
        IF  NOT pCBlock^.dcb_dw_io_area
        THEN
            BEGIN
            IF  dc_pLastMappedCBlock^.dcb_dw_io_area
            THEN
                BEGIN
                pCBlock^.dcb_dw_io_area := true;
                dc_pIOMid               := dc_pIOMid^.dcb_lru_next;
                IF  dc_pIOMid <> NIL
                THEN
                    dc_pIOMid^.dcb_dw_io_area := false;
                (*ENDIF*) 
                END
            ELSE
                IF  dc_pLastMappedCBlock = dc_pIOMid
                THEN
                    dc_pIOMid := pCBlock;
                (*ENDIF*) 
            (*ENDIF*) 
            END;
        (*ENDIF*) 
        IF  NOT pCBlock^.dcb_lru_rechain
        THEN
            BEGIN
            IF  dc_pLastMappedCBlock^.dcb_lru_rechain
            THEN
                BEGIN
                pCBlock^.dcb_lru_rechain := true;
                dc_pMid                  := dc_pMid^.dcb_lru_next;
                IF  dc_pMid <> NIL
                THEN
                    dc_pMid^.dcb_lru_rechain := false;
                (*ENDIF*) 
                END
            ELSE
                IF  dc_pLastMappedCBlock = dc_pMid
                THEN
                    dc_pMid := pCBlock;
                (*ENDIF*) 
            (*ENDIF*) 
            END;
        (* *)
        (* Remove from map area *)
        (* *)
        (*ENDIF*) 
        IF  pCBlock^.dcb_lru_prev <> NIL
        THEN
            pCBlock^.dcb_lru_prev^.dcb_lru_next := pCBlock^.dcb_lru_next
        ELSE
            dc_pFirstLRU := pCBlock^.dcb_lru_next;
        (*ENDIF*) 
        pCBlock^.dcb_lru_next^.dcb_lru_prev := pCBlock^.dcb_lru_prev;
        (* *)
        (* Insert into unmap area *)
        (* *)
        pCBlock^.dcb_lru_next := dc_pLastMappedCBlock^.dcb_lru_next;
        pCBlock^.dcb_lru_prev := dc_pLastMappedCBlock;
        IF  dc_pLastMappedCBlock^.dcb_lru_next <> NIL
        THEN
            dc_pLastMappedCBlock^.dcb_lru_next^.dcb_lru_prev := pCBlock
        ELSE
            BEGIN
            (* no unmaped cblock used at this moment therefore  *)
            (* dc_pLastLRU has to be determined because the old *)
            (* dc_pLastLRU is equal to dc_pLastMappedCBlock !   *)
            dc_pLastLRU := pCBlock
            END;
        (*ENDIF*) 
        dc_pLastMappedCBlock^.dcb_lru_next := pCBlock;
        END
    (*ENDIF*) 
    END;
(*ENDWITH*) 
END;
 
&endif
(*------------------------------*) 
 
PROCEDURE
      bd20_PutFirstLRUList (
            VAR DataCache : t_datacache;
            pCBlock       : tbd02_pDataCBlock);
 
VAR
      pPrevCBlock : tbd02_pDataCBlock;
      pNextCBlock : tbd02_pDataCBlock;
 
BEGIN
WITH DataCache DO
    BEGIN
    pPrevCBlock := pCBlock^.dcb_lru_prev;
    pNextCBlock := pCBlock^.dcb_lru_next;
&   ifdef AWE_USAGE
    IF  dc_UnMapAreaSize > 0
    THEN
        BEGIN
&       ifdef TEST_AWE
        bd20_AssertState( ASSERT_ID_11_BD20, dc_SegmentId, pCBlock^.dcb_pFrame_bd02 <> NIL );
&       endif
        IF  dc_pLastMappedCBlock = NIL
        THEN
            BEGIN
&           ifdef TEST_AWE
            bd20_AssertState( ASSERT_ID_3_BD20, dc_SegmentId,
                  (dc_SegmentSize - dc_UnMapAreaSize - dc_FreeCount) = 1 );
&           endif
            dc_pLastMappedCBlock := pCBlock
            END
        ELSE
            IF  ((dc_pLastMappedCBlock = pCBlock) AND (pPrevCBlock <> NIL))
            THEN
                BEGIN
                dc_pLastMappedCBlock := pPrevCBlock;
&               ifdef TEST_AWE
                IF  dc_pLastMappedCBlock <> NIL
                THEN
                    bd20_AssertState( ASSERT_ID_10_BD20, dc_SegmentId,
                          dc_pLastMappedCBlock^.dcb_pFrame_bd02 <> NIL );
&               endif
                (*ENDIF*) 
                END
            (*ENDIF*) 
        (*ENDIF*) 
        END;
&   endif
    (*ENDIF*) 
    IF  pPrevCBlock <> NIL
    THEN
        BEGIN
        IF  pCBlock^.dcb_lru_rechain
        THEN
            BEGIN
            dc_pMid^.dcb_lru_rechain := true;
            dc_pMid                  := dc_pMid^.dcb_lru_prev;
            pCBlock^.dcb_lru_rechain := false;
            END
        ELSE
            IF  pCBlock = dc_pMid
            THEN
                dc_pMid := dc_pMid^.dcb_lru_prev;
            (*ENDIF*) 
        (*ENDIF*) 
        IF  dc_pIOMid <> NIL
        THEN
            BEGIN
            IF  pCBlock^.dcb_dw_io_area
            THEN
                BEGIN
                dc_pIOMid^.dcb_dw_io_area := true;
                dc_pIOMid                 := dc_pIOMid^.dcb_lru_prev;
                pCBlock^.dcb_dw_io_area   := false
                END
            ELSE
                IF  pCBlock = dc_pIOMid
                THEN
                    dc_pIOMid := dc_pIOMid^.dcb_lru_prev
                (*ENDIF*) 
            (*ENDIF*) 
            END;
        (*ENDIF*) 
        pPrevCBlock^.dcb_lru_next := pNextCBlock;
        IF  pNextCBlock <> NIL
        THEN
            pNextCBlock^.dcb_lru_prev := pPrevCBlock
        ELSE
            dc_pLastLRU := pPrevCBlock;
        (*ENDIF*) 
        dc_pFirstLRU^.dcb_lru_prev := pCBlock;
        pCBlock^.dcb_lru_prev      := NIL;
        pCBlock^.dcb_lru_next      := dc_pFirstLRU;
        dc_pFirstLRU               := pCBlock;
        END
    (*ENDIF*) 
    END;
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      bd20_PutNewIntoLRUList (
            VAR DataCache : t_datacache;
            pCBlock       : tbd02_pDataCBlock);
 
VAR
      TotalFreeCount : tsp00_Int4;
 
BEGIN
WITH DataCache DO
    BEGIN
&   ifdef TEST_AWE
    bd20_AssertState( ASSERT_ID_1_BD20, dc_SegmentId, pCBlock^.dcb_pFrame_bd02 <> NIL );
&   endif
    IF  dc_pFirstLRU <> NIL
    THEN
        dc_pFirstLRU^.dcb_lru_prev := pCBlock
    ELSE
        dc_pLastLRU := pCBlock;
    (*ENDIF*) 
    pCBlock^.dcb_lru_prev    := NIL;
    pCBlock^.dcb_lru_next    := dc_pFirstLRU;
    pCBlock^.dcb_lru_rechain := false;
    pCBlock^.dcb_dw_io_area  := false;
    dc_pFirstLRU             := pCBlock;
    TotalFreeCount           := dc_FreeCount + dc_UnMapFreeCount;
    (* *)
&   ifdef AWE_USAGE
    IF  (dc_UnMapAreaSize > 0) AND (dc_pLastMappedCBlock = NIL)
    THEN
        BEGIN
&       ifdef TEST_AWE
        bd20_AssertState( ASSERT_ID_3_BD20, dc_SegmentId,
              (dc_SegmentSize - dc_UnMapAreaSize - dc_FreeCount) = 1 );
&       endif
        dc_pLastMappedCBlock := pCBlock;
        END;
&   endif
    (* *)
    (*ENDIF*) 
    IF  TotalFreeCount = dc_RecAreaSize
    THEN
        BEGIN
        IF  dc_pMid <> NIL
        THEN
            g01abort (csp3_bd_msg, csp3_n_datacache, MSG_MID_EXIST, 0);
        (*ENDIF*) 
        dc_pMid := dc_pLastLRU;
        END
    ELSE
        IF  TotalFreeCount < dc_RecAreaSize
        THEN
            BEGIN
            dc_pMid^.dcb_lru_rechain := true;
            dc_pMid                  := dc_pMid^.dcb_lru_prev
            END;
        (*ENDIF*) 
    (*ENDIF*) 
    IF  TotalFreeCount = dc_IOAreaSize
    THEN
        BEGIN
        IF  dc_pIOMid <> NIL
        THEN
            g01abort (csp3_bd_msg, csp3_n_datacache, MSG_IOMID_EXIST, 0);
        (*ENDIF*) 
        dc_pIOMid := dc_pLastLRU;
        END
    ELSE
        IF  TotalFreeCount < dc_IOAreaSize
        THEN
            BEGIN
            dc_pIOMid^.dcb_dw_io_area := true;
            dc_pIOMid                 := dc_pIOMid^.dcb_lru_prev
            END
        (*ENDIF*) 
    (*ENDIF*) 
    END
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      bd20_PutMidLRUList (
            VAR DataCache : t_datacache;
            pCBlock       : tbd02_pDataCBlock);
 
VAR
      pPrevCBlock : tbd02_pDataCBlock;
      pNextCBlock : tbd02_pDataCBlock;
 
BEGIN
WITH DataCache DO
    BEGIN
    pPrevCBlock := pCBlock^.dcb_lru_prev;
    pNextCBlock := pCBlock^.dcb_lru_next;
    IF  dc_pMid <> NIL
    THEN
        IF  NOT pCBlock^.dcb_lru_rechain AND (dc_pMid <> pCBlock)
        THEN
            BEGIN
            IF  NOT pCBlock^.dcb_dw_io_area AND (dc_pIOMid <> NIL)
            THEN
                IF  dc_pMid^.dcb_dw_io_area
                THEN
                    BEGIN
                    pCBlock^.dcb_dw_io_area := true;
                    dc_pIOMid := dc_pIOMid^.dcb_lru_next;
                    IF  dc_pIOMid <> NIL
                    THEN
                        dc_pIOMid^.dcb_dw_io_area := false
                    (*ENDIF*) 
                    END
                ELSE
                    BEGIN
                    IF  dc_pIOMid = dc_pMid
                    THEN
                        dc_pIOMid := pCBlock
                    (*ENDIF*) 
                    END;
                (*ENDIF*) 
            (*ENDIF*) 
            IF  pPrevCBlock <> NIL
            THEN
                pPrevCBlock^.dcb_lru_next := pNextCBlock
            ELSE
                dc_pFirstLRU := pNextCBlock;
            (*ENDIF*) 
            IF  pNextCBlock <> NIL
            THEN
                pNextCBlock^.dcb_lru_prev := pPrevCBlock;
            (*ENDIF*) 
            pCBlock^.dcb_lru_prev               := dc_pMid;
            pCBlock^.dcb_lru_next               := dc_pMid^.dcb_lru_next;
            pCBlock^.dcb_lru_next^.dcb_lru_prev := pCBlock;
            dc_pMid^.dcb_lru_next               := pCBlock;
            dc_pMid                             := pCBlock
            END
        (*ENDIF*) 
    (*ENDIF*) 
    END
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      bd20_PutLastLRUList (
            VAR DataCache : t_datacache;
            pCBlock       : tbd02_pDataCBlock);
 
VAR
      pPrevCBlock : tbd02_pDataCBlock;
      pNextCBlock : tbd02_pDataCBlock;
 
BEGIN
WITH DataCache DO
    BEGIN
    pPrevCBlock := pCBlock^.dcb_lru_prev;
    pNextCBlock := pCBlock^.dcb_lru_next;
    IF  NOT pCBlock^.dcb_lru_rechain AND (dc_pMid <> NIL)
    THEN
        BEGIN
        dc_pMid := dc_pMid^.dcb_lru_next;
        IF  dc_pMid <> NIL
        THEN
            dc_pMid^.dcb_lru_rechain := false
        (*ENDIF*) 
        END;
    (*ENDIF*) 
    IF  NOT pCBlock^.dcb_dw_io_area AND (dc_pIOMid <> NIL)
    THEN
        BEGIN
        pCBlock^.dcb_dw_io_area := true;
        dc_pIOMid               := dc_pIOMid^.dcb_lru_next;
        IF  dc_pIOMid <> NIL
        THEN
            dc_pIOMid^.dcb_dw_io_area := false
        (*ENDIF*) 
        END;
    (*ENDIF*) 
    IF  pPrevCBlock <> NIL
    THEN
        pPrevCBlock^.dcb_lru_next := pNextCBlock
    ELSE
        dc_pFirstLRU := pNextCBlock;
    (*ENDIF*) 
    IF  pNextCBlock <> NIL
    THEN
        pNextCBlock^.dcb_lru_prev := pPrevCBlock;
    (*ENDIF*) 
    pCBlock^.dcb_lru_prev     := dc_pLastLRU;
    pCBlock^.dcb_lru_next     := NIL;
    pCBlock^.dcb_lru_rechain  := true;
    dc_pLastLRU^.dcb_lru_next := pCBlock;
    dc_pLastLRU               := pCBlock
    END
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      bd20unset_changed (VAR datacache : t_datacache;
            act_block : tbd02_pDataCBlock);
 
VAR
      first_io_queue : boolean;
 
BEGIN
IF  (act_block = NIL)
THEN
    g01abort (csp3_b20x7_nil_cbptr, csp3_n_datacache,
          'BD20UNSET: index = NIL  ', 0)
ELSE
    WITH datacache, act_block^ DO
        BEGIN
&       ifdef TRACE
        t01int4 (bd_ioqueue, '==> ChangedS', ord (dcb_ChangedState_bd02));
        t01int4 (bd_ioqueue, '==> tfn     ', ord (dcb_tfn));
        t01int4 (bd_ioqueue, '==> page no ', dcb_occupant);
        t01addr (bd_ioqueue, '==> del elem', act_block);
&       endif
        IF  dcb_ChangedState_bd02 <> cstNone_ebd02
        THEN
            BEGIN
            IF  (dcb_io_next    <> NIL    ) OR
                (dcb_io_prev    <> NIL    ) OR
                (dc_pIOQueueHead1 = act_block) OR
                (dc_pIOQueueHead2 = act_block)
            THEN
                BEGIN
                IF  NOT dc_SVPActive
                THEN
                    first_io_queue := NOT dc_IOSwitch
                ELSE
                    first_io_queue :=
                          ((dcb_ChangedState_bd02 = cstSvpRelevant_ebd02) AND dc_IOSwitch)
                          OR
                          ((dcb_ChangedState_bd02 <> cstSvpRelevant_ebd02) AND NOT dc_IOSwitch);
                (*ENDIF*) 
                IF  (first_io_queue AND (dc_pIOQueueHead1 = NIL))
                    OR
                    (NOT first_io_queue AND (dc_pIOQueueHead2 = NIL))
                THEN
                    bd20_Abort2 ( csp3_b20x4_check,
                          'IOCHAIN empt', dcb_occupant, act_block);
                (*ENDIF*) 
                IF  (dcb_io_prev = NIL)
                THEN
                    BEGIN
                    IF  first_io_queue
                    THEN
                        BEGIN
                        dc_pIOQueueHead1 := dcb_io_next;
                        IF  dcb_io_next = NIL
                        THEN
                            dc_pIOQueueTail1 := NIL
                        (*ENDIF*) 
                        END
                    ELSE
                        BEGIN
                        dc_pIOQueueHead2 := dcb_io_next;
                        IF  dcb_io_next = NIL
                        THEN
                            dc_pIOQueueTail2 := NIL
                        (*ENDIF*) 
                        END;
                    (*ENDIF*) 
                    IF  (dcb_io_next <> NIL)
                    THEN
                        BEGIN
                        dcb_io_next^.dcb_io_prev := NIL;
                        dcb_io_next              := NIL
                        END
                    (*ENDIF*) 
                    END
                ELSE
                    BEGIN
                    dcb_io_prev^.dcb_io_next := dcb_io_next;
                    IF  (dcb_io_next <> NIL)
                    THEN
                        BEGIN
                        dcb_io_next^.dcb_io_prev := dcb_io_prev;
                        dcb_io_next              := NIL
                        END
                    ELSE
                        IF  first_io_queue
                        THEN
                            dc_pIOQueueTail1 := dcb_io_prev
                        ELSE
                            dc_pIOQueueTail2 := dcb_io_prev;
                        (*ENDIF*) 
                    (*ENDIF*) 
                    dcb_io_prev := NIL
                    END;
                (*ENDIF*) 
                dc_IOElems           := pred (dc_IOElems);
                bd20TotalChangedPages := pred (bd20TotalChangedPages);
                IF  dcb_ChangedState_bd02 = cstSvpRelevant_ebd02
                THEN
                    dc_SVPElems := pred (dc_SVPElems)
                (*ENDIF*) 
                END;
            (*ENDIF*) 
            dcb_ChangedState_bd02 := cstNone_ebd02;
            END;
&       ifdef TRACE
        (*ENDIF*) 
        IF  t01trace (bd_ioqueue)
        THEN
            bd20print_io_chain (datacache);
        (*ENDIF*) 
        IF  g01glob.datacachecheck
        THEN
            bd20check_io_chain (datacache);
&       endif
        (*ENDIF*) 
        END
    (*ENDWITH*) 
(*ENDIF*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      bd20set_changed (VAR datacache : t_datacache;
            act_block          : tbd02_pDataCBlock;
            ins_this_temp_page : boolean);
 
VAR
      is_io_relevant : boolean;
 
BEGIN
IF  (act_block = NIL)
THEN
    g01abort (csp3_b20x8_nil_cbptr, csp3_n_datacache,
          'BD20SET: cbptr = NIL    ', 0)
ELSE
    WITH datacache, act_block^ DO
        BEGIN
&       ifdef TRACE
        t01int4 (bd_ioqueue, '==> ChangedS', ord (dcb_ChangedState_bd02));
        t01int4 (bd_ioqueue, '==> tfn     ', ord (dcb_tfn));
        t01int4 (bd_ioqueue, '==> page no ', dcb_occupant);
        t01addr (bd_ioqueue, '==> ins elem', act_block);
&       endif
        IF  dcb_ChangedState_bd02 = cstNone_ebd02
        THEN
            BEGIN
            dcb_ChangedState_bd02 := cstChanged_ebd02;
            is_io_relevant        := dcb_RecMode_bd02 <> rmTemp_ebd02;
            END
        ELSE
            BEGIN
            IF  ins_this_temp_page
            THEN
                is_io_relevant :=
                      ((dcb_io_next = NIL        ) AND
                      (dcb_io_prev = NIL         ) AND
                      (dc_pIOQueueHead1 <> act_block) AND
                      (dc_pIOQueueHead2 <> act_block))
            ELSE
                is_io_relevant := false
            (*ENDIF*) 
            END;
        (*ENDIF*) 
        IF  is_io_relevant
        THEN
            BEGIN
            IF  dc_IOSwitch
            THEN
                BEGIN
                IF  (dc_pIOQueueHead2 <> NIL)
                THEN
                    BEGIN
                    act_block^.dcb_io_next        := dc_pIOQueueHead2;
                    dc_pIOQueueHead2^.dcb_io_prev := act_block
                    END
                ELSE
                    dc_pIOQueueTail2 := act_block;
                (*ENDIF*) 
                dc_pIOQueueHead2 := act_block
                END
            ELSE
                BEGIN
                IF  (dc_pIOQueueHead1 <> NIL)
                THEN
                    BEGIN
                    act_block^.dcb_io_next        := dc_pIOQueueHead1;
                    dc_pIOQueueHead1^.dcb_io_prev := act_block
                    END
                ELSE
                    dc_pIOQueueTail1 := act_block;
                (*ENDIF*) 
                dc_pIOQueueHead1 := act_block
                END;
            (*ENDIF*) 
            dc_IOElems            := succ (dc_IOElems);
            bd20TotalChangedPages := succ (bd20TotalChangedPages)
            END;
&       ifdef TRACE
        (*ENDIF*) 
        IF  t01trace (bd_ioqueue)
        THEN
            bd20print_io_chain (datacache);
        (*ENDIF*) 
        IF  g01glob.datacachecheck
        THEN
            bd20check_io_chain (datacache);
&       endif
        (*ENDIF*) 
        END
    (*ENDWITH*) 
(*ENDIF*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      bd20_Abort (
            VAR FileId : tgg00_FileId;
            MsgNo      : tsp00_Int4;
            MsgText    : tsp00_C12;
            Pno        : tsp00_PageNo;
            pCBlock    : tbd02_pDataCBlock);
 
BEGIN
bd20opmsg (sp3m_error, MsgNo, MsgText, Pno, pCBlock);
b06write_filename_and_root (FileId);
vabort (WRITE_CORE_BD20)
END;
 
(*------------------------------*) 
 
PROCEDURE
      bd20_Abort2 (
            MsgNo   : tsp00_Int4;
            MsgText : tsp00_C12;
            Pno     : tsp00_PageNo;
            pCBlock : tbd02_pDataCBlock);
 
BEGIN
bd20opmsg (sp3m_error, MsgNo, MsgText, Pno, pCBlock);
vabort (WRITE_CORE_BD20)
END;
 
(*------------------------------*) 
 
PROCEDURE
      bd20_DecrementWorkloadCounter (
            VAR DataCache : t_datacache;
            FileType      : tgg00_Tfn);
 
BEGIN
WITH DataCache DO
    BEGIN
    CASE FileType OF
        tfnUndoLog_egg00 :
            dc_UndoFilePageCnt := dc_UndoFilePageCnt - 1;
        tfnObj_egg00, tfnContObj_egg00, tfnOmsInv_egg00 :
            dc_OmsDataPageCnt := dc_OmsDataPageCnt - 1;
        tfnTempOms_egg00:
            dc_OmsTempPageCnt := dc_OmsTempPageCnt - 1;
        OTHERWISE
            dc_SqlDataPageCnt := dc_SqlDataPageCnt - 1
        END;
    (*ENDCASE*) 
    END
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      bd20_IncrementWorkloadCounter (
            VAR DataCache : t_datacache;
            FileType      : tgg00_Tfn);
 
BEGIN
WITH DataCache DO
    BEGIN
    CASE FileType OF
        tfnUndoLog_egg00 :
            dc_UndoFilePageCnt := dc_UndoFilePageCnt + 1;
        tfnObj_egg00, tfnContObj_egg00, tfnOmsInv_egg00 :
            dc_OmsDataPageCnt := dc_OmsDataPageCnt + 1;
        tfnTempOms_egg00:
            dc_OmsTempPageCnt := dc_OmsTempPageCnt + 1;
        OTHERWISE
            dc_SqlDataPageCnt := dc_SqlDataPageCnt + 1
        END;
    (*ENDCASE*) 
    END
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      bd20_MaintainCacheStatistic (
            VAR datacache : t_datacache;
            Found         : boolean;
            FileType      : tgg00_Tfn);
 
BEGIN
IF  Found
THEN
    WITH datacache DO
        BEGIN
        CASE FileType OF
            tfnObj_egg00, tfnContObj_egg00, tfnOmsInv_egg00, tfnTempOms_egg00 :
                dc_OmsDataHit := dc_OmsDataHit + 1;
            tfnUndoLog_egg00 :
                dc_UndoFileHit := dc_UndoFileHit + 1;
            OTHERWISE:
                dc_SqlDataHit := dc_SqlDataHit + 1;
            END;
        (*ENDCASE*) 
        END
    (*ENDWITH*) 
ELSE
    WITH datacache DO
        BEGIN
        CASE FileType OF
            tfnObj_egg00, tfnContObj_egg00, tfnOmsInv_egg00, tfnTempOms_egg00 :
                dc_OmsDataMiss := dc_OmsDataMiss + 1;
            tfnUndoLog_egg00 :
                dc_UndoFileMiss := dc_UndoFileMiss + 1;
            OTHERWISE:
                dc_SqlDataMiss := dc_SqlDataMiss + 1;
            END;
        (*ENDCASE*) 
        END
    (*ENDWITH*) 
(*ENDIF*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      bd20_InsertLockRequest (
            VAR TaskId    : tsp00_TaskId;
            VAR FileId    : tgg00_FileId;
            VAR DataCache : t_datacache;
            LockState     : tbd02_TaskQueueReason;
            pCBlock       : tbd02_pDataCBlock);
 
VAR
      pTaskQueueItem : tbd02_pTaskQueueItem;
 
BEGIN
WITH DataCache, pCBlock^ DO
    BEGIN
    b06check_vresume_cnt (TaskId);
    pTaskQueueItem := dc_pTaskQueueFree;
    IF  dc_pTaskQueueFree = NIL
    THEN
        bd20_Abort (FileId, csp3_b20x2_pid_queue_empty,
              'Empty TaskQ ', dcb_occupant, pCBlock);
    (*ENDIF*) 
    dc_pTaskQueueFree               := dc_pTaskQueueFree^.tqiVarNext_bd02;
    pTaskQueueItem^.tqiTaskId_bd02  := TaskId;
    pTaskQueueItem^.tqiReason_bd02  := LockState;
    pTaskQueueItem^.tqiVarNext_bd02 := NIL;
    IF  dcb_lock_req_head = NIL
    THEN
        dcb_lock_req_head := pTaskQueueItem
    ELSE
        dcb_lock_req_tail^.tqiVarNext_bd02 := pTaskQueueItem;
    (*ENDIF*) 
    dcb_lock_req_tail := pTaskQueueItem;
    IF  iosBlocked_ebd02 = dcb_io_state
    THEN
        v2prio (dcb_LastOwner_bd02, c_dc_task_prio, SET_PRIO_BD20,
              FileId.fileRoot_gg00, dcb_occupant, 0);
    (*ENDIF*) 
    END
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      bd20_InsertOccupant (
            TaskId        : tsp00_TaskId;
            VAR FileId    : tgg00_FileId;
            VAR DataCache : t_datacache;
            pCBlock       : tbd02_pDataCBlock);
 
VAR
      pTaskQueueItem : tbd02_pTaskQueueItem;
 
BEGIN
WITH DataCache, pCBlock^ DO
    BEGIN
    b06check_vresume_cnt (TaskId);
    pTaskQueueItem := dc_pTaskQueueFree  ;
    IF  dc_pTaskQueueFree = NIL
    THEN
        bd20_Abort (FileId, csp3_b20x7_pid_queue_empty,
              'Empty TaskQ ', dcb_occupant, pCBlock);
    (*ENDIF*) 
    dc_pTaskQueueFree               := dc_pTaskQueueFree^.tqiVarNext_bd02;
    pTaskQueueItem^.tqiVarNext_bd02 := dcb_queue_occ;
    pTaskQueueItem^.tqiTaskId_bd02  := TaskId;
    dcb_queue_occ                   := pTaskQueueItem
    END
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      bd20_InsertOldOccupant (
            TaskId        : tsp00_TaskId;
            VAR FileId    : tgg00_FileId;
            VAR DataCache : t_datacache;
            pCBlock       : tbd02_pDataCBlock);
 
VAR
      pTaskQueueItem : tbd02_pTaskQueueItem;
 
BEGIN
WITH DataCache, pCBlock^ DO
    BEGIN
    b06check_vresume_cnt (TaskId);
    pTaskQueueItem := dc_pTaskQueueFree;
    IF  dc_pTaskQueueFree = NIL
    THEN
        bd20_Abort (FileId, csp3_b20x6_pid_queue_empty,
              'Empty TaskQ ', dcb_occupant, pCBlock);
    (*ENDIF*) 
    dc_pTaskQueueFree               := dc_pTaskQueueFree^.tqiVarNext_bd02;
    pTaskQueueItem^.tqiVarNext_bd02 := dcb_queue_old_occ;
    pTaskQueueItem^.tqiTaskId_bd02  := TaskId;
    dcb_queue_old_occ               := pTaskQueueItem
    END
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      bd20_InsertOverflow (
            TaskId        : tsp00_TaskId;
            VAR FileId    : tgg00_FileId;
            VAR DataCache : t_datacache);
 
VAR
      pTaskQueueItem : tbd02_pTaskQueueItem;
 
BEGIN
WITH DataCache DO
    BEGIN
    b06check_vresume_cnt (TaskId);
    pTaskQueueItem := dc_pTaskQueueFree;
    IF  dc_pTaskQueueFree = NIL
    THEN
        bd20_Abort (FileId, csp3_b20x8_pid_queue_empty,
              'Empty TaskQ ', NIL_PAGE_NO_GG00, NIL);
    (*ENDIF*) 
    dc_pTaskQueueFree               := dc_pTaskQueueFree^.tqiVarNext_bd02;
    pTaskQueueItem^.tqiVarNext_bd02 := dc_pOverflowTaskQueue;
    pTaskQueueItem^.tqiTaskId_bd02  := TaskId;
    dc_pOverflowTaskQueue           := pTaskQueueItem
    END
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      bd20_InsertSavepointEnd (
            TaskId        : tsp00_TaskId;
            VAR FileId    : tgg00_FileId;
            VAR DataCache : t_datacache);
 
VAR
      pTaskQueueItem : tbd02_pTaskQueueItem;
 
BEGIN
WITH DataCache DO
    BEGIN
    b06check_vresume_cnt (TaskId);
    pTaskQueueItem := dc_pTaskQueueFree;
    IF  dc_pTaskQueueFree = NIL
    THEN
        bd20_Abort (FileId, csp3_b20x8_pid_queue_empty,
              'Empty TaskQ ', NIL_PAGE_NO_GG00, NIL);
    (*ENDIF*) 
    dc_pTaskQueueFree               := dc_pTaskQueueFree^.tqiVarNext_bd02;
    pTaskQueueItem^.tqiVarNext_bd02 := dc_pSvpEndTaskQueue;
    pTaskQueueItem^.tqiTaskId_bd02  := TaskId;
    dc_pSvpEndTaskQueue             := pTaskQueueItem
    END
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      bd20_ResumeLockRequest (
            TaskId        : tsp00_TaskId;
            VAR DataCache : t_datacache;
            pCBlock       : tbd02_pDataCBlock;
            bResumeAll    : boolean);
 
VAR
      bStop         : boolean;
      pTaskQueueItem : tbd02_pTaskQueueItem;
 
BEGIN
WITH DataCache, pCBlock^ DO
    BEGIN
    bStop := false;
    WHILE (dcb_lock_req_head <> NIL) AND (NOT bStop) DO
        BEGIN
&       ifdef SUSP_REASON
        g01opmsg (sp3p_nil, sp3m_info, csp3_bd_msg,
              csp3_n_datacache, 'B20RESUME BD LOCK       ', dcb_lock_req_head^.tqiTaskId_bd02);
&       endif
        IF  TaskId = dcb_lock_req_head^.tqiTaskId_bd02
        THEN
            g01abort (csp3_b20x7_nil_cbptr, csp3_n_datacache,
                  'BD20RESUME illegal pid  ', TaskId);
        (* *)
        (*ENDIF*) 
        vresume (dcb_lock_req_head^.tqiTaskId_bd02);
        (* *)
        bStop :=
              (dcb_lock_req_head^.tqiReason_bd02 = tqrExclusiveLock_ebd02)
              AND
              (NOT bResumeAll);
        dcb_lock_req_head^.tqiTaskId_bd02  := cgg_nil_pid;
        dcb_lock_req_head^.tqiReason_bd02  := tqrNil_ebd02;
        pTaskQueueItem                     := dcb_lock_req_head^.tqiVarNext_bd02;
        dcb_lock_req_head^.tqiVarNext_bd02 := dc_pTaskQueueFree;
        dc_pTaskQueueFree                  := dcb_lock_req_head;
        dcb_lock_req_head                  := pTaskQueueItem;
        IF  dcb_lock_req_head = NIL
        THEN
            dcb_lock_req_tail := NIL
        (*ENDIF*) 
        END;
    (*ENDWHILE*) 
    IF  iosBlocked_ebd02 = dcb_io_state
    THEN
        vprio (TaskId, c_dc_task_prio, NOT SET_PRIO_BD20)
    (*ENDIF*) 
    END
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      bd20_ResumeOccupant (
            VAR DataCache : t_datacache;
            MsgText       : tsp_c24;
            pCBlock       : tbd02_pDataCBlock);
 
VAR
      pTaskQueueItem : tbd02_pTaskQueueItem;
 
BEGIN
WITH DataCache, pCBlock^ DO
    BEGIN
    WHILE dcb_queue_occ <> NIL DO
        BEGIN
&       ifdef SUSP_REASON
        g01opmsg (sp3p_nil, sp3m_info, csp3_bd_msg, csp3_n_datacache,
              MsgText, dcb_queue_occ^.tqiTaskId_bd02);
&       endif
        vresume (dcb_queue_occ^.tqiTaskId_bd02);
        dcb_queue_occ^.tqiTaskId_bd02  := cgg_nil_pid;
        pTaskQueueItem                 := dcb_queue_occ^.tqiVarNext_bd02;
        dcb_queue_occ^.tqiVarNext_bd02 := dc_pTaskQueueFree;
        dc_pTaskQueueFree              := dcb_queue_occ;
        dcb_queue_occ                  := pTaskQueueItem
        END
    (*ENDWHILE*) 
    END
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      bd20_ResumeOldOccupant (
            VAR DataCache : t_datacache;
            MsgText       : tsp_c24;
            pCBlock       : tbd02_pDataCBlock);
 
VAR
      pTaskQueueItem : tbd02_pTaskQueueItem;
 
BEGIN
WITH DataCache, pCBlock^ DO
    BEGIN
    WHILE dcb_queue_old_occ <> NIL DO
        BEGIN
&       ifdef SUSP_REASON
        g01opmsg (sp3p_nil, sp3m_info, csp3_bd_msg, csp3_n_datacache,
              MsgText, dcb_queue_old_occ^.tqiTaskId_bd02);
&       endif
        vresume (dcb_queue_old_occ^.tqiTaskId_bd02);
        dcb_queue_old_occ^.tqiTaskId_bd02  := cgg_nil_pid;
        pTaskQueueItem                     := dcb_queue_old_occ^.tqiVarNext_bd02;
        dcb_queue_old_occ^.tqiVarNext_bd02 := dc_pTaskQueueFree;
        dc_pTaskQueueFree                  := dcb_queue_old_occ;
        dcb_queue_old_occ                  := pTaskQueueItem
        END
    (*ENDWHILE*) 
    END
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      bd20_ResumeOverflow (
            VAR DataCache : t_datacache;
            ResumeCount   : tsp00_Int4);
 
VAR
      pTaskQueueItem : tbd02_pTaskQueueItem;
 
BEGIN
WITH DataCache DO
    BEGIN
    WHILE (dc_pOverflowTaskQueue <> NIL) AND (ResumeCount > 0) DO
        BEGIN
&       ifdef SUSP_REASON
        g01opmsg (sp3p_nil, sp3m_info, csp3_bd_msg, csp3_n_datacache,
              'B20RESUME FRAME AVAIL2  ', dc_pOverflowTaskQueue^.tqiTaskId_bd02);
&       endif
        vresume (dc_pOverflowTaskQueue^.tqiTaskId_bd02);
        ResumeCount                            := pred (ResumeCount);
        dc_pOverflowTaskQueue^.tqiTaskId_bd02  := cgg_nil_pid;
        pTaskQueueItem                         := dc_pOverflowTaskQueue^.tqiVarNext_bd02;
        dc_pOverflowTaskQueue^.tqiVarNext_bd02 := dc_pTaskQueueFree;
        dc_pTaskQueueFree                      := dc_pOverflowTaskQueue;
        dc_pOverflowTaskQueue                  := pTaskQueueItem
        END
    (*ENDWHILE*) 
    END
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      bd20_ResumeSavepointEnd (
            VAR DataCache : t_datacache);
 
VAR
      pTaskQueueItem : tbd02_pTaskQueueItem;
 
BEGIN
WITH DataCache DO
    BEGIN
    WHILE  dc_pSvpEndTaskQueue <> NIL DO
        BEGIN
&       ifdef SUSP_REASON
        g01opmsg (sp3p_nil, sp3m_info, csp3_bd_msg, csp3_n_datacache,
              'B20RESUME SVP END       ', dc_pSvpEndTaskQueue^.tqiTaskId_bd02);
&       endif
        vresume (dc_pSvpEndTaskQueue^.tqiTaskId_bd02);
        dc_pSvpEndTaskQueue^.tqiTaskId_bd02  := cgg_nil_pid;
        pTaskQueueItem                       := dc_pSvpEndTaskQueue^.tqiVarNext_bd02;
        dc_pSvpEndTaskQueue^.tqiVarNext_bd02 := dc_pTaskQueueFree;
        dc_pTaskQueueFree                    := dc_pSvpEndTaskQueue;
        dc_pSvpEndTaskQueue                  := pTaskQueueItem
        END
    (*ENDWHILE*) 
    END
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      bd20_SearchInChain (
            VAR DataCache   : t_datacache;
            HashIndex       : tsp00_Int4;
            PageNo          : tsp00_PageNo;
            recMode         : tbd02_RecoveryMode;
            VAR pCBlock     : tbd02_pDataCBlock;
            VAR pPrevCBlock : tbd02_pDataCBlock;
            VAR bFound      : boolean);
 
BEGIN
bFound       := false;
pPrevCBlock  := NIL;
WITH DataCache DO
    BEGIN
    pCBlock := dc_pHeadList^ [HashIndex].he_cb;
    IF  pCBlock <> NIL
    THEN
        REPEAT
            IF  (pCBlock^.dcb_occupant = PageNo       ) AND
                (pCBlock^.dcb_RecMode_bd02 = recMode  ) AND
                (NOT pCBlock^.dcb_IsSourceOfACopy_bd02)
            THEN
                bFound := true
            ELSE
                BEGIN
                pPrevCBlock := pCBlock;
                pCBlock     := pCBlock^.dcb_VarNext_bd02
                END
            (*ENDIF*) 
        UNTIL
            bFound OR (pCBlock = NIL)
        (*ENDREPEAT*) 
    (*ENDIF*) 
    END
(*ENDWITH*) 
END;
 
(* PTS 1113035 TS 2002-01-31 *)
(*------------------------------*) 
 
PROCEDURE
      bd20_SearchAndResumeLockRequest(
            TaskId        : tsp00_TaskId;
            VAR DataCache : t_datacache;
            HashIndex     : tsp00_Int4;
            PageNo        : tsp00_PageNo;
            recMode       : tbd02_RecoveryMode);
 
VAR
      bFound      : boolean;
      pCBlock     : tbd02_pDataCBlock;
      pPrevCBlock : tbd02_pDataCBlock;
 
BEGIN
bd20_SearchInChain (DataCache, HashIndex, PageNo, recMode, pCBlock, pPrevCBlock, bFound);
IF  bFound
THEN
    WITH pCBlock^ DO
        BEGIN
        IF  (dcb_UsageCnt_bd02 = 0) AND (dcb_lock_req_head <> NIL)
        THEN
            bd20_ResumeLockRequest (TaskId, DataCache, pCBlock, NOT RESUME_ALL_BD20);
        (*ENDIF*) 
        END
    (*ENDWITH*) 
(*ENDIF*) 
END;
 
(* PTS 1113035 *)
(*------------------------------*) 
 
PROCEDURE
      bd20_SetPreventSplit (
            TaskId       : tsp00_TaskId;
            PreventSplit : boolean);
 
VAR
      RegOffset : tsp00_Int4;
 
BEGIN
RegOffset := 0;
WHILE RegOffset <= bd20RegionCount - 1 DO
    BEGIN
    vbegexcl (TaskId, g08data1 + RegOffset);
    bd20DataCacheList [RegOffset].dc_PreventSplit := PreventSplit;
    vendexcl (TaskId, g08data1 + RegOffset);
    RegOffset := RegOffset + 1
    END
(*ENDWHILE*) 
END;
 
&ifdef AWE_USAGE
(*------------------------------*) 
 
PROCEDURE
      bd20_InitAWEFramePool (
            TaskId     : tsp00_TaskId;
            VAR Buffer : tsp00_Int4);
 
VAR
      bOkay   : boolean;
      Index   : tsp00_Int4;
      pMemory : b20ptr;
 
BEGIN
WITH bd20AWEFramePool DO
    BEGIN
    fp_pPool_bd20       := NIL;
    fp_OccupiedCnt_bd20 := 0;
    fp_PoolSize_bd20    := 0;
    fp_PoolSize_bd20    := (g01maxdatawriter * g01io_block_count);
    Buffer              := Buffer - fp_PoolSize_bd20 - bd20RegionCount; (* dc_pAWEAuxBuffer *)
    IF  Buffer < 0
    THEN
        g01abort (csp3_b20x1_buffer_to_small, csp3_n_config,
              'Data cache to small    :', fp_PoolSize_bd20);
    (* *)
    (*ENDIF*) 
    vmalloc (fp_PoolSize_bd20 * sizeof (t_AWE_FramePoolEntry), pMemory.cblockaddr, bOkay);
    (* *)
    IF  bOkay
    THEN
        fp_pPool_bd20 := pMemory.pAuxFramePool
    ELSE
        g01abort (csp3_bd_msg, csp3_n_datacache, MSG_NO_MORE_MEMORY, 0);
    (*ENDIF*) 
    FOR Index := 0 TO fp_PoolSize_bd20 - 1 DO
        BEGIN
        fp_pPool_bd20^ [Index].fpe_pFrame_bd20 := bd999GetFrame( TaskId );
        fp_OccupiedCnt_bd20                    := fp_OccupiedCnt_bd20 + 1
        END
    (*ENDFOR*) 
    END
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      bd20_ShutdownAWEFramePool (
            TaskId : tsp00_TaskId);
 
VAR
      Index   : tsp00_Int4;
      pMemory : b20ptr;
 
BEGIN
WITH bd20AWEFramePool DO
    BEGIN
    IF  fp_pPool_bd20 <> NIL
    THEN
        BEGIN
        FOR Index := 0 TO fp_PoolSize_bd20 - 1 DO
            bd999ReleaseFrame( TaskId, fp_pPool_bd20^ [Index].fpe_pFrame_bd20 );
        (*ENDFOR*) 
        pMemory.pAuxFramePool := fp_pPool_bd20;
        vmfree (pMemory.cblockaddr);
        fp_pPool_bd20       := NIL;
        fp_OccupiedCnt_bd20 := 0;
        fp_PoolSize_bd20    := 0
        END
    (*ENDIF*) 
    END
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      bd20_GetFromAWEFramePool (
            TaskId     : tsp00_TaskId;
            AWEBlockNo : tsp00_Int4;
            VAR pFrame : tbd_nodeptr);
 
BEGIN
(* *)
vbegexcl (TaskId, g08datacache);
(* *)
WITH bd20AWEFramePool DO
    BEGIN
    IF  fp_OccupiedCnt_bd20 = 0
    THEN
        g01abort (csp3_bd_msg, csp3_n_datacache, MSG_NO_AUX_FRAMES, fp_PoolSize_bd20);
    (*ENDIF*) 
    pFrame              := fp_pPool_bd20^ [fp_OccupiedCnt_bd20 - 1].fpe_pFrame_bd20;
    fp_OccupiedCnt_bd20 := fp_OccupiedCnt_bd20 - 1
    END;
(*ENDWITH*) 
(* *)
vendexcl (TaskId, g08datacache);
(* *)
RTEMem_AWEMap( pFrame, AWEBlockNo )
END;
 
(*------------------------------*) 
 
PROCEDURE
      bd20_ReleaseToAWEFramePool (
            TaskId     : tsp00_TaskId;
            VAR pFrame : tbd_nodeptr);
 
BEGIN
(* *)
vbegexcl (TaskId, g08datacache);
(* *)
WITH bd20AWEFramePool DO
    BEGIN
    fp_pPool_bd20^ [fp_OccupiedCnt_bd20].fpe_pFrame_bd20 := pFrame;
    fp_OccupiedCnt_bd20                                  := fp_OccupiedCnt_bd20 + 1
    END;
(*ENDWITH*) 
(* *)
vendexcl (TaskId, g08datacache);
(* *)
RTEMem_AWEUnMap( pFrame );
pFrame := NIL;
END;
 
(*------------------------------*) 
 
PROCEDURE
      bd20_MapAuxBuffer (
            VAR DataCache : t_datacache;
            AWEBlockNo    : tsp00_Int4;
            VAR pFrame    : tbd_nodeptr);
 
BEGIN
WITH DataCache DO
    BEGIN
    pFrame           := dc_pAWEAuxBuffer;
    dc_pAWEAuxBuffer := NIL;
    RTEMem_AWEMap( pFrame, AWEBlockNo )
    END;
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      bd20_UnMapAuxBuffer(
            VAR DataCache : t_datacache;
            VAR pFrame    : tbd_nodeptr);
 
BEGIN
WITH DataCache DO
    BEGIN
    RTEMem_AWEUnMap( pFrame );
    dc_pAWEAuxBuffer := pFrame;
    pFrame           := NIL
    END
(*ENDWITH*) 
END;
 
&endif
(*------------------------------*) 
 
PROCEDURE
      bd20_AssertState(
            Ident       : tsp00_Int4;
            SegmentId   : tsp00_Int4;
            bConstraint : boolean);
 
BEGIN
IF  NOT bConstraint
THEN
    g01abort( Ident, csp3_n_datacache, 'ASSERTION FAILED        ', SegmentId );
(*ENDIF*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      bd20_ReadAccessToFrame(
            VAR dataCache : t_datacache;
            pFrame        : tbd_nodeptr);
 
VAR
      retCode : tsp00_Longint;
 
BEGIN
IF  (pFrame <> NIL) AND (dataCache.dc_UnMapAreaSize = 0)
THEN
    BEGIN
    retCode := RTESys_MemProtectReadOnly (pFrame, bd999GetPageSize);
    IF  retCode <> 0
    THEN
        g01abort (csp3_bd_msg, csp3_n_datacache, 'RTE MEMORY LOCK FAILED  ', retCode);
    (*ENDIF*) 
    END
(*ENDIF*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      bd20_ReadWriteAccessToFrame(
            VAR dataCache : t_datacache;
            pFrame        : tbd_nodeptr);
 
VAR
      retCode : tsp00_Longint;
 
BEGIN
IF  (pFrame <> NIL) AND (dataCache.dc_UnMapAreaSize = 0)
THEN
    BEGIN
    retCode := RTESys_MemProtectReadWrite (pFrame, bd999GetPageSize);
    IF  retCode <> 0
    THEN
        g01abort (csp3_bd_msg, csp3_n_datacache, 'RTE MEMORY LOCK FAILED  ', retCode);
    (*ENDIF*) 
    END
(*ENDIF*) 
END;
 
.CM *-END-* code ----------------------------------------
.SP 2 
***********************************************************
.PA 
