.ad 8
.bm 8
.fm 4
.bt $Copyright by   SAP AG, 2002$$Page %$
.tm 12
.hm 6
.hs 3
.tt 1 $SQL$Project Distributed Database System$VBD75$
.tt 2 $$$
.tt 3 $JuergenP$concurrency$2000-08-01$
***********************************************************
.nf
 
 
    ========== licence begin  GPL
    Copyright (C) 2000 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
.nf
.sp
Module  : concurrency
=========
.sp
Purpose : managing locks for concurrent access to B*trees
.CM *-END-* purpose -------------------------------------
.sp
.cp 3
Define  :
 
        VAR
              b75region_cnt : tsp00_Int4;
 
        PROCEDURE
              b75ilread_lock_index (VAR current : tbd_current_tree;
                    indexnode      : tsp00_PageNo;
                    suspend_reason : tsp00_Int2);
 
        PROCEDURE
              b75ilwrite_lock_index (VAR current : tbd_current_tree;
                    leaf            : tsp00_PageNo;
                    indexnode       : tsp00_PageNo;
                    VAR lock_return : tbd_lock_returncode;
                    suspend_reason  : tsp00_Int2);
 
        PROCEDURE
              b75init_tree_locklist (pid : tsp00_TaskId;
                    VAR e : tgg00_BasisError);
 
        PROCEDURE
              b75iuiread_unlocklock_index (
                    VAR current    : tbd_current_tree;
                    src_index      : tsp00_PageNo;
                    dest_index     : tsp00_PageNo;
                    suspend_reason : tsp00_Int2);
 
        PROCEDURE
              b75iuread_unlock_index (VAR current : tbd_current_tree;
                    indexnode       : tsp00_PageNo);
 
        PROCEDURE
              b75iuwrite_unlock_index (VAR current : tbd_current_tree;
                    indexnode       : tsp00_PageNo);
 
        PROCEDURE
              b75llread_lock_leaf (VAR current : tbd_current_tree;
                    leaf           : tsp00_PageNo;
                    suspend_reason : tsp00_Int2);
 
        PROCEDURE
              b75llwrite_lock_leaf (VAR current : tbd_current_tree;
                    leaf           : tsp00_PageNo;
                    suspend_reason : tsp00_Int2);
 
        PROCEDURE
              b75lulread_unlocklock_leaf(VAR current : tbd_current_tree;
                    src_leaf       : tsp00_PageNo;
                    src_index      : tsp00_PageNo;
                    dest_leaf      : tsp00_PageNo;
                    dest_index     : tsp00_PageNo;
                    suspend_reason : tsp00_Int2);
 
        PROCEDURE
              b75luread_unlock_leaf (VAR current : tbd_current_tree;
                    leaf : tsp00_PageNo);
 
        PROCEDURE
              b75luwrite_unlock_leaf (VAR current : tbd_current_tree;
                    leaf : tsp00_PageNo);
 
        FUNCTION
              b75exclusive_locks (pid : tsp00_TaskId) : boolean;
 
        PROCEDURE
              b75rdelete_lock_requests (pid : tsp00_TaskId);
 
        PROCEDURE
              b75reset_lock (VAR current : tbd_current_tree;
                    leaf      : tsp00_PageNo);
 
        PROCEDURE
              b75resume (pid : tsp00_TaskId);
 
        PROCEDURE
              b75set_prevent_split (pid : tsp00_TaskId);
 
        PROCEDURE
              b75show_treelocklist (VAR current : tbd_current_tree;
                    VAR rec_count : tsp00_Int4);
 
        PROCEDURE
              b75tldelete_lock_tree (VAR current : tbd_current_tree;
                    ignore_svp     : boolean;
                    suspend_reason : tsp00_Int2);
 
        PROCEDURE
              b75tlread_lock_tree (VAR current : tbd_current_tree;
                    suspend_reason : tsp00_Int2);
 
        PROCEDURE
              b75tlselect_lock_tree (VAR current : tbd_current_tree;
                    suspend_reason : tsp00_Int2);
 
        PROCEDURE
              b75tlwrite_lock_tree (VAR current : tbd_current_tree;
                    leaf            : tsp00_PageNo;
                    VAR lock_return : tbd_lock_returncode;
                    suspend_reason  : tsp00_Int2);
 
        FUNCTION
              b75tree_request (pid : tsp00_TaskId;
                    root : tsp00_PageNo) : boolean;
 
        PROCEDURE
              b75tudelete_unlock_tree (VAR current : tbd_current_tree);
 
        PROCEDURE
              b75turead_unlock_tree (VAR current : tbd_current_tree);
 
        PROCEDURE
              b75tuselect_unlock_tree (VAR current : tbd_current_tree);
 
        PROCEDURE
              b75tuwrite_unlock_tree (VAR current : tbd_current_tree);
 
.CM *-END-* define --------------------------------------
.sp;.cp 3
Use     :
 
        FROM
              error_text_handling : VBD06;
 
        PROCEDURE
              b06check_vresume_cnt (pid : tsp00_TaskId);
 
      ------------------------------ 
 
        FROM
              nodehandling : VBD13;
 
        PROCEDURE
              b13free_pnos_after_unlock
                    (VAR current : tbd_current_tree);
 
      ------------------------------ 
 
        FROM
              tree_requestlist : VBD76;
 
        PROCEDURE
              b76index_writers_start (VAR root_desc : tbd7_root_desc;
                    VAR resumed : boolean;
                    pid         : tsp00_TaskId);
 
        PROCEDURE
              b76insert_requestentry (
                    pid             : tsp00_TaskId;
                    VAR root_desc   : tbd7_root_desc;
                    leaf            : tsp00_PageNo;
                    indexnode       : tsp00_PageNo;
                    lockstate       : tbd_treelock;
                    ignore_svp      : boolean;
                    excl_lock_exist : boolean);
 
        PROCEDURE
              b76istart_index (VAR root_desc : tbd7_root_desc;
                    indexnode       : tsp00_PageNo;
                    lockstate       : tbd_treelock;
                    VAR split_found : boolean;
                    VAR resumed     : boolean);
 
        FUNCTION
              b76is_empty_requestlist (VAR root_desc : tbd7_root_desc)
                    : boolean;
 
        FUNCTION
              b76is_tree_requested (VAR root_desc : tbd7_root_desc;
                    lockstate : tbd_treelock) : boolean;
 
        PROCEDURE
              b76delete_requestentries;
 
        FUNCTION
              b76is_leaf_requested (VAR root_desc : tbd7_root_desc;
                    leaf      : tsp00_PageNo;
                    lockstate : tbd_treelock) : boolean;
 
        PROCEDURE
              b76leaf_writers_start (VAR root_desc : tbd7_root_desc;
                    VAR resumed : boolean);
 
        PROCEDURE
              b76lwstart_write_leaf (VAR root_desc : tbd7_root_desc;
                    leaf             : tsp00_PageNo;
                    VAR resumed      : boolean);
 
        PROCEDURE
              b76lrstart_read_leaf (VAR root_desc : tbd7_root_desc;
                    leaf        : tsp00_PageNo;
                    VAR resumed : boolean);
 
        PROCEDURE
              b76readers_start (VAR root_desc : tbd7_root_desc;
                    VAR resumed : boolean);
 
        PROCEDURE
              b76resume_after_svp (
                    TaskId    : tsp00_TaskId;
                    partition : tsp00_Int2);
 
        PROCEDURE
              b76riconv_to_index_req (
                    VAR root_desc   : tbd7_root_desc;
                    pid             : tsp00_TaskId;
                    index_node      : tsp00_PageNo;
                    lockstate       : tbd_treelock;
                    excl_lock_exist : boolean);
 
        PROCEDURE
              b76start_tree (VAR root_desc : tbd7_root_desc;
                    lockstate   : tbd_treelock;
                    VAR found   : boolean;
                    VAR resumed : boolean);
 
        FUNCTION
              b76is_index_requested (
                    VAR root_desc : tbd7_root_desc;
                    indexnode     : tsp00_PageNo;
                    lockstate     : tbd_treelock) : boolean;
 
      ------------------------------ 
 
        FROM
              tree_locklist : VBD77;
 
        VAR
              b77locklist : tbd7_locklist_array;
 
        FUNCTION
              b77anyleaf_write_locks (VAR root_desc : tbd7_root_desc)
                    : boolean;
 
        PROCEDURE
              b77check_locklist (VAR root_desc : tbd7_root_desc);
 
        PROCEDURE
              b77check_whole_locklist (Partition : integer);
 
        PROCEDURE
              b77conv_lock_to_req (
                    pid             : tsp00_TaskId;
                    VAR root_desc   : tbd7_root_desc;
                    lockstate       : tbd_treelock;
                    excl_lock_exist : boolean);
 
        PROCEDURE
              b77delete_lockentry (pid : tsp00_TaskId;
                    VAR root_desc : tbd7_root_desc;
                    VAR leaf      : tsp00_PageNo;
                    indexnode     : tsp00_PageNo;
                    lockstate     : tbd_treelock);
 
        FUNCTION
              b77excl_using_root (VAR root_desc : tbd7_root_desc;
                    pid : tsp00_TaskId) : boolean;
 
        FUNCTION
              b77exist_lock_within_subtree (
                    pid           : tsp00_TaskId;
                    VAR root_desc : tbd7_root_desc;
                    indexnode     : tsp00_PageNo): boolean;
 
        PROCEDURE
              b77index_check (VAR current : tbd_current_tree;
                    VAR root_desc : tbd7_root_desc);
 
        PROCEDURE
              b77index_or_leaf_writers (VAR root_desc : tbd7_root_desc;
                    pid             : tsp00_TaskId;
                    VAR index_found : boolean;
                    VAR leaf_found  : boolean);
 
        PROCEDURE
              b77init_tree_locklist (partition : integer;
                    VAR alloc_sum : tsp00_Int4;
                    VAR e         : tgg00_BasisError);
 
        PROCEDURE
              b77insert_lockentry (pid : tsp00_TaskId;
                    VAR root_desc : tbd7_root_desc;
                    leaf          : tsp00_PageNo;
                    lockstate     : tbd_treelock;
                    ignore_svp    : boolean);
 
        FUNCTION
              b77is_empty_locklist (VAR root_desc : tbd7_root_desc)
                    : boolean;
 
        PROCEDURE
              b77lconv_to_leaf (pid : tsp00_TaskId;
                    VAR root_desc : tbd7_root_desc;
                    dest_leaf     : tsp00_PageNo;
                    dest_index    : tsp00_PageNo;
                    lockstate     : tbd_treelock);
 
        FUNCTION
              b77leaf_in_locklist (VAR root_desc : tbd7_root_desc;
                    leaf : tsp00_PageNo;
                    pid  : tsp00_TaskId) : boolean;
 
        FUNCTION
              b77lleaf_in_locklist (VAR root_desc : tbd7_root_desc;
                    leaf      : tsp00_PageNo;
                    lockstate : tbd_treelock;
                    pid       : tsp00_TaskId) : boolean;
 
        PROCEDURE
              b77liconv_to_index_lock (VAR root_desc : tbd7_root_desc;
                    pid : tsp00_TaskId;
                    indexnode : tsp00_PageNo;
                    lockstate : tbd_treelock);
 
        PROCEDURE
              b77show_treelocklist (VAR current : tbd_current_tree;
                    VAR rec_count : tsp00_Int4;
                    partition : integer);
 
        FUNCTION
              b77stree_in_locklist (VAR root_desc : tbd7_root_desc)
                    : boolean;
 
        FUNCTION
              b77tree_in_locklist (VAR root_desc : tbd7_root_desc)
                    : boolean;
 
        PROCEDURE
              b77reset_lock (pid  : tsp00_TaskId;
                    VAR root_desc    : tbd7_root_desc;
                    VAR old_locktype : tbd_treelock);
 
        PROCEDURE
              b77tconv_to_tree (pid : tsp00_TaskId;
                    VAR root_desc : tbd7_root_desc;
                    leaf          : tsp00_PageNo;
                    lockstate     : tbd_treelock);
 
        PROCEDURE
              b77root_description (root : tsp00_PageNo;
                    VAR root_desc : tbd7_root_desc);
 
        FUNCTION
              b77write_index_locked (VAR root_desc : tbd7_root_desc;
                    indexnode      : tsp00_PageNo) : boolean;
 
      ------------------------------ 
 
        FROM
              Configuration_Parameter : VGG01;
 
        VAR
              g01glob   : tgg_kernel_globals;
              g01vtrace : tgg_vtrace_state;
 
        PROCEDURE
              g01abort (msg_no : tsp_int4;
                    msg_label  : tsp_c8;
                    msg_text   : tsp_c24;
                    bad_value  : tsp_int4);
 
        PROCEDURE
              g01allocate_msg (msg_label : tsp_c8;
                    msg_text   : tsp_c24;
                    alloc_size : tsp_int4);
 
        PROCEDURE
              g01check (msg_no : tsp_int4;
                    msg_label  : tsp_c8;
                    msg_text   : tsp_c24;
                    bad_value  : tsp_int4;
                    constraint : boolean);
 
        FUNCTION
              g01region_cnt (region_type : tgg_region_type) : tsp_int4;
 
      ------------------------------ 
 
        FROM
              Regions_and_Longwaits : VGG08;
 
        VAR
              g08split1 : tsp00_RegionId;
              g08tree1  : tsp00_RegionId;
&       ifdef TRACE
 
        PROCEDURE
              g08excl_check( pid : tsp00_TaskId;
                    region : tsp00_RegionId );
&       endif
 
      ------------------------------ 
 
        FROM
              KB_Logging : VKB560;
 
        PROCEDURE
              kb560StartSavepoint (VAR Trans : tgg00_TransContext;
                    MessType2 : tgg00_MessType2);
 
      ------------------------------ 
 
        FROM
              RTE_kernel : VEN101;
 
        PROCEDURE
              vbegexcl (pid : tsp_process_id;
                    region : tsp_region_id);
 
        PROCEDURE
              vendexcl (pid : tsp_process_id;
                    region : tsp_region_id);
 
        PROCEDURE
              v2prio (pid : tsp_process_id;
                    prio     : tsp_int1;
                    set_prio : boolean;
                    root     : tsp_page_no;
                    leaf     : tsp_page_no;
                    locktype : tbd_treelock);
 
        PROCEDURE
              vresume (pid : tsp_process_id;
                    suspend_level : tsp_int1);
 
        PROCEDURE
              vsuspend (pid        : tsp_process_id;
                    suspend_level  : tsp_int1;
                    suspend_reason : tsp_int2);
 
.CM *-END-* use -----------------------------------------
.sp;.cp 3
Synonym :
 
        PROCEDURE
              v2prio;
 
              integer  tsp_page_no
              integer  tbd_treelock
 
.CM *-END-* synonym -------------------------------------
.sp;.cp 3
Author  : JuergenP
.sp
.cp 3
Created : 1982-02-19
.sp
.cp 3
Version : 2002-08-26
.sp
.cp 3
Release :      Date : 2000-08-01
.sp
***********************************************************
.sp
.cp 10
.fo
.oc _/1
Specification:
 
The ADABAS/D Server supports parallel access to one and
the same B*tree. A distinction is made between:
.sp;.nf
   - retrieval function (READER) and
   - update function (WRITER).
.sp;.fo
At the same time, interference between different operations
is prevented and freedom from deadlock is guaranteed. In order
to fulfill these two requirements, locks are set by the operations.
The locked objects are either a single leaf or the entire tree.
The purpose of the separated lock types is described below:
.sp;.nf
 
- r_lock_tree :  reading the indexlevel
- r_lock_leaf :  reading a node on leaflevel
- w_lock_leaf :  update a node on leaflevel
- w_lock_tree :  update index- and leaflevel
- d_lock_tree :  update or drop a (longcolumn) file
- s_lock_tree :  reading all nodes on leaflevel
- r_lock_index:  reading a node on first indexlevel
- w_lock_index:  update some nodes on leaflevel and an indexnode
 
.sp;.fo
 
.sp
Lock orders are executed with the procedures listed below:
.sp;cp 6
B75EXCLUSIVE_LOCKS
.sp
This function checks whether there are any w_lock_tree's within
the treelocklist independent on lockmode. If no w_lock_tree is
found then a true is provided else false.
 
.sp;.cp 10
B75ILREAD_LOCK_INDEX
.sp
This procedure is used to set a r_lock_index on a B*tree, which is
identified by ROOT. Possible acknowledgments in LOCK_RETURN are
lock_okay or lock_dirty. In the latter case a collision is detected
and the lockrequest is stored within the treelocklist as a request.
Note that during the savepoint phase r_lock_index demands ignored
w_lock_index requests! This prevent deadlocks. CURR_INDEX is set
to INDEXNODE.
 
.sp;.cp 10
B75ILWRITE_LOCK_INDEX
.sp
This procedure is used to set a w_lock_index on a INDEXNODE of a
B*tree, which is identified by ROOT. If a savepoint is active this
procedure makes sure that no more treesplittoperations will performed.
The calling task suspends itselfs in a region and prevents that
any other task apply for a w_lock_index, w_lock_tree or d_lock_tree
(see B75TLDELETE_LOCK and B75RESUME). Possible acknowledgments in
LOCK_RETURN are lock_okay, lock_dirty or lock_failed. CURR_INDEX
is set to INDEXNODE.
 
.sp;.cp 7
B75INIT_TREE_LOCKLIST
.sp
This procedure generates and initializes the treelocklist and
therefore it must be called during system generation and for
each system restart. If in the generation phase is not enought
storage available then an error will be provided.
 
.sp;cp 9
B75IUIREAD_UNLOCKLOCK_INDEX
.sp
This procedure is used to transform a locked r_lock_index on SRC_INDEX
into a locked or requested r_lock_index on DEST_INDEX. Before
requesting DEST_INDEX SRC_INDEX is released and suspended processes are
resumed provided that the requirements are accomplished.
Note that it's allowed to apply this procedure only on a dynamic
B*tree. In the slow system a check will guarantee this. Note
that the value of lle_leaf inside the lockentry will not be changed!
 
.sp;.cp 7
B75IUREAD_UNLOCK_INDEX
.sp
This procedure is used to release a r_lock_index on an INDEXNODE of
a B*tree, which is identified by CURRENT. Additional suspended
processes are resumed; provided that the requirements are
accomplished.
 
.sp;.cp 6
B75IUWRITE_UNLOCK_INDEX
.sp
This procedure is used to release a w_lock_index on a B*tree, which
is identified by CURRENT.  Additional suspended processes are resumed
provided that the requirements are accomplished.
 
.sp;.cp 10
B75LLREAD_LOCK_LEAF
.sp
This procedure is used to set a r_lock_leaf on a certain leaf,
which is identified by ROOT (component of tbd_current_tree) and
LEAF. Possible acknowledgments in LOCK_RETURN are lock_okay or
lock_dirty. In the latter case a collision is detected and the
lock request is stored within the treelocklist as a request.
Additional the lock treatment causes an update of the parameter
CURRENT.
 
.sp;cp 8
B75LLWRITE_LOCK_LEAF
.sp
This procedure is used to set a w_lock_leaf on a leaf, which is
identified by ROOT (component of tbd_current_tree) and LEAF.
Possible acknowledgments in LOCK_RETURN are lock_okay or
lock_dirty. In the latter case a collision is detected and the lock
request is stored within the treelocklist as a request.
 
.sp;cp 11
B75LULREAD_UNLOCKLOCK_LEAF
.sp
This procedure is used to transform a locked r_lock_leaf on SRC_LEAF
into a locked or requested r_lock_leaf on DEST_LEAF. Before
requesting DEST_LEAF SRC_LEAF is released and suspended processes are
resumed provided that the requirements are accomplished.
Note that it isn't allowed to apply this procedure on a dynamic
B*tree, if SRC_LEAF and DEST_LEAF have different indexnodes.
In the slow system a check between SRC_INDEX and DEST_INDEX will
cause an abort.
 
.sp;cp 7
B75LUREAD_UNLOCK_LEAF
.sp
This procedure is used to release a r_lock_leaf on a leaf, which
is identified by PID, ROOT (components of tbd_current_tree) and LEAF.
Additional suspended processes are resumed; provided that the
requirements are accomplished.
 
.sp;cp 6
B75LUWRITE_UNLOCK_LEAF
.sp
This procedure is used to release a w_lock_leaf on a leaf, which
is identified by PID, ROOT (components of tbd_current_tree) and
LEAF. Additional suspended processes are resumed; provided that the
requirements are accomplished.
 
.sp;cp 7
B75RDELETE_LOCK_REQUESTS
.sp
This procedure is called during the shutdown phase and removes
all existing request entries. Locked entries are disregarded!
At the beginning the B75RESUME procedure is called, to free the
splitt region, which possible contains tasks.
 
.sp;cp 9
B75RESET_LOCK
.sp
This procedure is used to reset a any existing lock to a r_lock_tree.
Additional suspended processes are waked up; provided that the
requirements are accomplished. Note that this will raise performance.
For instance if any lock on B*leaflevel is to special then it is
converted to a r_lock_tree. Now the user can go on without requesting
a new r_lock_tree.
 
.sp;cp 7
B75RESUME
.sp
This procedure is used to wake up a task, which tried to perform
a treesplittoperation (w_lock_tree) during the savepoint phase
(see B75TLWRITE_LOCK_TREE). Additional the prevent flag is set
to false again (see B75SET_PREVENT_SPLIT).
 
.sp;cp 9
B75SET_PREVENT_SPLIT
.sp
This procedure sets a flag, which indicates whether it's allowed
to perform a w_lock_tree operation on a B*tree. During the
savepoint phase this flag is set to true else it is false. After
the savepoint phase it is set back to false by the procedure
B75RESUME.
 
.sp;cp 17
B75TLDELETE_LOCK
.sp
This procedure is used to set a d_lock_tree on a tree, which is
identified by ROOT. If a savepoint is active this procedure makes
sure that no more treesplittoperations will performed. (One
exception, but see below) The calling task suspends itselfs in a
region and prevents that any other task apply for a w_lock_tree
or d_lock_tree (see B75TLWRITE_LOCK_TREE and B75RESUME).
Exception: Droping of a table containing longcolums causes a
d_lock_tree on the "primary tree" and a d_lock_tree for each
corresponding "longcolumn tree". So a task with a d_lock_tree
is authorized to set another d_lock_tree although a savepoint is
active. The parameter SPLITT_LOCK_EXIST indicates whether a task
is authorized to do this. Possible acknowledgments in LOCK_RETURN
are lock_okay or lock_dirty. In the latter case a collision is
detected and the lockrequest is stored within the treelocklist as
a request.
 
.sp;cp 9
B75TLREAD_LOCK_TREE
.sp
This procedure is used to set an r_lock_tree on a B*tree, which
identified by ROOT. Possible acknowledgments are
lock_okay or lock_dirty. In the latter case a collision is detected
and the lockrequest is stored within the treelocklist as a request.
Note that during the savepoint phase r_lock_tree demands ignore
w_lock_tree requests! This prevents deadlocks.
 
.sp;cp 6
B75TLSELECT_TREE
.sp
This procedure is used to set a s_lock_tree on a B*tree, which is
identified by ROOT. Possible acknowledgments in LOCK_RETURN are
lock_okay or lock_dirty. In the latter case a collision is detected
and the lockrequest is stored within the treelocklist as a request.
 
.sp;cp 10
B75TLWRITE_LOCK_TREE
.sp
This procedure is used to set a w_lock_tree on a B*tree, which is
identified by ROOT. If a savepoint is active this procedure makes
sure that no more treesplittoperations will performed. The calling
task suspends itselfs in a region and prevents that any other task
apply for a w_lock_tree or d_lock_tree (see B75TLDELETE_LOCK and
B75RESUME). Possible acknowledgments in LOCK_RETURN are lock_okay,
lock_dirty or lock_failed.
 
.sp;cp 6
B75TREE_REQUEST
.sp
This function checks whether a w_lock_tree request on a B*tree
exists. The tree is identified by ROOT. If such an entry exists
then true is provided.
 
.sp;cp 5
B75TUDELETE_UNLOCK_TREE
.sp
This procedure is used to release a d_lock_tree on a B*tree, which
is identified by PID and ROOT (components of tbd_current_tree).
 
.sp;cp 7
B75TUREAD_UNLOCK_TREE
.sp
This procedure is used to release a r_lock_tree on a B*tree, which
is identified by PID and ROOT (components of tbd_current_tree).
Additional suspended processes are resumed; provided that the
requirements are accomplished.
 
.sp;cp 7
B75TUSELECT_UNLOCK_TREE
.sp
This procedure is used to release a s_lock_tree on a B*tree, which
is identified by PID and ROOT (components of tbd_current_tree).
Additional suspended processes are resumed; provided that the
requirements are accomplished.
 
.sp;cp 7
B75TUWRITE_UNLOCK_TREE
.sp
This procedure is used to release a w_lock_tree on a B*tree, which
is identified by PID and ROOT (components of tbd_current_tree).
Additional suspended processes are resumed; provided that the
requirements are accomplished.
 
.CM *-END-* specification -------------------------------
.sp 2
***********************************************************
.sp
.cp 10
.fo
.oc _/1
Description:
 
When the B*tree is accessed, a read protect is first set both
by each READER and by each WRITER, i.e. when they enter the tree,
READER and WRITER are handled alike.  WRITER will later change
this lock to a leaf write lock if the operation has
not caused any overflow or underflow; otherwise it will change
it to a tree write lock.
.sp
As long as there are only read locks on the tree or individual
leaves are write-locked, additional read locks can be set.  If
one of these locks is converted into a tree write lock,
subsequent read requests are entered in the request list and wait
there to be executed, i.e. the tree is locked.  If then all
readers and writers are at leaf level (those that are limited
to individual leaves, i.e. require no balancing with the right
neighbor leaf and no index reorganization), write requests are
executed at tree level.  When all these operations have also
been run, the tree is released.
.sp 2;.cp 15
READER and WRITER protocols are given below.
.sp 3;.nf
   READER Protocol
   ================
 
 
     0) Request read lock on tree;
 
     1) After lock is obtained, carry out
        read operation;
 
     2) Release read lock.
.sp 4
   WRITER Protocol
   ================
 
 
     0) Request read lock on tree;
 
     1) After lock is obtained, identify the leaf
        to which the write operation is to be
        performed;
 
 
     2) Check whether the leaf is 'secured'
        against the write operation;
 
 
         3) if yes, request write lock on the
            leaf; continue at 5);
 
 
         4) otherwise, continue at 9)
 
 
     5) After lock is obtained, check whether a
        'dirty' acknowledgement is pending;
 
 
         6) if yes, check whether the leaf is
            still 'secured';
 
 
             7) if yes, re-identify entry position and carry
                out operation; continue at 13);
 
 
             8) otherwise, continue at 9);
 
 
         9) otherwise, request write lock on tree;
 
 
         10) After lock is obtained, check whether a
             'dirty' acknowledgement is pending;
 
 
             11) if yes, re-identify entry position and carry
                 out operation; continue at 13);
 
 
             12) otherwise, carry out operation;
 
 
     13) Release lock.
.CM *-END-* description ---------------------------------
***********************************************************
.sp
.cp 10
.nf
.oc _/1
Structure:
 
.CM *-END-* structure -----------------------------------
.sp 2
**********************************************************
.sp
.cp 10
.nf
.oc _/1
.CM -lll-
Code    :
 
 
CONST
      c_excl_lock_exist = true; (* PTS 1106058 TS 2000-03-28 *)
      c_ignore_svp      = true;
 
 
(*------------------------------*) 
 
PROCEDURE
      b75ilread_lock_index (VAR current : tbd_current_tree;
            indexnode      : tsp00_PageNo;
            suspend_reason : tsp00_Int2);
 
VAR
      do_suspend : boolean;
      partition  : integer;
      root_desc  : tbd7_root_desc;
 
BEGIN
WITH current, curr_trans^ DO
    BEGIN
    b06check_vresume_cnt (trTaskId_gg00);
    do_suspend := false;
    partition  := curr_tree_id.fileRoot_gg00 MOD b75region_cnt;
    vbegexcl (trTaskId_gg00, g08tree1 + partition);
&   ifdef TRACE
    g08excl_check (trTaskId_gg00, g08tree1 + partition);
&   endif
    (* *)
    b77root_description (curr_tree_id.fileRoot_gg00, root_desc);
    IF  bd75is_whole_subtree_locked (root_desc, indexnode)
    THEN
        BEGIN
        do_suspend := true;
        (* PTS 1106058 TS 2000-03-28 *)
        b76riconv_to_index_req (root_desc, trTaskId_gg00,
              indexnode, r_lock_index, NOT c_excl_lock_exist);
        (* PTS 1106058 *)
        bd75set_vprio (root_desc)
        END
    ELSE
        b77liconv_to_index_lock (root_desc, trTaskId_gg00,
              indexnode, r_lock_index);
    (*ENDIF*) 
&   ifdef TRACE
    b77check_locklist (root_desc);
&   else
    IF  g01glob.bd_lock_check
    THEN
        b77check_locklist (root_desc);
&   endif
    (*ENDIF*) 
    vendexcl (trTaskId_gg00, g08tree1 + partition);
    curr_node_locked  := indexnode;
    curr_lvl_1_locked := indexnode;
    curr_lockstate    := r_lock_index;
    IF  do_suspend
    THEN
        BEGIN
        vsuspend (trTaskId_gg00, cgg_suspend_lvl_0, suspend_reason);
        END;
    (*ENDIF*) 
    b06check_vresume_cnt (trTaskId_gg00);
    END
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      b75ilwrite_lock_index (VAR current : tbd_current_tree;
            leaf            : tsp00_PageNo;
            indexnode       : tsp00_PageNo;
            VAR lock_return : tbd_lock_returncode;
            suspend_reason  : tsp00_Int2);
 
VAR
      resume           : boolean;
      split_found      : boolean;
      windex_requested : boolean;
      windex_locked    : boolean;
      wleaf_locked     : boolean;
      tree_partition   : integer;
      split_partition  : integer;
      root_desc        : tbd7_root_desc;
 
BEGIN
split_found     := false;
wleaf_locked    := false;
windex_locked   := false;
resume          := false;
tree_partition  := current.curr_tree_id.fileRoot_gg00 MOD b75region_cnt;
split_partition := tree_partition;
WITH current, curr_trans^, b77locklist [tree_partition] DO
    BEGIN
    b06check_vresume_cnt (curr_trans^.trTaskId_gg00);
    IF  trBdExclFileLocks_gg00 = 0
    THEN
        BEGIN
        vbegexcl (curr_trans^.trTaskId_gg00, g08split1 + split_partition);
        vbegexcl (curr_trans^.trTaskId_gg00, g08tree1 + tree_partition);
        IF  tll_prevent_split
        THEN
            BEGIN
            tll_pid_request := curr_trans^.trTaskId_gg00;
            vendexcl (curr_trans^.trTaskId_gg00, g08tree1 + tree_partition);
            vsuspend (curr_trans^.trTaskId_gg00, cgg_suspend_lvl_0, 179);
            vbegexcl (curr_trans^.trTaskId_gg00, g08tree1 + tree_partition);
            END
        (*ENDIF*) 
        END
    ELSE
        vbegexcl (trTaskId_gg00, g08tree1 + tree_partition);
    (*ENDIF*) 
&   ifdef TRACE
    g08excl_check (curr_trans^.trTaskId_gg00,g08tree1 + tree_partition);
&   endif
    (* *)
    b77root_description (curr_tree_id.fileRoot_gg00, root_desc);
    windex_requested := b76is_index_requested (root_desc, indexnode, w_lock_index);
    b77index_or_leaf_writers (root_desc, curr_trans^.trTaskId_gg00, windex_locked, wleaf_locked);
    IF  windex_requested                                     OR
        b76is_leaf_requested (root_desc, leaf, w_lock_leaf)  OR
        b76is_leaf_requested (root_desc, leaf, r_lock_leaf)
        OR
        (b76is_tree_requested (root_desc, s_lock_tree)        AND
        NOT windex_locked                                     AND
        NOT wleaf_locked)
    THEN
        BEGIN
        (* PTS 1106058 TS 2000-03-28 *)
        b76riconv_to_index_req (root_desc, curr_trans^.trTaskId_gg00,
              indexnode, w_lock_index,  (0 < trBdExclFileLocks_gg00));
        (* PTS 1106058  *)
        bd75set_vprio (root_desc);
        IF  b76is_leaf_requested (root_desc, leaf, r_lock_leaf)
        THEN
            BEGIN
            IF  windex_requested
            THEN
                lock_return := lock_failed
            ELSE
                lock_return := lock_dirty;
            (*ENDIF*) 
            b76lrstart_read_leaf (root_desc, leaf, resume);
            IF  (NOT wleaf_locked) AND (NOT windex_locked)
            THEN
                b76start_tree (root_desc, s_lock_tree,
                      split_found, resume)
            (*ENDIF*) 
            END
        ELSE
            BEGIN
            IF  b76is_tree_requested (root_desc, s_lock_tree) AND
                NOT wleaf_locked                              AND
                NOT windex_locked
            THEN
                BEGIN
                IF  windex_requested
                THEN
                    lock_return := lock_failed
                ELSE
                    lock_return := lock_dirty;
                (*ENDIF*) 
                b76start_tree (root_desc, s_lock_tree,
                      split_found, resume)
                END
            ELSE
                IF  b76is_leaf_requested (root_desc, leaf, w_lock_leaf)
                THEN
                    BEGIN
                    IF  windex_requested
                    THEN
                        lock_return := lock_failed
                    ELSE
                        lock_return := lock_dirty;
                    (*ENDIF*) 
                    IF  NOT b77stree_in_locklist (root_desc)
                    THEN
                        b76lwstart_write_leaf (root_desc, leaf, resume)
                    (*ENDIF*) 
                    END
                ELSE
                    BEGIN
                    lock_return := lock_failed;
                    IF  NOT b77exist_lock_within_subtree (
                        trTaskId_gg00, root_desc, indexnode)
                    THEN
                        b76istart_index (root_desc, indexnode,
                              w_lock_index, split_found, resume)
                    (*ENDIF*) 
                    END
                (*ENDIF*) 
            (*ENDIF*) 
            END
        (*ENDIF*) 
        END
    ELSE
        IF  NOT b77exist_lock_within_subtree (trTaskId_gg00, root_desc, indexnode)
        THEN
            BEGIN
            lock_return := lock_okay;
            b77liconv_to_index_lock (root_desc, curr_trans^.trTaskId_gg00,
                  indexnode, w_lock_index)
            END
        ELSE
            BEGIN
            lock_return := lock_dirty;
            (* PTS 1106058 TS 2000-03-28 *)
            b76riconv_to_index_req (root_desc, curr_trans^.trTaskId_gg00,
                  indexnode, w_lock_index,  (0 < trBdExclFileLocks_gg00));
            (* PTS 1106058  *)
            bd75set_vprio (root_desc)
            END;
        (*ENDIF*) 
    (*ENDIF*) 
&   ifdef TRACE
    b77check_locklist (root_desc);
&   else
    IF  g01glob.bd_lock_check
    THEN
        b77check_locklist (root_desc);
&   endif
    (*ENDIF*) 
    vendexcl (curr_trans^.trTaskId_gg00, g08tree1 + tree_partition);
    IF  trBdExclFileLocks_gg00 = 0
    THEN
        vendexcl (curr_trans^.trTaskId_gg00, g08split1 + split_partition);
    (*ENDIF*) 
    trBdExclFileLocks_gg00 := trBdExclFileLocks_gg00 + 1;
    curr_node_locked      := indexnode;
    curr_lvl_1_locked     := indexnode;
    curr_lockstate        := w_lock_index;
    IF  lock_return <> lock_okay
    THEN
        vsuspend (curr_trans^.trTaskId_gg00, cgg_suspend_lvl_0, suspend_reason);
    (*ENDIF*) 
    b06check_vresume_cnt (curr_trans^.trTaskId_gg00);
    END
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      b75init_tree_locklist (pid : tsp00_TaskId;
            VAR e : tgg00_BasisError);
 
VAR
      partition : integer;
      alloc_sum : tsp00_Int4;
 
BEGIN
b75region_cnt := g01region_cnt (rgnTree_egg00);
IF  (b75region_cnt < 1) OR (b75region_cnt > cbd7_max_partition)
THEN
    g01abort (csp3_b75x1_invalid_region_cnt, csp3_n_config,
          'TREE_REGIONS invalid:   ', b75region_cnt);
(*ENDIF*) 
alloc_sum := 0;
partition := 0;
WHILE ((partition < b75region_cnt) AND (e = e_ok)) DO
    BEGIN
    vbegexcl (pid, g08tree1 + partition);
    b77init_tree_locklist (partition, alloc_sum, e);
    vendexcl (pid, g08tree1 + partition);
    partition := succ (partition)
    END;
(*ENDWHILE*) 
IF  alloc_sum > 0
THEN
    BEGIN
    g01allocate_msg (csp3_n_dynpool, 'TREE_LOCK region count :',
          b75region_cnt);
    g01allocate_msg (csp3_n_dynpool, 'DYNP_B77_TREE_LOCK     :',
          alloc_sum)
    END
(*ENDIF*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      b75iuiread_unlocklock_index (VAR current : tbd_current_tree;
            src_index      : tsp00_PageNo;
            dest_index     : tsp00_PageNo;
            suspend_reason : tsp00_Int2);
 
VAR
      do_suspend  : boolean;
      partition   : integer;
      resume      : boolean;
      split_found : boolean;
      leaf        : tsp00_PageNo;
      root_desc   : tbd7_root_desc;
 
BEGIN
WITH current, curr_trans^ DO
    BEGIN
    b06check_vresume_cnt (trTaskId_gg00);
    do_suspend  := false;
    resume      := false;
    split_found := false;
    leaf        := NIL_PAGE_NO_GG00;
    partition   := curr_tree_id.fileRoot_gg00 MOD b75region_cnt;
    vbegexcl (trTaskId_gg00, g08tree1 + partition);
&   ifdef TRACE
    g08excl_check (trTaskId_gg00, g08tree1 + partition);
    IF  NOT (ftsDynamic_egg00 IN curr_tree_id.fileType_gg00) OR
        NOT  g01glob.bd_subtree
    THEN
        g01abort (csp3_b75x1_illegal_index_lock, csp3_n_treelock,
              'illegal index lock(root)', curr_tree_id.fileRoot_gg00);
&   endif
    (* *)
    (*ENDIF*) 
    b77root_description (curr_tree_id.fileRoot_gg00, root_desc);
    IF  NOT b77exist_lock_within_subtree (trTaskId_gg00, root_desc, src_index)
    THEN
        b76istart_index (root_desc, src_index, w_lock_index, split_found, resume);
    (*ENDIF*) 
    IF  b77write_index_locked (root_desc, dest_index)
    THEN
        BEGIN
        do_suspend := true;
        b77delete_lockentry (trTaskId_gg00, root_desc,
              leaf, src_index, r_lock_index);
        b76insert_requestentry (trTaskId_gg00, root_desc,
              leaf, dest_index, r_lock_index, NOT c_ignore_svp,
              NOT c_excl_lock_exist);  (* PTS 1106058 TS 2000-03-28 *)
        bd75set_vprio (root_desc)
        END
    ELSE
        b77liconv_to_index_lock (root_desc, trTaskId_gg00,
              dest_index, r_lock_index);
    (*ENDIF*) 
&   ifdef TRACE
    b77check_locklist (root_desc);
&   else
    IF  g01glob.bd_lock_check
    THEN
        b77check_locklist (root_desc);
&   endif
    (*ENDIF*) 
    vendexcl (trTaskId_gg00, g08tree1 + partition);
    curr_node_locked  := dest_index;
    curr_lvl_1_locked := dest_index;
    IF  do_suspend
    THEN
        vsuspend (trTaskId_gg00, cgg_suspend_lvl_0, suspend_reason);
    (*ENDIF*) 
    b06check_vresume_cnt (trTaskId_gg00);
    END
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      b75iuread_unlock_index (VAR current : tbd_current_tree;
            indexnode       : tsp00_PageNo);
 
VAR
      resumed     : boolean;
      split_found : boolean;
      partition   : integer;
      leaf        : tsp00_PageNo;
      root_desc   : tbd7_root_desc;
 
BEGIN
WITH current, curr_trans^ DO
    BEGIN
    b06check_vresume_cnt (trTaskId_gg00);
    resumed      := false;
    split_found := false;
    leaf         := NIL_PAGE_NO_GG00;
    partition    := curr_tree_id.fileRoot_gg00 MOD b75region_cnt;
    vbegexcl (trTaskId_gg00, g08tree1 + partition);
&   ifdef TRACE
    g08excl_check (trTaskId_gg00, g08tree1 + partition);
&   endif
    (* *)
    b77root_description (curr_tree_id.fileRoot_gg00, root_desc);
    b77delete_lockentry (trTaskId_gg00, root_desc, leaf, indexnode, r_lock_index);
    IF  NOT b77exist_lock_within_subtree (trTaskId_gg00, root_desc, indexnode)
    THEN
        BEGIN
        IF  NOT b76is_empty_requestlist (root_desc)
        THEN
            BEGIN
            b76istart_index (root_desc, indexnode, w_lock_index,
                  split_found, resumed);
            IF  NOT split_found AND b77is_empty_locklist (root_desc)
            THEN
                b76start_tree (root_desc, w_lock_tree,
                      split_found, resumed);
            (*ENDIF*) 
            IF  (NOT split_found) AND (NOT resumed)
            THEN
                b76start_tree (root_desc, d_lock_tree,
                      split_found, resumed)
            (*ENDIF*) 
            END
        (*ENDIF*) 
        END;
&   ifdef TRACE
    (*ENDIF*) 
    b77check_locklist (root_desc);
&   else
    IF  g01glob.bd_lock_check
    THEN
        b77check_locklist (root_desc);
&   endif
    (*ENDIF*) 
    vendexcl (trTaskId_gg00, g08tree1 + partition);
    curr_node_locked  := NIL_PAGE_NO_GG00;
    curr_lvl_1_locked := NIL_PAGE_NO_GG00;
    curr_lockstate    := no_bd_lock;
    b06check_vresume_cnt (trTaskId_gg00);
    END
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      b75iuwrite_unlock_index (VAR current : tbd_current_tree;
            indexnode       : tsp00_PageNo);
 
VAR
      resumed     : boolean;
      index_found : boolean;
      leaf_found  : boolean;
      split_found : boolean;
      partition   : integer;
      dummy_leaf  : tsp00_PageNo;
      root_desc   : tbd7_root_desc;
 
BEGIN
WITH current, curr_trans^ DO
    BEGIN
    b06check_vresume_cnt (curr_trans^.trTaskId_gg00);
    resumed     := false;
    index_found := false;
    leaf_found  := false;
    split_found := false;
    dummy_leaf  := NIL_PAGE_NO_GG00;
    partition   := curr_tree_id.fileRoot_gg00 MOD b75region_cnt;
    vbegexcl (trTaskId_gg00, g08tree1 + partition);
&   ifdef TRACE
    g08excl_check (trTaskId_gg00, g08tree1 + partition);
&   endif
    (* *)
    b77root_description (curr_tree_id.fileRoot_gg00, root_desc);
    b77delete_lockentry (trTaskId_gg00, root_desc, dummy_leaf,
          indexnode, w_lock_index);
    IF  NOT b76is_empty_requestlist (root_desc)
    THEN
        BEGIN
        b76istart_index (root_desc, indexnode, w_lock_index,
              split_found, resumed);
        IF  (NOT resumed)
        THEN
            BEGIN
            b76istart_index (root_desc, indexnode, r_lock_index, split_found, resumed);
            b77index_or_leaf_writers (root_desc, trTaskId_gg00, index_found, leaf_found);
            IF  (NOT index_found) AND (NOT leaf_found)
            THEN
                b76start_tree (root_desc, s_lock_tree, split_found, resumed);
            (*ENDIF*) 
            IF  (NOT resumed) AND (NOT split_found) AND b77is_empty_locklist (root_desc)
            THEN
                BEGIN
                b76start_tree (root_desc, w_lock_tree, split_found, resumed);
                IF  (NOT resumed) AND (NOT split_found)
                THEN
                    b76start_tree (root_desc, d_lock_tree, split_found, resumed)
                (*ENDIF*) 
                END
            (*ENDIF*) 
            END
        (*ENDIF*) 
        END;
&   ifdef TRACE
    (*ENDIF*) 
    b77check_locklist (root_desc);
&   else
    IF  g01glob.bd_lock_check
    THEN
        b77check_locklist (root_desc);
&   endif
    (*ENDIF*) 
    vendexcl (trTaskId_gg00, g08tree1 + partition);
    trBdExclFileLocks_gg00 := trBdExclFileLocks_gg00 - 1;
    curr_node_locked      := NIL_PAGE_NO_GG00;
    curr_lvl_1_locked     := NIL_PAGE_NO_GG00;
    curr_lockstate        := no_bd_lock;
    WITH curr_tree_id DO
        IF  (trError_gg00 = e_ok                   ) AND
            (tsSaveptWanted_egg00 IN trState_gg00  ) AND
            NOT (hsNoLog_egg00 IN fileHandling_gg00) (* PTS 1001949 UH 18-01-1999 *)
        THEN
            BEGIN
            trState_gg00 := trState_gg00 - [tsSaveptWanted_egg00];
            kb560StartSavepoint (curr_trans^, mm_lock);
            END;
        (*ENDIF*) 
    (*ENDWITH*) 
    b06check_vresume_cnt (curr_trans^.trTaskId_gg00);
    END
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      b75llread_lock_leaf (VAR current : tbd_current_tree;
            leaf           : tsp00_PageNo;
            suspend_reason : tsp00_Int2);
 
VAR
      do_suspend  : boolean;
      partition   : integer;
      dummy_leaf  : tsp00_PageNo;
      root_desc   : tbd7_root_desc;
 
BEGIN
WITH current DO
    BEGIN
    b06check_vresume_cnt (curr_trans^.trTaskId_gg00);
    do_suspend := false;
    partition  := curr_tree_id.fileRoot_gg00 MOD b75region_cnt;
    vbegexcl (curr_trans^.trTaskId_gg00, g08tree1 + partition);
&   ifdef TRACE
    g08excl_check (curr_trans^.trTaskId_gg00, g08tree1 + partition);
&   endif
    (* *)
    b77root_description (curr_tree_id.fileRoot_gg00, root_desc);
    IF  b77lleaf_in_locklist (root_desc, leaf, w_lock_leaf, curr_trans^.trTaskId_gg00)
        OR
        b76is_leaf_requested (root_desc, leaf, w_lock_leaf)
    THEN
        BEGIN
        do_suspend := true;
        dummy_leaf := NIL_PAGE_NO_GG00;
        b77delete_lockentry (curr_trans^.trTaskId_gg00, root_desc,
              dummy_leaf, curr_lvl_1_locked, curr_lockstate);
        b76insert_requestentry (curr_trans^.trTaskId_gg00, root_desc, leaf,
              curr_lvl_1_locked, r_lock_leaf, NOT c_ignore_svp,
              NOT c_excl_lock_exist);  (* PTS 1106058 TS 2000-03-28 *)
        bd75set_vprio (root_desc)
        END
    ELSE
        b77lconv_to_leaf (curr_trans^.trTaskId_gg00, root_desc,
              leaf, cbd7_dummy_index, r_lock_leaf);
    (*ENDIF*) 
&   ifdef TRACE
    b77check_locklist (root_desc);
    b77index_check (current, root_desc);
&   else
    IF  g01glob.bd_lock_check
    THEN
        BEGIN
        b77check_locklist (root_desc);
        b77index_check (current, root_desc)
        END;
&   endif
    (*ENDIF*) 
    vendexcl (curr_trans^.trTaskId_gg00, g08tree1 + partition);
    curr_node_locked := leaf;
    curr_lockstate   := r_lock_leaf;
    IF  do_suspend
    THEN
        vsuspend (curr_trans^.trTaskId_gg00, cgg_suspend_lvl_0, suspend_reason);
    (*ENDIF*) 
    b06check_vresume_cnt (curr_trans^.trTaskId_gg00);
    END
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      b75llwrite_lock_leaf (VAR current : tbd_current_tree;
            leaf           : tsp00_PageNo;
            suspend_reason : tsp00_Int2);
 
VAR
      do_suspend  : boolean;
      partition   : integer;
      dummy_leaf  : tsp00_PageNo;
      root_desc   : tbd7_root_desc;
 
BEGIN
WITH current DO
    BEGIN
    b06check_vresume_cnt (curr_trans^.trTaskId_gg00);
    do_suspend := false;
    partition  := curr_tree_id.fileRoot_gg00 MOD b75region_cnt;
    vbegexcl (curr_trans^.trTaskId_gg00, g08tree1 + partition);
&   ifdef TRACE
    g08excl_check (curr_trans^.trTaskId_gg00, g08tree1 + partition);
&   endif
    (* *)
    b77root_description (curr_tree_id.fileRoot_gg00, root_desc);
    IF  b77leaf_in_locklist (root_desc, leaf, curr_trans^.trTaskId_gg00) OR
        b76is_tree_requested (root_desc, s_lock_tree)                OR
        b77stree_in_locklist (root_desc)
    THEN
        BEGIN
        do_suspend := true;
        dummy_leaf := NIL_PAGE_NO_GG00;
        b77delete_lockentry (curr_trans^.trTaskId_gg00, root_desc,
              dummy_leaf, curr_lvl_1_locked, curr_lockstate);
        b76insert_requestentry (curr_trans^.trTaskId_gg00, root_desc, leaf,
              curr_lvl_1_locked, w_lock_leaf, NOT c_ignore_svp,
              NOT c_excl_lock_exist);  (* PTS 1106058 TS 2000-03-28 *)
        bd75set_vprio (root_desc)
        END
    ELSE
        b77lconv_to_leaf (curr_trans^.trTaskId_gg00, root_desc, leaf,
              cbd7_dummy_index, w_lock_leaf);
    (*ENDIF*) 
&   ifdef TRACE
    b77check_locklist (root_desc);
    b77index_check (current, root_desc);
&   else
    IF  g01glob.bd_lock_check
    THEN
        BEGIN
        b77check_locklist (root_desc);
        b77index_check (current, root_desc)
        END;
&   endif
    (*ENDIF*) 
    vendexcl (curr_trans^.trTaskId_gg00, g08tree1 + partition);
    curr_node_locked := leaf;
    curr_lockstate   := w_lock_leaf;
    IF  do_suspend
    THEN
        vsuspend (curr_trans^.trTaskId_gg00, cgg_suspend_lvl_0, suspend_reason);
    (*ENDIF*) 
    b06check_vresume_cnt (curr_trans^.trTaskId_gg00);
    END
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      b75lulread_unlocklock_leaf (VAR current : tbd_current_tree;
            src_leaf       : tsp00_PageNo;
            src_index      : tsp00_PageNo;
            dest_leaf      : tsp00_PageNo;
            dest_index     : tsp00_PageNo;
            suspend_reason : tsp00_Int2);
 
VAR
      do_suspend  : boolean;
      partition   : integer;
      resume      : boolean;
      split_found : boolean;
      valid       : boolean;
      root_desc   : tbd7_root_desc;
 
BEGIN
WITH current, curr_tree_id DO
    BEGIN
    b06check_vresume_cnt (curr_trans^.trTaskId_gg00);
    do_suspend  := false;
    resume      := false;
    split_found := false;
    partition   := fileRoot_gg00 MOD b75region_cnt;
    vbegexcl (curr_trans^.trTaskId_gg00, g08tree1 + partition);
&   ifdef TRACE
    g08excl_check (curr_trans^.trTaskId_gg00, g08tree1 + partition);
&   endif
    IF  g01vtrace.vtrCheck_gg00 OR g01glob.bd_lock_check
    THEN
        BEGIN
        IF  (src_index <> dest_index)
            AND
            (src_index <> NIL_PAGE_NO_GG00)
            AND
            (dest_index <> NIL_PAGE_NO_GG00)
            AND
            (ftsDynamic_egg00 IN curr_tree_id.fileType_gg00)
            AND
            g01glob.bd_subtree
        THEN
            valid := false
        ELSE
            valid := true;
        (*ENDIF*) 
        g01check (csp3_b75c1_illegal_call, csp3_n_treelock,
              'B75: subtree boundary!  ', 0, valid)
        END;
    (* *)
    (*ENDIF*) 
    b77root_description (fileRoot_gg00, root_desc);
    IF  NOT b77lleaf_in_locklist (root_desc, src_leaf, r_lock_leaf,
        curr_trans^.trTaskId_gg00)
    THEN
        BEGIN
        IF  NOT b77stree_in_locklist (root_desc)
        THEN
            b76lwstart_write_leaf (root_desc, src_leaf, resume)
        (*ENDIF*) 
        END;
    (*ENDIF*) 
    IF  b77lleaf_in_locklist (root_desc, dest_leaf, w_lock_leaf,
        curr_trans^.trTaskId_gg00)
    THEN
        BEGIN
        do_suspend := true;
        b77delete_lockentry (curr_trans^.trTaskId_gg00, root_desc,
              src_leaf, curr_lvl_1_locked, r_lock_leaf);
        b76insert_requestentry (curr_trans^.trTaskId_gg00, root_desc,
              dest_leaf, curr_lvl_1_locked, r_lock_leaf, NOT c_ignore_svp,
              NOT c_excl_lock_exist);  (* PTS 1106058 TS 2000-03-28 *)
        bd75set_vprio (root_desc)
        END
    ELSE
        b77lconv_to_leaf (curr_trans^.trTaskId_gg00, root_desc, dest_leaf,
              dest_index, r_lock_leaf);
    (*ENDIF*) 
&   ifdef TRACE
    b77check_locklist (root_desc);
&   else
    IF  g01glob.bd_lock_check
    THEN
        b77check_locklist (root_desc);
&   endif
    (*ENDIF*) 
    vendexcl (curr_trans^.trTaskId_gg00, g08tree1 + partition);
    curr_node_locked := dest_leaf;
    IF  do_suspend
    THEN
        vsuspend (curr_trans^.trTaskId_gg00, cgg_suspend_lvl_0, suspend_reason);
    (*ENDIF*) 
    b06check_vresume_cnt (curr_trans^.trTaskId_gg00);
    END
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      b75luread_unlock_leaf (VAR current : tbd_current_tree;
            leaf : tsp00_PageNo);
 
VAR
      partition   : integer;
      split_found : boolean;
      resume      : boolean;
      root_desc   : tbd7_root_desc;
 
BEGIN
WITH current, curr_tree_id, curr_trans^ DO
    BEGIN
    b06check_vresume_cnt (curr_trans^.trTaskId_gg00);
    resume      := false;
    split_found := false;
    partition   := fileRoot_gg00 MOD b75region_cnt;
    vbegexcl (trTaskId_gg00, g08tree1 + partition);
&   ifdef TRACE
    g08excl_check (trTaskId_gg00, g08tree1 + partition);
&   endif
    (* *)
    b77root_description (fileRoot_gg00, root_desc);
    b77delete_lockentry (trTaskId_gg00, root_desc, leaf, curr_lvl_1_locked, r_lock_leaf);
    IF  NOT b77lleaf_in_locklist (root_desc, leaf, r_lock_leaf, trTaskId_gg00)
    THEN
        BEGIN
        IF  NOT b77stree_in_locklist (root_desc)
        THEN
            BEGIN
            b76lwstart_write_leaf (root_desc, leaf, resume);
            IF  NOT resume
                AND
                (ftsDynamic_egg00 IN fileType_gg00)
                AND
                g01glob.bd_subtree
                AND
                NOT b77exist_lock_within_subtree (
                trTaskId_gg00, root_desc, curr_lvl_1_locked)
            THEN
                b76istart_index (root_desc, curr_lvl_1_locked,
                      w_lock_index, split_found, resume);
            (*ENDIF*) 
            IF  (NOT resume) AND (NOT split_found)
            THEN
                IF  b77is_empty_locklist (root_desc)
                THEN
                    BEGIN
                    b76start_tree (root_desc, w_lock_tree, split_found, resume);
                    IF  (NOT split_found) AND (NOT resume)
                    THEN
                        b76start_tree (root_desc, d_lock_tree, split_found, resume);
                    (*ENDIF*) 
                    END
                (*ENDIF*) 
            (*ENDIF*) 
            END
        (*ENDIF*) 
        END;
&   ifdef TRACE
    (*ENDIF*) 
    b77check_locklist (root_desc);
&   else
    IF  g01glob.bd_lock_check
    THEN
        b77check_locklist (root_desc);
&   endif
    (*ENDIF*) 
    vendexcl (trTaskId_gg00, g08tree1 + partition);
    curr_node_locked  := NIL_PAGE_NO_GG00;
    curr_lvl_1_locked := NIL_PAGE_NO_GG00;
    curr_lockstate    := no_bd_lock;
    b06check_vresume_cnt (trTaskId_gg00);
    END
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      b75luwrite_unlock_leaf (VAR current : tbd_current_tree;
            leaf : tsp00_PageNo);
 
VAR
      partition     : integer;
      resume        : boolean;
      split_found   : boolean;
      wleaf_locked  : boolean;
      windex_locked : boolean;
      root_desc     : tbd7_root_desc;
 
BEGIN
WITH current, curr_trans^, curr_tree_id DO
    BEGIN
    b06check_vresume_cnt (curr_trans^.trTaskId_gg00);
    windex_locked := false;
    wleaf_locked  := false;
    resume        := false;
    split_found   := false;
    partition     := fileRoot_gg00 MOD b75region_cnt;
    vbegexcl (trTaskId_gg00, g08tree1 + partition);
&   ifdef TRACE
    g08excl_check (trTaskId_gg00, g08tree1 + partition);
&   endif
    (* *)
    b77root_description (fileRoot_gg00, root_desc);
    b77delete_lockentry (trTaskId_gg00, root_desc, leaf,
          curr_lvl_1_locked, w_lock_leaf);
    IF  NOT  b76is_empty_requestlist (root_desc)
    THEN
        BEGIN
        b76lrstart_read_leaf (root_desc, leaf, resume);
        IF  (ftsDynamic_egg00 IN fileType_gg00)
            AND
            g01glob.bd_subtree
        THEN
            b77index_or_leaf_writers (root_desc, trTaskId_gg00,
                  windex_locked, wleaf_locked)
        ELSE
            wleaf_locked := b77anyleaf_write_locks (root_desc);
        (*ENDIF*) 
        IF  NOT (windex_locked) AND (NOT wleaf_locked)
        THEN
            b76start_tree (root_desc, s_lock_tree,
                  split_found, resume);
        (*ENDIF*) 
        IF  NOT (resume OR b77stree_in_locklist (root_desc))
        THEN
            BEGIN
            b76lwstart_write_leaf (root_desc, leaf, resume);
            IF  NOT resume
                AND
                (ftsDynamic_egg00 IN curr_tree_id.fileType_gg00)
                AND
                g01glob.bd_subtree
                AND
                NOT b77exist_lock_within_subtree (trTaskId_gg00,
                root_desc, curr_lvl_1_locked)
            THEN
                b76istart_index (root_desc, curr_lvl_1_locked,
                      w_lock_index, split_found, resume);
            (*ENDIF*) 
            IF  (NOT resume) AND (NOT split_found)
            THEN
                IF  b77is_empty_locklist (root_desc)
                THEN
                    BEGIN
                    b76start_tree (root_desc, w_lock_tree,
                          split_found, resume);
                    IF  (NOT split_found) AND (NOT resume)
                    THEN
                        b76start_tree (root_desc, d_lock_tree,
                              split_found, resume)
                    (*ENDIF*) 
                    END
                (*ENDIF*) 
            (*ENDIF*) 
            END
        (*ENDIF*) 
        END;
&   ifdef TRACE
    (*ENDIF*) 
    b77check_locklist (root_desc);
&   else
    IF  g01glob.bd_lock_check
    THEN
        b77check_locklist (root_desc);
&   endif
    (*ENDIF*) 
    vendexcl (trTaskId_gg00, g08tree1 + partition);
    curr_node_locked  := NIL_PAGE_NO_GG00;
    curr_lvl_1_locked := NIL_PAGE_NO_GG00;
    curr_lockstate    := no_bd_lock;
    b06check_vresume_cnt (curr_trans^.trTaskId_gg00);
    WITH curr_tree_id DO
        IF  (trError_gg00 = e_ok                   ) AND
            (tsSaveptWanted_egg00 IN trState_gg00  ) AND
            NOT (hsNoLog_egg00 IN fileHandling_gg00) (* PTS 1001949 UH 18-01-1999 *)
        THEN
            BEGIN
            trState_gg00 := trState_gg00 - [tsSaveptWanted_egg00];
            kb560StartSavepoint (curr_trans^, mm_lock);
            END;
        (*ENDIF*) 
    (*ENDWITH*) 
    END
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
FUNCTION
      b75exclusive_locks (pid : tsp00_TaskId) : boolean;
 
VAR
      lock_found  : boolean;
      partition   : integer;
 
BEGIN
partition  := 0;
lock_found := false;
WHILE (partition < b75region_cnt) AND (NOT lock_found) DO
    BEGIN
    vbegexcl (pid, g08tree1 + partition);
    WITH  b77locklist [partition] DO
        BEGIN
        lock_found := (tll_split_counter - tll_svp_ignore_cnt) > 0;
        IF  (tll_split_counter < 0) OR (tll_svp_ignore_cnt < 0)
        THEN
            g01abort (csp3_b75x1_counter_mismatch, csp3_n_treelock,
                  'B75EXCLUS: cnt mismatch:', 0)
        (*ENDIF*) 
        END;
    (*ENDWITH*) 
    vendexcl (pid, g08tree1 + partition);
    partition := succ (partition)
    END;
(*ENDWHILE*) 
b75exclusive_locks := lock_found
END;
 
(*------------------------------*) 
 
PROCEDURE
      b75rdelete_lock_requests (pid : tsp00_TaskId);
 
VAR
      partition : integer;
 
BEGIN
b75resume (pid);
FOR partition := 0 TO (b75region_cnt - 1) DO
    BEGIN
    vbegexcl (pid, g08tree1 + partition);
&   ifdef TRACE
    g08excl_check (pid, g08tree1 + partition);
&   endif
    b76delete_requestentries;
    vendexcl (pid, g08tree1 + partition)
    END
(*ENDFOR*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      b75reset_lock (VAR current : tbd_current_tree;
            leaf      : tsp00_PageNo);
 
VAR
      windex_locked : boolean;
      wleaf_locked  : boolean;
      split_found   : boolean;
      resume        : boolean;
      partition     : integer;
      old_locktype  : tbd_treelock;
      root_desc     : tbd7_root_desc;
 
BEGIN
WITH current, curr_trans^, curr_tree_id DO
    BEGIN
    b06check_vresume_cnt (curr_trans^.trTaskId_gg00);
    windex_locked := false;
    wleaf_locked  := false;
    resume        := false;
    split_found   := false;
    old_locktype  := r_lock_tree;
    partition     := curr_tree_id.fileRoot_gg00 MOD b75region_cnt;
    vbegexcl (trTaskId_gg00, g08tree1 + partition);
&   ifdef TRACE
    g08excl_check (trTaskId_gg00, g08tree1 + partition);
&   endif
    (* *)
    b77root_description (curr_tree_id.fileRoot_gg00, root_desc);
    b77reset_lock (trTaskId_gg00, root_desc, old_locktype);
    IF  g01glob.bd_lock_check
    THEN
        IF  curr_lockstate <> old_locktype
        THEN
            g01abort (csp3_b75x1_lockstate_mismatch, csp3_n_treelock,
                  'B75RESET: type mismatch:', ord (curr_lockstate));
        (*ENDIF*) 
    (*ENDIF*) 
    CASE old_locktype OF
        w_lock_tree, d_lock_tree :
            BEGIN
            b76readers_start (root_desc, resume)
            END;
        w_lock_index :
            BEGIN
            b76istart_index (root_desc, curr_lvl_1_locked,
                  w_lock_index, split_found, resume);
            IF  NOT resume
            THEN
                BEGIN
                b76istart_index (root_desc, curr_lvl_1_locked,
                      r_lock_index, split_found, resume);
                b77index_or_leaf_writers (root_desc,
                      trTaskId_gg00, windex_locked,
                      wleaf_locked);
                IF  (NOT windex_locked) AND (NOT wleaf_locked)
                THEN
                    b76start_tree (root_desc, s_lock_tree,
                          split_found, resume)
                (*ENDIF*) 
                END
            (*ENDIF*) 
            END;
        w_lock_leaf :
            BEGIN
            b76lrstart_read_leaf (root_desc, leaf, resume);
            IF  (ftsDynamic_egg00 IN fileType_gg00)
                AND
                g01glob.bd_subtree
            THEN
                b77index_or_leaf_writers (root_desc,
                      trTaskId_gg00, windex_locked, wleaf_locked)
            ELSE
                wleaf_locked := b77anyleaf_write_locks (root_desc);
            (*ENDIF*) 
            IF  (NOT windex_locked) AND (NOT wleaf_locked)
            THEN
                b76start_tree (root_desc, s_lock_tree,
                      split_found, resume);
            (*ENDIF*) 
            IF  NOT (resume OR b77stree_in_locklist (root_desc))
            THEN
                BEGIN
                b76lwstart_write_leaf (root_desc, leaf, resume);
                IF  (ftsDynamic_egg00 IN fileType_gg00)
                    AND
                    (NOT b77exist_lock_within_subtree(
                    trTaskId_gg00, root_desc, curr_lvl_1_locked))
                    AND
                    g01glob.bd_subtree
                THEN
                    b76istart_index (root_desc, curr_lvl_1_locked,
                          w_lock_index, split_found, resume)
                (*ENDIF*) 
                END
            (*ENDIF*) 
            END;
        r_lock_index :
            BEGIN
            (* PTS 1107109 TS 2000-07-20 *)
            IF  NOT b77exist_lock_within_subtree (
                trTaskId_gg00, root_desc, curr_lvl_1_locked)
            THEN
                b76istart_index (root_desc, curr_lvl_1_locked,
                      w_lock_index, split_found, resume);
            (* PTS 1107109 *)
            (*ENDIF*) 
            END;
        r_lock_leaf :
            BEGIN
            IF  (NOT b77lleaf_in_locklist (root_desc, leaf,
                r_lock_leaf, trTaskId_gg00))
                AND
                (NOT b77stree_in_locklist (root_desc))
            THEN
                BEGIN
                b76lwstart_write_leaf (root_desc, leaf,
                      resume);
                IF  NOT resume
                    AND
                    (ftsDynamic_egg00 IN fileType_gg00)
                    AND
                    g01glob.bd_subtree
                    AND
                    (NOT b77exist_lock_within_subtree (
                    trTaskId_gg00, root_desc, curr_lvl_1_locked))
                THEN
                    b76istart_index (root_desc, curr_lvl_1_locked,
                          w_lock_index, split_found, resume)
                (*ENDIF*) 
                END
            (*ENDIF*) 
            END;
        s_lock_tree :
            BEGIN
            IF   (NOT b77stree_in_locklist (root_desc))
            THEN
                BEGIN
                b76leaf_writers_start (root_desc, resume);
                IF  (ftsDynamic_egg00 IN fileType_gg00)
                    AND
                    g01glob.bd_subtree
                THEN
                    b76index_writers_start (root_desc,
                          resume, trTaskId_gg00)
                (*ENDIF*) 
                END
            (*ENDIF*) 
            END;
        OTHERWISE :
            ;
        END;
    (*ENDCASE*) 
&   ifdef TRACE
    b77check_locklist (root_desc);
&   else
    IF  g01glob.bd_lock_check
    THEN
        b77check_locklist (root_desc);
&   endif
    (*ENDIF*) 
    vendexcl (trTaskId_gg00, g08tree1 + partition);
    curr_node_locked  := NIL_PAGE_NO_GG00;
    curr_lvl_1_locked := NIL_PAGE_NO_GG00;
    curr_lockstate    := r_lock_tree;
    b06check_vresume_cnt (curr_trans^.trTaskId_gg00);
    IF  (old_locktype = w_lock_tree ) OR
        (old_locktype = d_lock_tree ) OR
        (old_locktype = w_lock_index)
    THEN
        trBdExclFileLocks_gg00 := trBdExclFileLocks_gg00 - 1;
    (*ENDIF*) 
    IF  (old_locktype = w_lock_tree              ) AND
        (current.currFreeQueue_bd00.fqTop_bd00 > 1)
    THEN
        b13free_pnos_after_unlock (current);
    (*ENDIF*) 
    END
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      b75resume (pid : tsp00_TaskId);
 
VAR
      partition : integer;
 
BEGIN
FOR partition := 0 TO b75region_cnt  - 1 DO
    BEGIN
    vbegexcl (pid, g08tree1 + partition);
&   ifdef TRACE
    g08excl_check (pid, g08tree1 + partition);
&   endif
    WITH b77locklist [partition] DO
        BEGIN
        IF  tll_pid_request <> 0
        THEN
            vresume (tll_pid_request, cgg_suspend_lvl_0);
        (*ENDIF*) 
        tll_prevent_split := false;
        tll_pid_request   := 0;
        IF  tll_resume_counter <> 0
        THEN
            b76resume_after_svp (pid, partition);
        (*ENDIF*) 
        END;
    (*ENDWITH*) 
    (* PTS 1107109 TS 2000-07-18 *)
&   ifdef TRACE
    b77check_whole_locklist (partition);
&   else
    IF  g01glob.bd_lock_check
    THEN
        b77check_whole_locklist (partition);
&   endif
    (* PTS 1107109 *)
    (*ENDIF*) 
    vendexcl (pid, g08tree1 + partition)
    END
(*ENDFOR*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      b75set_prevent_split (pid : tsp00_TaskId);
 
VAR
      partition : integer;
 
BEGIN
FOR partition := 0 TO b75region_cnt - 1 DO
    BEGIN
    vbegexcl (pid, g08tree1 + partition);
    b77locklist [partition].tll_prevent_split := true;
    vendexcl (pid, g08tree1 + partition)
    END
(*ENDFOR*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      b75show_treelocklist (VAR current : tbd_current_tree;
            VAR rec_count : tsp00_Int4);
 
VAR
      partition : integer;
 
BEGIN
WITH current, curr_trans^ DO
    BEGIN
    trError_gg00    := e_ok;
    partition := 0;
    rec_count := 0;
    REPEAT
        vbegexcl (trTaskId_gg00, g08tree1 + partition);
&       ifdef TRACE
        g08excl_check (trTaskId_gg00, g08tree1 + partition);
&       endif
        b77show_treelocklist (current, rec_count, partition);
        vendexcl (trTaskId_gg00, g08tree1 + partition);
        partition := succ (partition);
    UNTIL
        (trError_gg00 <> e_ok) OR (partition = b75region_cnt)
    (*ENDREPEAT*) 
    END
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      b75tldelete_lock_tree (VAR current : tbd_current_tree;
            ignore_svp     : boolean;
            suspend_reason : tsp00_Int2);
 
VAR
      do_suspend      : boolean;
      tree_partition  : integer;
      split_partition : integer;
      root_desc       : tbd7_root_desc;
 
BEGIN
tree_partition  := current.curr_tree_id.fileRoot_gg00 MOD b75region_cnt;
split_partition := tree_partition;
do_suspend      := false;
WITH b77locklist [tree_partition], current, curr_tree_id, curr_trans^ DO
    BEGIN
    b06check_vresume_cnt (curr_trans^.trTaskId_gg00);
    IF  trBdExclFileLocks_gg00 = 0
    THEN
        BEGIN
        vbegexcl (trTaskId_gg00, g08split1 + split_partition);
        vbegexcl (trTaskId_gg00, g08tree1 + tree_partition);
        IF  tll_prevent_split
        THEN
            BEGIN
            tll_pid_request := trTaskId_gg00;
            vendexcl (trTaskId_gg00, g08tree1 + tree_partition);
            vsuspend (trTaskId_gg00, cgg_suspend_lvl_0, 180);
            vbegexcl (trTaskId_gg00, g08tree1 + tree_partition);
&           ifdef TRACE
            g08excl_check (trTaskId_gg00, g08split1 + split_partition);
&           endif
            END
        (*ENDIF*) 
        END
    ELSE
        vbegexcl (trTaskId_gg00, g08tree1 + tree_partition);
    (*ENDIF*) 
&   ifdef TRACE
    g08excl_check (trTaskId_gg00, g08tree1 + tree_partition);
&   endif
    (* *)
    b77root_description (fileRoot_gg00, root_desc);
    IF  b77excl_using_root (root_desc, trTaskId_gg00)
    THEN
        BEGIN
        b77insert_lockentry (trTaskId_gg00, root_desc, NIL_PAGE_NO_GG00,
              d_lock_tree, ignore_svp);
        IF  ignore_svp
        THEN
            tll_svp_ignore_cnt := succ (tll_svp_ignore_cnt);
        (*ENDIF*) 
        tll_split_counter := succ (tll_split_counter)
        END
    ELSE
        BEGIN
        do_suspend := true;
        b76insert_requestentry (trTaskId_gg00, root_desc, NIL_PAGE_NO_GG00,
              cbd7_dummy_index, d_lock_tree, ignore_svp,
              (0 < trBdExclFileLocks_gg00)); (* PTS 1106058 TS 2000-03-28 *)
        bd75set_vprio (root_desc)
        END;
    (*ENDIF*) 
&   ifdef TRACE
    b77check_locklist (root_desc);
&   else
    IF  g01glob.bd_lock_check
    THEN
        b77check_locklist (root_desc);
&   endif
    (*ENDIF*) 
    vendexcl (trTaskId_gg00, g08tree1 + tree_partition);
    IF  trBdExclFileLocks_gg00 = 0
    THEN
        vendexcl (trTaskId_gg00, g08split1 + split_partition);
    (*ENDIF*) 
    trBdExclFileLocks_gg00    := trBdExclFileLocks_gg00 + 1;
    current.curr_node_locked := NIL_PAGE_NO_GG00;
    current.curr_lockstate   := d_lock_tree;
    IF  do_suspend
    THEN
        vsuspend (trTaskId_gg00, cgg_suspend_lvl_0, suspend_reason);
    (*ENDIF*) 
    b06check_vresume_cnt (curr_trans^.trTaskId_gg00);
    END
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      b75tlread_lock_tree (VAR current : tbd_current_tree;
            suspend_reason : tsp00_Int2);
 
VAR
      do_suspend : boolean;
      partition  : integer;
      root_desc  : tbd7_root_desc;
 
BEGIN
WITH current, curr_trans^ DO
    BEGIN
    b06check_vresume_cnt (curr_trans^.trTaskId_gg00);
    partition  := curr_tree_id.fileRoot_gg00 MOD b75region_cnt;
    do_suspend := false;
    (* *)
    vbegexcl (trTaskId_gg00, g08tree1 + partition);
    (* *)
&   ifdef TRACE
    g08excl_check (trTaskId_gg00, g08tree1 + partition);
&   endif
    (* *)
    b77root_description (curr_tree_id.fileRoot_gg00, root_desc);
    IF  bd75whole_tree_locked (root_desc)
    THEN
        BEGIN
        do_suspend := true;
        b76insert_requestentry (trTaskId_gg00, root_desc, NIL_PAGE_NO_GG00,
              cbd7_dummy_index, r_lock_tree, NOT c_ignore_svp,
              NOT c_excl_lock_exist);  (* PTS 1106058 TS 2000-03-28 *)
        bd75set_vprio (root_desc)
        END
    ELSE
        b77insert_lockentry (trTaskId_gg00, root_desc, NIL_PAGE_NO_GG00, r_lock_tree,
              NOT c_ignore_svp);
    (*ENDIF*) 
&   ifdef TRACE
    b77check_locklist (root_desc);
&   else
    IF  g01glob.bd_lock_check
    THEN
        b77check_locklist (root_desc);
&   endif
    (* *)
    (*ENDIF*) 
    vendexcl (trTaskId_gg00, g08tree1 + partition);
    (* *)
    curr_node_locked := NIL_PAGE_NO_GG00;
    curr_lockstate   := r_lock_tree;
    IF  do_suspend
    THEN
        vsuspend (trTaskId_gg00, cgg_suspend_lvl_0, suspend_reason);
    (*ENDIF*) 
    b06check_vresume_cnt (curr_trans^.trTaskId_gg00);
    END
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      b75tlselect_lock_tree (VAR current : tbd_current_tree;
            suspend_reason : tsp00_Int2);
 
VAR
      do_suspend    : boolean;
      partition     : integer;
      windex_locked : boolean;
      wleaf_locked  : boolean;
      dummy_leaf    : tsp00_PageNo;
      root_desc     : tbd7_root_desc;
 
BEGIN
do_suspend    := false;
windex_locked := false;
wleaf_locked  := false;
WITH current DO
    BEGIN
    b06check_vresume_cnt (curr_trans^.trTaskId_gg00);
    partition := curr_tree_id.fileRoot_gg00 MOD b75region_cnt;
    vbegexcl (curr_trans^.trTaskId_gg00, g08tree1 + partition);
&   ifdef TRACE
    g08excl_check (curr_trans^.trTaskId_gg00, g08tree1 + partition);
&   endif
    (* *)
    b77root_description (curr_tree_id.fileRoot_gg00, root_desc);
    IF  (ftsDynamic_egg00 IN curr_tree_id.fileType_gg00)
        AND
        g01glob.bd_subtree
    THEN
        b77index_or_leaf_writers (root_desc, curr_trans^.trTaskId_gg00,
              windex_locked, wleaf_locked)
    ELSE
        wleaf_locked := b77anyleaf_write_locks (root_desc);
    (*ENDIF*) 
    IF  windex_locked OR wleaf_locked
    THEN
        BEGIN
        do_suspend := true;
        dummy_leaf := NIL_PAGE_NO_GG00;
        (* PTS 1106058 TS 2000-03-28 *)
        b77conv_lock_to_req (curr_trans^.trTaskId_gg00, root_desc,
              s_lock_tree, NOT c_excl_lock_exist);
        (* PTS 1106058 TS 2000-03-28 *)
        bd75set_vprio (root_desc);
        END
    ELSE
        b77tconv_to_tree (curr_trans^.trTaskId_gg00, root_desc,
              NIL_PAGE_NO_GG00, s_lock_tree);
    (*ENDIF*) 
&   ifdef TRACE
    b77check_locklist (root_desc);
&   else
    IF  g01glob.bd_lock_check
    THEN
        b77check_locklist (root_desc);
&   endif
    (*ENDIF*) 
    vendexcl (curr_trans^.trTaskId_gg00, g08tree1 + partition);
    curr_node_locked := NIL_PAGE_NO_GG00;
    curr_lockstate   := s_lock_tree;
    IF  do_suspend
    THEN
        vsuspend (curr_trans^.trTaskId_gg00, cgg_suspend_lvl_0, suspend_reason);
    (*ENDIF*) 
    b06check_vresume_cnt (curr_trans^.trTaskId_gg00);
    END
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      b75tlwrite_lock_tree (VAR current : tbd_current_tree;
            leaf            : tsp00_PageNo;
            VAR lock_return : tbd_lock_returncode;
            suspend_reason  : tsp00_Int2);
 
VAR
      dtree_requested          : boolean; (* PTS 1105578 TS 2000-02-10 *)
      structure_lock_requested : boolean; (* PTS 1105578 TS 2000-02-10 *)
      rleaf_requested          : boolean; (* PTS 1107109 TS 2000-07-07 *)
      wleaf_requested          : boolean; (* PTS 1107109 TS 2000-07-07 *)
      rindex_requested         : boolean; (* PTS 1107109 TS 2000-07-07 *)
      windex_requested         : boolean;
      wtree_requested          : boolean;
      wleaf_locked             : boolean;
      windex_locked            : boolean;
      split_found              : boolean;
      resume                   : boolean;
      tree_partition           : integer;
      split_partition          : integer;
      root_desc                : tbd7_root_desc;
 
BEGIN
resume          := false;
split_found     := false;
windex_locked   := false;
wleaf_locked    := false;
tree_partition  := current.curr_tree_id.fileRoot_gg00 MOD b75region_cnt;
split_partition := tree_partition;
WITH current, curr_trans^, curr_tree_id, b77locklist [tree_partition] DO
    BEGIN
    b06check_vresume_cnt (curr_trans^.trTaskId_gg00);
    IF  trBdExclFileLocks_gg00 = 0
    THEN
        BEGIN
        vbegexcl (trTaskId_gg00, g08split1 + split_partition);
        vbegexcl (trTaskId_gg00, g08tree1 + tree_partition);
        IF  tll_prevent_split
        THEN
            BEGIN
            tll_pid_request := curr_trans^.trTaskId_gg00;
            vendexcl (trTaskId_gg00, g08tree1 + tree_partition);
            vsuspend (trTaskId_gg00, cgg_suspend_lvl_0, 181);
            vbegexcl (trTaskId_gg00, g08tree1 + tree_partition)
            END
        (*ENDIF*) 
        END
    ELSE
        vbegexcl (trTaskId_gg00, g08tree1 + tree_partition);
    (*ENDIF*) 
&   ifdef TRACE
    g08excl_check (trTaskId_gg00, g08tree1 + tree_partition);
&   endif
    (* *)
    b77root_description (fileRoot_gg00, root_desc);
    wtree_requested := b76is_tree_requested (root_desc, w_lock_tree);
    (* PTS 1105578 TS 2000-02-10 *)
    dtree_requested := b76is_tree_requested (root_desc, d_lock_tree);
    (* PTS 1105578 *)
    b77index_or_leaf_writers (root_desc, curr_trans^.trTaskId_gg00,
          windex_locked, wleaf_locked);
    (* *)
    IF  (ftsDynamic_egg00 IN curr_tree_id.fileType_gg00) AND g01glob.bd_subtree
    THEN
        BEGIN
        (* PTS 1107109 TS 2000-07-07 *)
        rindex_requested := b76is_index_requested (root_desc, curr_lvl_1_locked, r_lock_index);
        (* PTS 1107109 *)
        windex_requested := b76is_index_requested (root_desc, curr_lvl_1_locked, w_lock_index);
        END
    ELSE
        BEGIN
        rindex_requested := false; (* PTS 1107109 TS 2000-07-07 *)
        windex_requested := false;
        END;
    (*ENDIF*) 
    (* PTS 1105578 TS 2000-02-10 *)
    structure_lock_requested := wtree_requested OR windex_requested OR dtree_requested;
    (* PTS 1105578 *)
    (* PTS 1107109 TS 2000-07-07 *)
    wleaf_requested := b76is_leaf_requested (root_desc, leaf, w_lock_leaf);
    rleaf_requested := b76is_leaf_requested (root_desc, leaf, r_lock_leaf);
    (* PTS 1107109 *)
    IF  structure_lock_requested OR wleaf_requested OR rleaf_requested
        OR
        rindex_requested (* PTS 1107109 TS 2000-07-07 *)
        OR
        (
        NOT windex_locked AND NOT wleaf_locked AND
        b76is_tree_requested (root_desc, s_lock_tree)
        )
    THEN
        BEGIN
        (* PTS 1106058 TS 2000-03-28 *)
        b77conv_lock_to_req (trTaskId_gg00, root_desc, w_lock_tree,
              (0 < trBdExclFileLocks_gg00));
        (* PTS 1106058  *)
        bd75set_vprio (root_desc);
        IF  rleaf_requested
        THEN
            BEGIN
            IF  structure_lock_requested (* PTS 1105578 TS 2000-02-10 *)
            THEN
                lock_return := lock_failed
            ELSE
                lock_return := lock_dirty;
            (*ENDIF*) 
            b76lrstart_read_leaf (root_desc, leaf, resume);
            IF  (NOT wleaf_locked) AND (NOT windex_locked)
            THEN
                b76start_tree (root_desc, s_lock_tree, split_found, resume);
            (*ENDIF*) 
            END
        ELSE
            BEGIN
            IF  b76is_tree_requested (root_desc, s_lock_tree) AND
                NOT wleaf_locked                              AND
                NOT windex_locked
            THEN
                BEGIN
                IF  structure_lock_requested (* PTS 1105578 TS 2000-02-10 *)
                THEN
                    lock_return := lock_failed
                ELSE
                    lock_return := lock_dirty;
                (*ENDIF*) 
                b76start_tree (root_desc, s_lock_tree, split_found, resume);
                (* PTS 1107109 TS 2000-07-07 *)
                IF  rindex_requested
                THEN
                    b76istart_index (root_desc, curr_lvl_1_locked, r_lock_index,
                          split_found, resume);
                (* PTS 1107109 *)
                (*ENDIF*) 
                END
            ELSE
                IF  wleaf_requested
                THEN
                    BEGIN
                    IF  structure_lock_requested (* PTS 1105578 TS 2000-02-10 *)
                    THEN
                        lock_return := lock_failed
                    ELSE
                        lock_return := lock_dirty;
                    (*ENDIF*) 
                    IF  NOT b77stree_in_locklist (root_desc)
                    THEN
                        b76lwstart_write_leaf (root_desc, leaf, resume);
                    (*ENDIF*) 
                    END
                ELSE
                    IF  rindex_requested (* PTS 1107109 TS 2000-07-07 *)
                    THEN
                        BEGIN
                        IF  structure_lock_requested (* PTS 1105578 TS 2000-02-10 *)
                        THEN
                            lock_return := lock_failed
                        ELSE
                            lock_return := lock_dirty;
                        (*ENDIF*) 
                        b76istart_index (root_desc, curr_lvl_1_locked, r_lock_index,
                              split_found, resume);
                        END
                    ELSE
                        BEGIN
                        (* PTS 1105578 TS 2000-02-10 *)
                        lock_return := lock_failed;
                        IF  windex_requested
                        THEN
                            BEGIN
                            IF  NOT b77exist_lock_within_subtree (
                                trTaskId_gg00, root_desc, curr_lvl_1_locked)
                            THEN
                                b76istart_index (root_desc, curr_lvl_1_locked,
                                      w_lock_index, split_found, resume)
                            (*ENDIF*) 
                            END
                        ELSE
                            IF  wtree_requested
                            THEN
                                BEGIN
                                IF  b77is_empty_locklist (root_desc)
                                THEN
                                    b76start_tree (root_desc, w_lock_tree,
                                          split_found, resume)
                                (*ENDIF*) 
                                END
                            ELSE (* dtree_requested *)
                                BEGIN
                                IF  b77is_empty_locklist (root_desc)
                                THEN
                                    b76start_tree (root_desc, d_lock_tree,
                                          split_found, resume)
                                (*ENDIF*) 
                                END;
                            (*ENDIF*) 
                        (*ENDIF*) 
                        (* PTS 1105578 *)
                        END
                    (*ENDIF*) 
                (*ENDIF*) 
            (*ENDIF*) 
            END
        (*ENDIF*) 
        END
    ELSE
        IF  b77excl_using_root (root_desc, curr_trans^.trTaskId_gg00)
        THEN
            BEGIN
            lock_return := lock_okay;
            b77tconv_to_tree (trTaskId_gg00, root_desc, leaf, w_lock_tree);
            END
        ELSE
            BEGIN
            lock_return := lock_dirty;
            (* PTS 1106058 TS 2000-03-28 *)
            b77conv_lock_to_req (trTaskId_gg00, root_desc, w_lock_tree,
                  (0 < trBdExclFileLocks_gg00));
            (* PTS 1106058  *)
            bd75set_vprio (root_desc)
            END;
        (*ENDIF*) 
    (*ENDIF*) 
&   ifdef TRACE
    b77check_locklist (root_desc);
&   else
    IF  g01glob.bd_lock_check
    THEN
        b77check_locklist (root_desc);
&   endif
    (*ENDIF*) 
    vendexcl (trTaskId_gg00, g08tree1 + tree_partition);
    IF  trBdExclFileLocks_gg00 = 0
    THEN
        vendexcl (trTaskId_gg00, g08split1 + split_partition);
    (*ENDIF*) 
    IF  (curr_lockstate = w_lock_leaf) OR
        (curr_lockstate = r_lock_tree)
    THEN
        trBdExclFileLocks_gg00 := trBdExclFileLocks_gg00 + 1;
    (*ENDIF*) 
    curr_lockstate := w_lock_tree;
    IF  lock_return <> lock_okay
    THEN
        vsuspend (curr_trans^.trTaskId_gg00, cgg_suspend_lvl_0, suspend_reason);
    (*ENDIF*) 
    b06check_vresume_cnt (curr_trans^.trTaskId_gg00);
    END
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
FUNCTION
      b75tree_request (pid : tsp00_TaskId;
            root : tsp00_PageNo) : boolean;
 
VAR
      partition : integer;
      root_desc : tbd7_root_desc;
 
BEGIN
partition := root MOD b75region_cnt;
vbegexcl (pid, g08tree1 + partition);
&ifdef TRACE
g08excl_check (pid, g08tree1 + partition);
&endif
(* *)
b77root_description (root, root_desc);
b75tree_request := b76is_tree_requested (root_desc, w_lock_tree);
vendexcl (pid, g08tree1 + partition)
END;
 
(*------------------------------*) 
 
PROCEDURE
      b75tudelete_unlock_tree (VAR current : tbd_current_tree);
 
VAR
      partition   : integer;
      resume      : boolean;
      split_found : boolean;
      dummy_pno   : tsp00_PageNo;
      root_desc   : tbd7_root_desc;
 
BEGIN
WITH current, curr_trans^ DO
    BEGIN
    b06check_vresume_cnt (curr_trans^.trTaskId_gg00);
    resume      := false;
    split_found := false;
    dummy_pno   := NIL_PAGE_NO_GG00;
    partition   := curr_tree_id.fileRoot_gg00 MOD b75region_cnt;
    vbegexcl (trTaskId_gg00, g08tree1 + partition);
&   ifdef TRACE
    g08excl_check (trTaskId_gg00, g08tree1 + partition);
&   endif
    (* *)
    b77root_description (curr_tree_id.fileRoot_gg00, root_desc);
    b77delete_lockentry (trTaskId_gg00, root_desc,
          dummy_pno, curr_lvl_1_locked, d_lock_tree);
    b76start_tree (root_desc, w_lock_tree, split_found, resume);
    IF  NOT resume
    THEN
        BEGIN
        b76readers_start (root_desc, resume);
        IF  (NOT split_found) AND (NOT resume)
        THEN
            b76start_tree (root_desc, d_lock_tree, split_found, resume)
        (*ENDIF*) 
        END;
&   ifdef TRACE
    (*ENDIF*) 
    b77check_locklist (root_desc);
&   else
    IF  g01glob.bd_lock_check
    THEN
        b77check_locklist (root_desc);
&   endif
    (*ENDIF*) 
    vendexcl (trTaskId_gg00, g08tree1 + partition);
    trBdExclFileLocks_gg00 := trBdExclFileLocks_gg00 - 1;
    curr_node_locked      := NIL_PAGE_NO_GG00;
    curr_lockstate        := no_bd_lock;
    b06check_vresume_cnt (curr_trans^.trTaskId_gg00);
    END
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      b75turead_unlock_tree (VAR current : tbd_current_tree);
 
VAR
      partition   : integer;
      split_found : boolean;
      resume      : boolean;
      leaf        : tsp00_PageNo;
      root_desc   : tbd7_root_desc;
 
BEGIN
WITH current DO
    BEGIN
    b06check_vresume_cnt (curr_trans^.trTaskId_gg00);
    leaf        := NIL_PAGE_NO_GG00;
    resume      := false;
    split_found := false;
    partition   := curr_tree_id.fileRoot_gg00 MOD b75region_cnt;
    vbegexcl (curr_trans^.trTaskId_gg00, g08tree1 + partition);
&   ifdef TRACE
    g08excl_check (curr_trans^.trTaskId_gg00, g08tree1 + partition);
&   endif
    (* *)
    b77root_description (curr_tree_id.fileRoot_gg00, root_desc);
    b77delete_lockentry (curr_trans^.trTaskId_gg00, root_desc, leaf,
          curr_lvl_1_locked, r_lock_tree);
    IF  NOT resume
    THEN
        IF  b77is_empty_locklist (root_desc)
        THEN
            BEGIN
            b76start_tree (root_desc, w_lock_tree, split_found, resume);
            IF  (NOT split_found) AND (NOT resume)
            THEN
                b76start_tree (root_desc, d_lock_tree, split_found, resume)
            (*ENDIF*) 
            END;
&       ifdef TRACE
        (*ENDIF*) 
    (*ENDIF*) 
    b77check_locklist (root_desc);
&   else
    IF  g01glob.bd_lock_check
    THEN
        b77check_locklist (root_desc);
&   endif
    (*ENDIF*) 
    vendexcl (curr_trans^.trTaskId_gg00, g08tree1 + partition);
    curr_node_locked  := NIL_PAGE_NO_GG00;
    curr_lvl_1_locked := NIL_PAGE_NO_GG00;
    curr_lockstate    := no_bd_lock;
    b06check_vresume_cnt (curr_trans^.trTaskId_gg00);
    END
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      b75tuselect_unlock_tree (VAR current : tbd_current_tree);
 
VAR
      partition   : integer;
      split_found : boolean;
      resume      : boolean;
      dummy_pno   : tsp00_PageNo;
      root_desc   : tbd7_root_desc;
 
BEGIN
WITH current, curr_tree_id DO
    BEGIN
    b06check_vresume_cnt (curr_trans^.trTaskId_gg00);
    dummy_pno   := NIL_PAGE_NO_GG00;
    resume      := false;
    split_found := false;
    partition   := fileRoot_gg00 MOD b75region_cnt;
    vbegexcl (curr_trans^.trTaskId_gg00, g08tree1 + partition);
&   ifdef TRACE
    g08excl_check (curr_trans^.trTaskId_gg00, g08tree1 + partition);
&   endif
    (* *)
    b77root_description (fileRoot_gg00, root_desc);
    b77delete_lockentry (curr_trans^.trTaskId_gg00, root_desc, dummy_pno,
          curr_lvl_1_locked, s_lock_tree);
    IF  NOT b77stree_in_locklist (root_desc)
    THEN
        BEGIN
        b76leaf_writers_start (root_desc, resume);
        IF  (ftsDynamic_egg00 IN fileType_gg00)
            AND
            g01glob.bd_subtree
        THEN
            b76index_writers_start (root_desc, resume, curr_trans^.trTaskId_gg00);
        (*ENDIF*) 
        IF  NOT resume
        THEN
            IF  b77is_empty_locklist (root_desc)
            THEN
                BEGIN
                b76start_tree (root_desc, w_lock_tree, split_found, resume);
                IF  (NOT split_found) AND (NOT resume)
                THEN
                    b76start_tree (root_desc, d_lock_tree, split_found, resume)
                (*ENDIF*) 
                END
            (*ENDIF*) 
        (*ENDIF*) 
        END;
&   ifdef TRACE
    (*ENDIF*) 
    b77check_locklist (root_desc);
&   else
    IF  g01glob.bd_lock_check
    THEN
        b77check_locklist (root_desc);
&   endif
    (*ENDIF*) 
    vendexcl (curr_trans^.trTaskId_gg00, g08tree1 + partition);
    curr_node_locked := NIL_PAGE_NO_GG00;
    curr_lockstate   := no_bd_lock;
    b06check_vresume_cnt (curr_trans^.trTaskId_gg00);
    END
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
PROCEDURE
      b75tuwrite_unlock_tree (VAR current : tbd_current_tree);
 
VAR
      partition   : integer;
      split_found : boolean;
      resume      : boolean;
      dummy_pno   : tsp00_PageNo;
      root_desc   : tbd7_root_desc;
 
BEGIN
WITH current, curr_trans^ DO
    BEGIN
    b06check_vresume_cnt (curr_trans^.trTaskId_gg00);
    resume      := false;
    split_found := false;
    dummy_pno   := NIL_PAGE_NO_GG00;
    partition   := curr_tree_id.fileRoot_gg00 MOD b75region_cnt;
    vbegexcl (trTaskId_gg00, g08tree1 + partition);
&   ifdef TRACE
    g08excl_check (trTaskId_gg00, g08tree1 + partition);
&   endif
    (* *)
    b77root_description (curr_tree_id.fileRoot_gg00, root_desc);
    b77delete_lockentry (trTaskId_gg00, root_desc, dummy_pno,
          curr_lvl_1_locked, w_lock_tree);
    IF  NOT  b76is_empty_requestlist (root_desc)
    THEN
        BEGIN
        b76start_tree (root_desc, w_lock_tree, split_found, resume);
        IF  NOT resume
        THEN
            BEGIN
            b76readers_start (root_desc, resume);
            IF  (NOT split_found) AND (NOT resume)
            THEN
                b76start_tree (root_desc, d_lock_tree,
                      split_found, resume)
            (*ENDIF*) 
            END
        (*ENDIF*) 
        END;
&   ifdef TRACE
    (*ENDIF*) 
    b77check_locklist (root_desc);
&   else
    IF  g01glob.bd_lock_check
    THEN
        b77check_locklist (root_desc);
&   endif
    (*ENDIF*) 
    vendexcl (trTaskId_gg00, g08tree1 + partition);
    trBdExclFileLocks_gg00 := trBdExclFileLocks_gg00 - 1;
    curr_node_locked       := NIL_PAGE_NO_GG00;
    curr_lvl_1_locked      := NIL_PAGE_NO_GG00;
    curr_lockstate         := no_bd_lock;
    b06check_vresume_cnt (curr_trans^.trTaskId_gg00);
    IF  (current.currFreeQueue_bd00.fqTop_bd00 > 1)
    THEN
        b13free_pnos_after_unlock (current);
    (*ENDIF*) 
    WITH curr_tree_id DO
        IF  (trError_gg00 = e_ok                     ) AND
            (tsSaveptWanted_egg00 IN trState_gg00    ) AND
            NOT (hsNoLog_egg00 IN fileHandling_gg00) (* PTS 1001949 UH 18-01-1999 *)
        THEN
            BEGIN
            trState_gg00 := trState_gg00 - [tsSaveptWanted_egg00];
            kb560StartSavepoint (curr_trans^, mm_lock);
            END
        (*ENDIF*) 
    (*ENDWITH*) 
    END
(*ENDWITH*) 
END;
 
(*------------------------------*) 
 
FUNCTION
      bd75is_whole_subtree_locked (VAR root_desc : tbd7_root_desc;
            indexnode : tsp00_PageNo) : boolean;
 
VAR
      partition : integer;
      locked    : boolean;
 
BEGIN
locked := false;
IF  b77write_index_locked (root_desc, indexnode)
THEN
    locked := true
ELSE
    IF  b76is_index_requested (root_desc, indexnode, w_lock_index)
    THEN
        BEGIN
        partition := root_desc.rd_root MOD b75region_cnt;
        IF  NOT b77locklist [partition].tll_prevent_split
        THEN
            locked := true
        (*ENDIF*) 
        END;
    (*ENDIF*) 
(*ENDIF*) 
bd75is_whole_subtree_locked := locked
END;
 
(*------------------------------*) 
 
PROCEDURE
      bd75set_vprio (root_desc : tbd7_root_desc);
 
CONST
      c_set_prio = true;
 
BEGIN
IF  root_desc.rd_collision_ptr <> NIL
THEN
    WITH root_desc.rd_collision_ptr^ DO
        BEGIN
        lle_prio_on := true;
        v2prio (lle_pid, cbd7_prio_high, c_set_prio, root_desc.rd_root,
              lle_leaf, lle_state);
        root_desc.rd_collision_ptr := NIL
        END
    (*ENDWITH*) 
(*ENDIF*) 
END;
 
(*------------------------------*) 
 
FUNCTION
      bd75whole_tree_locked
            (VAR root_desc : tbd7_root_desc) : boolean;
 
VAR
      partition           : integer;
      excl_lock_requested : boolean; (* PTS 1105578 TS 2000-02-10 *)
      locked              : boolean;
 
BEGIN
locked              := false;
excl_lock_requested := false;
IF  b77tree_in_locklist (root_desc)
THEN
    locked := true
ELSE
    BEGIN
    excl_lock_requested := b76is_tree_requested (root_desc, w_lock_tree);
    IF  NOT excl_lock_requested (* PTS 1105578 TS 2000-02-10 *)
    THEN
        excl_lock_requested := b76is_tree_requested (root_desc, d_lock_tree);
    (*ENDIF*) 
    IF  excl_lock_requested
    THEN
        BEGIN
        partition := root_desc.rd_root MOD b75region_cnt;
        IF  NOT b77locklist [partition].tll_prevent_split
        THEN
            locked := true
        (*ENDIF*) 
        END
    (*ENDIF*) 
    END;
(*ENDIF*) 
bd75whole_tree_locked := locked
END;
 
.CM *-END-* code ----------------------------------------
.SP 2 
***********************************************************
*-PRETTY-*  statements    :        741
*-PRETTY-*  lines of code :       2115        PRETTYX 3.10 
*-PRETTY-*  lines in file :       2994         1997-12-10 
.PA 
