1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187
|
/****************************************************************
* *
* Copyright 2001, 2012 Fidelity Information Services, Inc *
* *
* This source code contains the intellectual property *
* of its copyright holder(s), and is made available *
* under a license. If you do not know the terms of *
* the license, please stop and do not read further. *
* *
****************************************************************/
#ifndef __MLKDEF_H__
#define __MLKDEF_H__
/* mlkdef.h */
#include <sys/types.h>
typedef struct mlk_tp_struct
{
struct mlk_tp_struct *next; /* next stacking struct */
unsigned int level : 9; /* incremental lock level */
unsigned int zalloc : 1; /* if true, there is a ZALLOC posted for this lock */
unsigned int tplevel : 8; /* $TLEVEL when this was stacked */
unsigned int unused : 14; /* ** Reserved ** */
} mlk_tp;
typedef struct /* One of these nodes is required for each process which is blocked on a lock */
{
ptroff_t next; /* relative pointer to the next mlk_prcblk. If the entry is in the free
* list, then this is a relative pointer to the next free entry. */
uint4 process_id; /* the pid of the blocked process */
short ref_cnt; /* number of times process references prcblk */
unsigned short unlock; /* boolean to indicate activity on lock */
} mlk_prcblk;
typedef struct /* lock node. The member descriptions below are correct if the entry
* is in the tree. If the entry is in the free list, then all
* of the members are meaningless, except for rsib, which is a
* relative pointer to the next item in the free list */
{
ptroff_t value; /* relative pointer to the shrsub for this node (always present) */
ptroff_t parent; /* relative pointer to the parent node (zero if name level) */
ptroff_t children; /* relative pointer to the eldest child of this node (zero if none) */
ptroff_t lsib; /* relative pointers to the "left sibling" and "right sibling" */
ptroff_t rsib; /* note that each level of the tree is sorted, for faster lookup */
ptroff_t pending; /* relative pointer to a mlk_prcblk, or zero if no entries are are blocked on this node */
int4 owner; /* process id of the owner, if zero, this node is un-owned, and there
* must, by defintion, be either a non-zero 'pending' entry, or a
* non-zero 'children' entry and in the latter case, at least one
* child must have a 'pending' entry */
uint4 sequence; /* The sequence number at the time that this node was created. If
* during a direct re-access via pointer from a mlk_pvtblk, the
* sequence numbers do not match, then we must assume that the
* lock was stolen from us by LKE or some other abnormal event. */
UINTPTR_T auxowner; /* For gt.cm, this contains information on the remote owner of the lock.*/
int4 image_count; /* the number of image activiations since login */
int4 login_time; /* the low-order 32 bits of the time that the process logged in. login_time
* and image_count can be used together to determine whether the process has
* abnormally terminated. */
int4 auxpid; /* If non-zero auxowner, this is the pid of the client that is holding the lock */
unsigned char auxnode[16]; /* If non-zero auxowner, this is the nodename of the client that is holding the lock */
} mlk_shrblk;
typedef struct /* the subscript value of a single node in a tree. Stored separately so that
* the mlk_shrblk's can all have fixed positions, and yet we can
* efficiently store variable length subscripts. Each entry is rounded to
* a length of 4 bytes to eliminiate unaligned references. */
{
ptroff_t backpointer; /* relative pointer to mlk_shrblk which owns this entry, so that we can
* efficiently compress the space. If this is zero, then the item is
* an abandon entry. */
unsigned char length; /* length of the data */
unsigned char data[1]; /* the data itself, actually data[length] */
} mlk_shrsub;
/* WARNING: GT.CM and GT.CX rely on the fact that this structure is at the start of the lock space
* and that the array of pids is at the top of this structure */
#define NUM_CLST_LCKS 64
typedef struct mlk_ctldata_struct /* this describes the entire shared lock section */
{
ptroff_t prcfree; /* relative pointer to the first empty mlk_prcblk */
ptroff_t blkfree; /* relative pointer to the first free mlk_shrblk.
* if zero, the blkcnt must also equal zero */
ptroff_t blkroot; /* relative pointer to the first name level mlk_shrblk.
* if zero, then there are no locks in this section */
ptroff_t subbase; /* relative pointer to the base of the mlk_shrsub area */
ptroff_t subfree; /* relative pointer to the first free cell in the shrsub area */
ptroff_t subtop; /* relative pointer to the top of the shrsub area */
uint4 max_prccnt; /* maximum number of entries in the prcfree chain */
uint4 max_blkcnt; /* maximum number of entires in the blkfree chain */
int4 prccnt; /* number of entries in the prcfree chain */
int4 blkcnt; /* number of entires in the blkfree chain */
uint4 clus_pids[NUM_CLST_LCKS]; /* Pids of processes on other machines in the cluster to be woken up */
unsigned int wakeups; /* lock wakeup counter */
} mlk_ctldata;
/* Define types for shared memory resident structures */
#ifdef DB64
# ifdef __osf__
# pragma pointer_size(save)
# pragma pointer_size(long)
# else
# error UNSUPPORTED PLATFORM
# endif
#endif
typedef mlk_prcblk *mlk_prcblk_ptr_t;
typedef mlk_shrblk *mlk_shrblk_ptr_t;
typedef mlk_shrsub *mlk_shrsub_ptr_t;
typedef mlk_ctldata *mlk_ctldata_ptr_t;
#ifdef DB64
# ifdef __osf__
# pragma pointer_size(restore)
# endif
#endif
/* Now define main private lock structure */
typedef struct mlk_pvtblk_struct /* one of these entries exists for each nref which is locked or being processed */
{
mlk_ctldata_ptr_t ctlptr; /* pointer to the mlk_ctldata for the data base region, duplicated to save
* recalculating it each time. */
mlk_shrblk_ptr_t nodptr; /* pointer to the node in the shared data structure which corresponds to
* this nref */
mlk_shrblk_ptr_t blocked; /* pointer to the node in the shared data structure which blocked this
* operation */
struct mlk_pvtblk_struct
*next; /* pointer to the next mlk_pvtblk in this chain. The chain may be temporary
* if lock processing is underway, or permanent, in which case the chain
* represents owned locks. */
struct gd_region_struct *region; /* pointer to the database region in which the lock belongs */
uint4 sequence; /* shrblk sequence for nodptr node (node we want) */
uint4 blk_sequence; /* shrblk sequence for blocked node (node preventing our lock) */
mlk_tp *tp; /* pointer to saved tp information */
uint4 total_length; /* the total length of the 'value' string. */
uint4 total_len_padded; /* Length with padding to 4 bytes for each substring */
unsigned short subscript_cnt; /* the number of subscripts (plus one for the name) in this nref */
unsigned level : 9; /* incremental lock level */
unsigned zalloc : 1; /* if true, there is a ZALLOC posted for this lock */
unsigned granted : 1; /* if true, the lock has been granted in the database */
unsigned unused : 5; /* ** Unused ** the number of bits in the bit-fields add up to
only 16, therefore although they have type unsigned,
they are accommodated within 2 bytes. Since there is
no type for bit-fields, unsigned should be the only
type specified and alignment works according to the
total number of bits */
unsigned char trans; /* boolean indicating whether already in list */
unsigned char translev; /* level for transaction (accounting for redundancy) */
unsigned char old; /* oldness boolean used for backing out zallocates */
unsigned char filler[1]; /* Fill out to align data on word boundary */
unsigned char value[1]; /* actually, an array unsigned char value[total_length]. This string
* consists of the nref's subscripts each preceeded by the length of
* the subscript, held as a single byte. For example, ^A(45), would be
* represented as 02 5E 41 02 34 35, and total length would be 5. */
} mlk_pvtblk;
/* convert relative pointer to absolute pointer */
#define R2A(X) (((sm_uc_ptr_t) &(X)) + (X))
/* store absolute pointer Y in X as a relative pointer */
#define A2R(X, Y) ((X) = (ptroff_t)(((sm_uc_ptr_t)(Y)) - ((sm_uc_ptr_t) &(X))))
/* compute the true size of a mlk_pvtblk */
#define MLK_PVTBLK_SIZE(DLEN, SCNT) (SIZEOF(mlk_pvtblk) - 1 + (DLEN) + (SCNT))
/* compute the true size of a mlk_shrsub include stddef.h*/
#define MLK_SHRSUB_SIZE(X) (ROUND_UP(OFFSETOF(mlk_shrsub, data[0]) + (X)->length, SIZEOF(ptroff_t)))
/* SIZEOF(ptroff_t) - 1 is used for padding because mlk_shrblk_create() ROUND_UPs to SIZEOF(ptroff_t) aligned boundary */
#define MLK_PVTBLK_SHRSUB_SIZE(PVTBLK, SHRSUBNEED) \
(SHRSUBNEED * (OFFSETOF(mlk_shrsub, data[0]) + SIZEOF(ptroff_t) - 1) + PVTBLK->total_length)
#define DEF_LOCK_SIZE OS_PAGELET_SIZE * 200
typedef struct mlk_stats_struct
{
gtm_uint64_t n_user_locks_success;
gtm_uint64_t n_user_locks_fail;
} mlk_stats_t;
#define MLK_FAIRNESS_DISABLED ((uint4)-1)
#endif
|