fis-gtm/sr_port/op_gvsavtarg.c

107 lines
3.8 KiB
C

/****************************************************************
* *
* Copyright 2001, 2011 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. *
* *
****************************************************************/
#include "mdef.h"
#include "gtm_string.h"
#include "gdsroot.h"
#include "gtm_facility.h"
#include "fileinfo.h"
#include "gdsbt.h"
#include "gdsfhead.h"
#include "stringpool.h"
#include "op.h"
#include "gdskill.h" /* needed for tp.h */
#include "gdscc.h" /* needed for tp.h */
#include "filestruct.h" /* needed for tp.h */
#include "jnl.h" /* needed for tp.h */
#include "buddy_list.h" /* needed for tp.h */
#include "hashtab_int4.h" /* needed for tp.h */
#include "tp.h"
#include "process_gvt_pending_list.h"
GBLREF gd_binding *gd_map;
GBLREF gd_region *gv_cur_region;
GBLREF gv_key *gv_currkey;
GBLREF gv_namehead *gv_target;
GBLREF spdesc stringpool;
GBLREF uint4 dollar_tlevel;
GBLREF sgm_info *first_sgm_info, *sgm_info_ptr;
void op_gvsavtarg(mval *v)
{
int len, align_len;
unsigned char *c;
DEBUG_ONLY(
unsigned char *tmpc;
)
short end;
gvsavtarg_t *gvsavtarg;
DCL_THREADGBL_ACCESS;
SETUP_THREADGBL_ACCESS;
DBG_CHECK_GVTARGET_GVCURRKEY_IN_SYNC;
DBG_CHECK_GVTARGET_CSADDRS_IN_SYNC;
v->mvtype = 0; /* so stp_gcol (if invoked below) can free up space currently occupied by this to-be-overwritten mval */
if (NULL == gv_currkey)
{ /* Simplest case, finish it off */
v->str.len = 0;
v->mvtype = MV_STR;
return;
}
assert(NULL != TREF(gd_targ_addr));
assert((NULL != gv_target) || (0 == gv_currkey->end));
/* The way savtarg/rectarg works is by saving and restoring a copy of "gv_target". This assumes that once gv_target
* has been allocated and used in a savtarg, the memory is never freed at least until the rectarg is completed.
* gvtargets in the pending list could be freed and reallocated so such gvtargets should never be the current
* "gv_target" global in case we are in savtarg (or else at rectarg time the saved gv_target could have been freed).
* Assert accordingly.
*/
assert((NULL == gv_target) || !is_gvt_in_pending_list(gv_target));
end = gv_currkey->end;
len = (int)(end + GVSAVTARG_FIXED_SIZE);
align_len = len + (GVSAVTARG_ALIGN_BNDRY - 1); /* is for 8-byte alignment of v->str.addr */
ENSURE_STP_FREE_SPACE(align_len);
v->str.len = len;
c = (unsigned char *)(ROUND_UP2((UINTPTR_T)stringpool.free, GVSAVTARG_ALIGN_BNDRY));
assert((c + len) <= (stringpool.free + align_len));
v->str.addr = (char *)c;
v->mvtype = MV_STR; /* initialize mvtype now that mval has been otherwise completely set up */
stringpool.free += align_len;
gvsavtarg = (gvsavtarg_t *)c;
/* Now we are going to fill in the structure fields most of which are pointer fields (size upto 8-byte).
* This is why we ensure 8-byte alignment of c before typecasting it into gvsavtarg.
*/
DEBUG_ONLY(
assert(!dollar_tlevel || (NULL != first_sgm_info) || (NULL == sgm_info_ptr));
if (dollar_tlevel && (NULL != sgm_info_ptr))
DBG_CHECK_IN_FIRST_SGM_INFO_LIST(sgm_info_ptr);
)
gvsavtarg->gd_targ_addr = TREF(gd_targ_addr);
gvsavtarg->gd_map = gd_map;
gvsavtarg->gv_cur_region = gv_cur_region;
gvsavtarg->gv_target = gv_target;
gvsavtarg->gv_last_subsc_null = TREF(gv_last_subsc_null);
gvsavtarg->gv_some_subsc_null = TREF(gv_some_subsc_null);
gvsavtarg->prev = gv_currkey->prev;
gvsavtarg->end = end;
c += GVSAVTARG_FIXED_SIZE;
if (0 < end)
{
assert(KEY_DELIMITER != gv_currkey->base[0]);
assert(KEY_DELIMITER == gv_currkey->base[end - 1]);
assert(KEY_DELIMITER == gv_currkey->base[end]);
memcpy(c, gv_currkey->base, end);
}
return;
}