/**************************************************************** * * * 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. * * * ****************************************************************/ /* General repository for global variable definitions. This keeps us from pulling in modules and all their references when all we wanted was the global data def.. */ #include "mdef.h" #include "gtm_inet.h" #include "gtm_iconv.h" #include "gtm_socket.h" #include "gtm_unistd.h" #include "gtm_limits.h" #include #include #ifdef UNIX # include #endif #ifdef VMS # include /* Required for gtmsource.h */ # include # include # include "desblk.h" #endif #include "cache.h" #include "hashtab_addr.h" #include "hashtab_int4.h" #include "hashtab_int8.h" #include "hashtab_mname.h" #include "hashtab_str.h" #include "hashtab_objcode.h" /* The define of CHEXPAND below causes error.h to create GBLDEFs */ #define CHEXPAND #include "error.h" #include "rtnhdr.h" #include "gdsroot.h" #include "gdskill.h" #include "ccp.h" #include "gtm_facility.h" #include "fileinfo.h" #include "gdsbt.h" #include "gdsfhead.h" #include "filestruct.h" #include "gdscc.h" #include "comline.h" #include "compiler.h" #include "cmd_qlf.h" #include "io.h" #include "iosp.h" #include "jnl.h" #include "lv_val.h" #include "mdq.h" #include "mprof.h" #include "mv_stent.h" #include "stack_frame.h" #include "stp_parms.h" #include "stringpool.h" #include "buddy_list.h" /* needed for tp.h */ #include "tp.h" #include "tp_frame.h" #include "mlkdef.h" #include "zshow.h" #include "zwrite.h" #include "zbreak.h" #include "mmseg.h" #ifndef VMS # include "gtmsiginfo.h" #endif #include "gtmimagename.h" #include "iotcpdef.h" #include "gt_timer.h" #include "iosocketdef.h" /* needed for socket_pool and MAX_N_SOCKETS */ #include "ctrlc_handler_dummy.h" #include "unw_prof_frame_dummy.h" #include "op.h" #include "gtmsecshr.h" #include "error_trap.h" #include "patcode.h" /* for pat_everything and sizeof_pat_everything */ #include "source_file.h" /* for REV_TIME_BUFF_LEN */ #include "mupipbckup.h" #include "dpgbldir.h" #include "mmemory.h" #include "have_crit.h" #include "alias.h" /* FOR REPLICATION RELATED GLOBALS */ #include "repl_msg.h" #include "gtmsource.h" #include "gtmrecv.h" /* FOR MERGE RELATED GLOBALS */ #include "gvname_info.h" #include "op_merge.h" #ifdef UNIX #include "cli.h" #include "invocation_mode.h" #include "fgncal.h" #include "parse_file.h" /* for MAX_FBUFF */ #include "repl_sem.h" #include "gtm_zlib.h" #endif #include "jnl_typedef.h" #ifdef VMS #include "gtm_logicals.h" /* for GTM_MEMORY_NOACCESS_COUNT */ #endif #include "gds_blk_upgrade.h" /* for UPGRADE_IF_NEEDED flag */ #include "cws_insert.h" /* for CWS_REORG_ARRAYSIZE */ #ifdef UNICODE_SUPPORTED #include "gtm_icu_api.h" #include "gtm_utf8.h" #endif # ifdef GTM_CRYPT # include "gtmcrypt.h" # include "gdsblk.h" # include "muextr.h" # endif #ifdef GTM_TRIGGER #include "gv_trigger.h" #include "gtm_trigger.h" #endif #define DEFAULT_ZERROR_STR "Unprocessed $ZERROR, see $ZSTATUS" #define DEFAULT_ZERROR_LEN (SIZEOF(DEFAULT_ZERROR_STR) - 1) GBLDEF gd_region *db_init_region; GBLDEF sgmnt_data_ptr_t cs_data; GBLDEF sgmnt_addrs *cs_addrs; GBLDEF sgmnt_addrs *cs_addrs_list; /* linked list of csa corresponding to all currently open databases */ GBLDEF unsigned short proc_act_type; GBLDEF volatile bool ctrlc_pending; GBLDEF volatile int4 ctrap_action_is; GBLDEF bool out_of_time; GBLDEF io_pair io_curr_device; /* current device */ GBLDEF io_pair io_std_device; /* standard device */ GBLDEF io_log_name *dollar_principal; /* pointer to log name GTM$PRINCIPAL if defined */ GBLDEF bool prin_in_dev_failure = FALSE; GBLDEF bool prin_out_dev_failure = FALSE; GBLDEF io_desc *active_device; GBLDEF bool error_mupip = FALSE, file_backed_up = FALSE, gv_replopen_error = FALSE, gv_replication_error = FALSE, incremental = FALSE, jobpid = FALSE, online = FALSE, record = FALSE, std_dev_outbnd = FALSE, in_mupip_freeze = FALSE, in_backup = FALSE, view_debug1 = FALSE, view_debug2 = FALSE, view_debug3 = FALSE, view_debug4 = FALSE, mupip_error_occurred, dec_nofac; GBLDEF boolean_t is_updproc = FALSE, is_updhelper = FALSE, mupip_jnl_recover = FALSE, repl_allowed = FALSE, suspend_lvgcol = FALSE, run_time = FALSE, unhandled_stale_timer_pop = FALSE, gtcm_connection = FALSE, is_replicator = FALSE, /* TRUE => this process can write jnl records to the jnlpool for replicated db */ tp_in_use = FALSE, /* TRUE => TP has been used by this process and is thus initialized */ dollar_truth = TRUE, have_standalone_access = FALSE, gtm_stdxkill = FALSE; /* TRUE => Use M Standard X-KILL - FALSE use historical GTM X-KILL (default) */ GBLDEF VSIG_ATOMIC_T forced_exit = FALSE; /* Asynchronous signal/interrupt handler sets this variable to TRUE, * hence the VSIG_ATOMIC_T type in the definition. */ GBLDEF intrpt_state_t intrpt_ok_state = INTRPT_OK_TO_INTERRUPT; /* any other value implies it is not ok to interrupt */ GBLDEF unsigned char *msp, *mubbuf, *restart_ctxt, *stackbase, *stacktop, *stackwarn, *restart_pc; GBLDEF int4 backup_close_errno, backup_write_errno, mubmaxblk, forced_exit_err, exit_state, restore_read_errno; GBLDEF volatile int4 outofband, crit_count = 0; GBLDEF int mumps_status = SS_NORMAL, stp_array_size = 0; GBLDEF gvzwrite_datablk *gvzwrite_block; GBLDEF lvzwrite_datablk *lvzwrite_block; GBLDEF io_log_name *io_root_log_name; GBLDEF mliteral literal_chain; GBLDEF mstr *comline_base, *err_act, **stp_array, extnam_str, env_gtm_env_xlate; GBLDEF MSTR_CONST(default_sysid, "gtm_sysid"); GBLDEF mval dollar_zgbldir, dollar_zsource = DEFINE_MVAL_STRING(MV_STR, 0, 0, 0, NULL, 0, 0), dollar_zstatus, dollar_zstep = DEFINE_MVAL_STRING(MV_STR | MV_NM | MV_INT | MV_NUM_APPROX, 0, 0, 1, "B", 0, 0), dollar_ztrap, ztrap_pop2level = DEFINE_MVAL_STRING(MV_NM | MV_INT, 0, 0, 0, 0, 0, 0), zstep_action, dollar_system, dollar_estack_delta = DEFINE_MVAL_STRING(MV_STR, 0, 0, 0, NULL, 0, 0), dollar_etrap, dollar_zerror = DEFINE_MVAL_STRING(MV_STR, 0, 0, DEFAULT_ZERROR_LEN, DEFAULT_ZERROR_STR, 0, 0), dollar_zyerror, dollar_ztexit = DEFINE_MVAL_STRING(MV_STR, 0, 0, 0, NULL, 0, 0); GBLDEF uint4 dollar_zjob; GBLDEF mval dollar_zinterrupt; GBLDEF boolean_t dollar_zininterrupt; GBLDEF boolean_t dollar_ztexit_bool; /* Truth value of dollar_ztexit when coerced to boolean */ GBLDEF boolean_t dollar_zquit_anyway; GBLDEF mv_stent *mv_chain; GBLDEF sgm_info *first_sgm_info; /* List of participating regions in the TP transaction with NO ftok ordering */ GBLDEF sgm_info *first_tp_si_by_ftok; /* List of participating regions in the TP transaction sorted on ftok order */ GBLDEF spdesc indr_stringpool, rts_stringpool, stringpool; GBLDEF stack_frame *frame_pointer; GBLDEF stack_frame *zyerr_frame = NULL; GBLDEF symval *curr_symval; GBLDEF tp_frame *tp_pointer; GBLDEF tp_region *halt_ptr, *grlist; GBLDEF trans_num local_tn; /* transaction number for THIS PROCESS (starts at 0 each time) */ GBLDEF trans_num tstart_local_tn; /* copy of global variable "local_tn" at op_tstart time */ GBLDEF gv_namehead *gv_target; GBLDEF gv_namehead *gv_target_list; /* List of ALL gvts that were allocated (in targ_alloc) by this process */ GBLDEF gv_namehead *gvt_tp_list; /* List of gvts that were referenced in the current TP transaction */ GBLDEF gvt_container *gvt_pending_list; /* list of gvts that need to be re-examined/re-allocated when region is opened */ GBLDEF buddy_list *gvt_pending_buddy_list;/* buddy_list for maintaining memory for gv_targets to be re-examined/allocated */ GBLDEF int4 exi_condition; GBLDEF uint4 gtmDebugLevel; GBLDEF caddr_t smCallerId; /* Caller of top level malloc/free */ GBLDEF int process_exiting; GBLDEF int4 dollar_zsystem; GBLDEF int4 dollar_zeditor; GBLDEF boolean_t sem_incremented = FALSE; GBLDEF boolean_t new_dbinit_ipc = FALSE; GBLDEF mval **ind_result_array, **ind_result_sp, **ind_result_top; GBLDEF mval **ind_source_array, **ind_source_sp, **ind_source_top; GBLDEF rtn_tabent *rtn_fst_table, *rtn_names, *rtn_names_top, *rtn_names_end; GBLDEF int4 break_message_mask; GBLDEF bool rc_locked = FALSE; GBLDEF boolean_t certify_all_blocks = FALSE; /* If flag is set all blocks are checked after they are * written to the database. Upon error we stay critical * and report. This flag can be set via the MUMPS command * VIEW "GDSCERT":1. */ GBLDEF mval curr_gbl_root; GBLDEF gd_addr *original_header; GBLDEF hash_table_str *complits_hashtab = NULL; GBLDEF hash_table_str *compsyms_hashtab = NULL; GBLDEF mem_list *mem_list_head; GBLDEF boolean_t debug_mupip; GBLDEF unsigned char t_fail_hist[CDB_MAX_TRIES]; /* type has to be unsigned char and not enum cdb_sc to ensure single byte */ GBLDEF cache_rec_ptr_t cr_array[((MAX_BT_DEPTH * 2) - 1) * 2]; /* Maximum number of blocks that can be in transaction */ GBLDEF unsigned int cr_array_index; GBLDEF boolean_t need_core; /* Core file should be created */ GBLDEF boolean_t created_core; /* core file was created */ GBLDEF boolean_t core_in_progress; /* creating core NOW */ GBLDEF boolean_t dont_want_core; /* Higher level flag overrides need_core set by lower level rtns */ GBLDEF boolean_t exit_handler_active; /* recursion prevention */ GBLDEF boolean_t block_saved; #if defined(KEEP_zOS_EBCDIC) || defined(VMS) GBLDEF iconv_t dse_over_cvtcd = (iconv_t)0; #endif GBLDEF gtm_chset_t dse_over_chset = CHSET_M; GBLDEF char window_token; GBLDEF mval window_mval; GBLDEF char director_token; GBLDEF mval director_mval; LITDEF MIDENT_DEF(zero_ident, 0, NULL); /* the null mident */ static char ident_buff1[SIZEOF(mident_fixed)]; static char ident_buff2[SIZEOF(mident_fixed)]; GBLDEF MIDENT_DEF(window_ident, 0, &ident_buff1[0]); /* the current identifier */ GBLDEF MIDENT_DEF(director_ident, 0, &ident_buff2[0]); /* the look-ahead identifier */ GBLDEF char *lexical_ptr; GBLDEF int4 aligned_source_buffer[MAX_SRCLINE / SIZEOF(int4) + 1]; GBLDEF unsigned char *source_buffer = (unsigned char *)aligned_source_buffer; GBLDEF src_line_struct src_head; GBLDEF short int source_column, source_line; GBLDEF bool devctlexp; GBLDEF char cg_phase; /* code generation phase */ /* Previous code generation phase: Only used by emit_code.c to initialize the push list at the * beginning of each phase (bug fix: C9D12-002478) */ GBLDEF char cg_phase_last; GBLDEF int cmd_cnt; GBLDEF command_qualifier glb_cmd_qlf = { CQ_DEFAULT }, cmd_qlf = { CQ_DEFAULT }; #ifdef __osf__ #pragma pointer_size (save) #pragma pointer_size (long) #endif GBLDEF char **cmd_arg; #ifdef __osf__ #pragma pointer_size (restore) #endif #ifdef UNIX GBLDEF volatile uint4 heartbeat_counter = 0; #endif /* DEFERRED EVENTS */ GBLDEF int dollar_zmaxtptime = 0; GBLDEF bool licensed = TRUE; #if defined(UNIX) GBLDEF volatile int4 num_deferred; #elif defined(VMS) GBLDEF volatile short num_deferred; GBLDEF int4 lkid, lid; GBLDEF desblk exi_blk; GBLDEF struct chf$signal_array *tp_restart_fail_sig; GBLDEF boolean_t tp_restart_fail_sig_used; #else # error "Unsupported Platform" #endif GBLDEF volatile int4 fast_lock_count = 0; /* Used in wcs_stale */ /* REPLICATION RELATED GLOBALS */ GBLDEF gtmsource_options_t gtmsource_options; GBLDEF gtmrecv_options_t gtmrecv_options; GBLDEF boolean_t is_tracing_on; GBLDEF void (*tp_timeout_start_timer_ptr)(int4 tmout_sec) = tp_start_timer_dummy; GBLDEF void (*tp_timeout_clear_ptr)(void) = tp_clear_timeout_dummy; GBLDEF void (*tp_timeout_action_ptr)(void) = tp_timeout_action_dummy; GBLDEF void (*ctrlc_handler_ptr)() = ctrlc_handler_dummy; GBLDEF int (*op_open_ptr)(mval *v, mval *p, int t, mval *mspace) = op_open_dummy; GBLDEF void (*unw_prof_frame_ptr)(void) = unw_prof_frame_dummy; GBLDEF boolean_t mu_reorg_process = FALSE; /* set to TRUE by MUPIP REORG */ GBLDEF boolean_t mu_reorg_in_swap_blk = FALSE; /* set to TRUE for the duration of the call to "mu_swap_blk" */ GBLDEF boolean_t mu_rndwn_process = FALSE; GBLDEF gv_key *gv_currkey_next_reorg; GBLDEF gv_namehead *reorg_gv_target; #ifdef UNIX GBLDEF struct sockaddr_un gtmsecshr_sock_name; GBLDEF struct sockaddr_un gtmsecshr_cli_sock_name; GBLDEF key_t gtmsecshr_key; #endif GBLDEF int gtmsecshr_sockpath_len; GBLDEF int gtmsecshr_cli_sockpath_len; GBLDEF mstr gtmsecshr_pathname; GBLDEF int server_start_tries; GBLDEF int gtmsecshr_log_file; GBLDEF int gtmsecshr_sockfd = FD_INVALID; GBLDEF boolean_t gtmsecshr_sock_init_done = FALSE; GBLDEF char muext_code[MUEXT_MAX_TYPES][2] = { # define MUEXT_TABLE_ENTRY(muext_rectype, code0, code1) {code0, code1}, # include "muext_rec_table.h" # undef MUEXT_TABLE_ENTRY }; GBLDEF int patch_is_fdmp; GBLDEF int patch_fdmp_recs; GBLDEF boolean_t horiz_growth = FALSE; GBLDEF int4 prev_first_off, prev_next_off; /* these two globals store the values of first_off and next_off in cse, * when there is a blk split at index level. This is to permit rollback * to intermediate states */ GBLDEF sm_uc_ptr_t min_mmseg; GBLDEF sm_uc_ptr_t max_mmseg; GBLDEF mmseg *mmseg_head; GBLDEF ua_list *first_ua, *curr_ua; GBLDEF char *update_array, *update_array_ptr; GBLDEF int gv_fillfactor = 100, rc_set_fragment; /* Contains offset within data at which data fragment starts */ GBLDEF uint4 update_array_size = 0, cumul_update_array_size = 0; /* the current total size of the update array */ GBLDEF kill_set *kill_set_tail; GBLDEF boolean_t pool_init = FALSE; GBLDEF boolean_t is_src_server = FALSE; GBLDEF boolean_t is_rcvr_server = FALSE; GBLDEF jnl_format_buffer *non_tp_jfb_ptr = NULL; GBLDEF unsigned char *non_tp_jfb_buff_ptr; GBLDEF boolean_t dse_running = FALSE; GBLDEF jnlpool_addrs jnlpool; GBLDEF jnlpool_ctl_ptr_t jnlpool_ctl; GBLDEF jnlpool_ctl_struct temp_jnlpool_ctl_struct; GBLDEF jnlpool_ctl_ptr_t temp_jnlpool_ctl = &temp_jnlpool_ctl_struct; GBLDEF sm_uc_ptr_t jnldata_base; GBLDEF int4 jnlpool_shmid = INVALID_SHMID; GBLDEF recvpool_addrs recvpool; GBLDEF int recvpool_shmid = INVALID_SHMID; GBLDEF int gtmsource_srv_count = 0; GBLDEF int gtmrecv_srv_count = 0; /* The following _in_prog counters are needed to prevent deadlocks while doing jnl-qio (timer & non-timer). */ GBLDEF volatile int4 db_fsync_in_prog; GBLDEF volatile int4 jnl_qio_in_prog; #ifdef UNIX GBLDEF void (*op_write_ptr)(mval *); GBLDEF void (*op_wteol_ptr)(int4 n); GBLDEF gtmsiginfo_t signal_info; #ifndef MUTEX_MSEM_WAKE GBLDEF int mutex_sock_fd = FD_INVALID; GBLDEF struct sockaddr_un mutex_sock_address; GBLDEF struct sockaddr_un mutex_wake_this_proc; GBLDEF int mutex_wake_this_proc_len; GBLDEF int mutex_wake_this_proc_prefix_len; GBLDEF fd_set mutex_wait_on_descs; #endif #endif GBLDEF void (*call_on_signal)(); GBLDEF enum gtmImageTypes image_type; /* initialized at startup i.e. in dse.c, lke.c, gtm.c, mupip.c, gtmsecshr.c etc. */ #ifdef UNIX GBLDEF parmblk_struct *param_list; /* call-in parameters block (defined in unix/fgncalsp.h)*/ GBLDEF unsigned int invocation_mode = MUMPS_COMPILE; /* how mumps has been invoked */ GBLDEF char cli_err_str[MAX_CLI_ERR_STR] = ""; /* Parse Error message buffer */ GBLDEF char *cli_err_str_ptr = NULL; GBLDEF io_desc *gtm_err_dev = NULL; GBLDEF boolean_t gtm_pipe_child = FALSE; #endif /* this array is indexed by file descriptor */ GBLDEF boolean_t *lseekIoInProgress_flags = (boolean_t *)0; #if defined(UNIX) /* Latch variable for Unix implementations. Used in SUN and HP */ GBLDEF global_latch_t defer_latch; #endif GBLDEF int num_additional_processors; GBLDEF int gtm_errno = -1; /* holds the errno (unix) in case of an rts_error */ GBLDEF int4 error_condition = 0; GBLDEF global_tlvl_info *global_tlvl_info_head; GBLDEF buddy_list *global_tlvl_info_list; GBLDEF boolean_t job_try_again; GBLDEF volatile int4 gtmMallocDepth; /* Recursion indicator */ GBLDEF d_socket_struct *socket_pool; GBLDEF boolean_t mu_star_specified; GBLDEF backup_reg_list *mu_repl_inst_reg_list; #ifndef VMS GBLDEF volatile int suspend_status = NO_SUSPEND; #endif GBLDEF gv_namehead *reset_gv_target = INVALID_GV_TARGET; GBLDEF VSIG_ATOMIC_T util_interrupt = 0; GBLDEF sgmnt_addrs *kip_csa; GBLDEF boolean_t need_kip_incr; GBLDEF int merge_args = 0; GBLDEF merge_glvn_ptr mglvnp = NULL; GBLDEF int ztrap_form; GBLDEF boolean_t ztrap_new; GBLDEF int4 wtfini_in_prog; /* items for $piece stats */ #ifdef DEBUG GBLDEF int c_miss; /* cache misses (debug) */ GBLDEF int c_hit; /* cache hits (debug) */ GBLDEF int c_small; /* scanned small string brute force */ GBLDEF int c_small_pcs; /* chars scanned by small scan */ GBLDEF int c_pskip; /* number of pieces "skipped" */ GBLDEF int c_pscan; /* number of pieces "scanned" */ GBLDEF int c_parscan; /* number of partial scans (partial cache hits) */ GBLDEF int cs_miss; /* cache misses (debug) */ GBLDEF int cs_hit; /* cache hits (debug) */ GBLDEF int cs_small; /* scanned small string brute force */ GBLDEF int cs_small_pcs; /* chars scanned by small scan */ GBLDEF int cs_pskip; /* number of pieces "skipped" */ GBLDEF int cs_pscan; /* number of pieces "scanned" */ GBLDEF int cs_parscan; /* number of partial scans (partial cache hits) */ GBLDEF int c_clear; /* cleared due to (possible) value change */ GBLDEF boolean_t setp_work; #endif GBLDEF z_records zbrk_recs = {NULL, NULL, NULL}; #ifdef UNIX GBLDEF ipcs_mesg db_ipcs; /* For requesting gtmsecshr to update ipc fields */ GBLDEF gd_region *ftok_sem_reg = NULL; /* Last region for which ftok semaphore is grabbed */ GBLDEF gd_region *standalone_reg = NULL; /* We have standalone access for this region */ GBLDEF int gtm_non_blocked_write_retries; /* number of retries for non-blocked write to pipe */ #endif #ifdef VMS /* Following global variables store the state of an erroring sys$qio just before a GTMASSERT in the CHECK_CHANNEL_STATUS macro */ GBLDEF uint4 check_channel_status = 0; /* stores the qio return status */ GBLDEF uint4 check_channel_id = 0; /* stores the qio channel id */ #endif GBLDEF boolean_t write_after_image = FALSE; /* true for after-image jnlrecord writing by recover/rollback */ GBLDEF int iott_write_error; GBLDEF int4 write_filter; GBLDEF boolean_t need_no_standalone = FALSE; GBLDEF int4 zdir_form = ZDIR_FORM_FULLPATH; /* $ZDIR shows full path including DEVICE and DIRECTORY */ GBLDEF mval dollar_zdir = DEFINE_MVAL_STRING(MV_STR, 0, 0, 0, NULL, 0, 0); GBLDEF int * volatile var_on_cstack_ptr = NULL; /* volatile pointer to int; volatile so that nothing gets optimized out */ GBLDEF hash_table_int4 cw_stagnate; GBLDEF boolean_t cw_stagnate_reinitialized = FALSE; GBLDEF uint4 pat_everything[] = { 0, 2, PATM_E, 1, 0, PAT_MAX_REPEAT, 0, PAT_MAX_REPEAT, 1 }; /* pattern = ".e" */ GBLDEF mstr_len_t sizeof_pat_everything = SIZEOF(pat_everything); GBLDEF uint4 *pattern_typemask; GBLDEF pattern *pattern_list; GBLDEF pattern *curr_pattern; /* Unicode related data */ GBLDEF boolean_t gtm_utf8_mode; /* Is GT.M running with Unicode Character Set; Set only after ICU initialization */ GBLDEF boolean_t is_gtm_chset_utf8; /* Is gtm_chset environment variable set to UTF8 */ GBLDEF boolean_t utf8_patnumeric; /* Should patcode N match non-ASCII numbers in pattern match ? */ GBLDEF boolean_t badchar_inhibit = FALSE;/* Suppress malformed UTF-8 characters by default */ GBLDEF MSTR_DEF(dollar_zchset, 1, "M"); GBLDEF MSTR_DEF(dollar_zpatnumeric, 1, "M"); /* Standard MUMPS pattern-match table. * This table holds the current pattern-matching attributes of each ASCII character. * Bits 0..23 of each entry correspond with the pattern-match characters, A..X. */ GBLDEF pattern mumps_pattern = { (void *) 0, /* flink */ (void *) 0, /* typemask */ (void *) 0, /* pat YZ name array */ (void *) 0, /* pat YZ name-length array */ -1, /* number of YZ patcodes */ 1, /* namlen */ {'M', '\0'} /* name */ }; /* mapbit is used by pattab.c and patstr.c. Note that patstr.c uses only entries until PATM_X */ GBLDEF readonly uint4 mapbit[] = { PATM_A, PATM_B, PATM_C, PATM_D, PATM_E, PATM_F, PATM_G, PATM_H, PATM_I, PATM_J, PATM_K, PATM_L, PATM_M, PATM_N, PATM_O, PATM_P, PATM_Q, PATM_R, PATM_S, PATM_T, PATM_U, PATM_V, PATM_W, PATM_X, PATM_YZ1, PATM_YZ2, PATM_YZ3, PATM_YZ4 }; LITDEF uint4 typemask[PATENTS] = { PATM_C, PATM_C, PATM_C, PATM_C, PATM_C, PATM_C, PATM_C, PATM_C, /* hex 00-07 : ASCII characters */ PATM_C, PATM_C, PATM_C, PATM_C, PATM_C, PATM_C, PATM_C, PATM_C, /* hex 08-0F : ASCII characters */ PATM_C, PATM_C, PATM_C, PATM_C, PATM_C, PATM_C, PATM_C, PATM_C, /* hex 10-17 : ASCII characters */ PATM_C, PATM_C, PATM_C, PATM_C, PATM_C, PATM_C, PATM_C, PATM_C, /* hex 18-1F : ASCII characters */ PATM_P, PATM_P, PATM_P, PATM_P, PATM_P, PATM_P, PATM_P, PATM_P, /* hex 20-27 : ASCII characters */ PATM_P, PATM_P, PATM_P, PATM_P, PATM_P, PATM_P, PATM_P, PATM_P, /* hex 28-2F : ASCII characters */ PATM_N, PATM_N, PATM_N, PATM_N, PATM_N, PATM_N, PATM_N, PATM_N, /* hex 30-37 : ASCII characters */ PATM_N, PATM_N, PATM_P, PATM_P, PATM_P, PATM_P, PATM_P, PATM_P, /* hex 38-3F : ASCII characters */ PATM_P, PATM_U, PATM_U, PATM_U, PATM_U, PATM_U, PATM_U, PATM_U, /* hex 40-47 : ASCII characters */ PATM_U, PATM_U, PATM_U, PATM_U, PATM_U, PATM_U, PATM_U, PATM_U, /* hex 48-4F : ASCII characters */ PATM_U, PATM_U, PATM_U, PATM_U, PATM_U, PATM_U, PATM_U, PATM_U, /* hex 50-57 : ASCII characters */ PATM_U, PATM_U, PATM_U, PATM_P, PATM_P, PATM_P, PATM_P, PATM_P, /* hex 58-5F : ASCII characters */ PATM_P, PATM_L, PATM_L, PATM_L, PATM_L, PATM_L, PATM_L, PATM_L, /* hex 60-67 : ASCII characters */ PATM_L, PATM_L, PATM_L, PATM_L, PATM_L, PATM_L, PATM_L, PATM_L, /* hex 68-6F : ASCII characters */ PATM_L, PATM_L, PATM_L, PATM_L, PATM_L, PATM_L, PATM_L, PATM_L, /* hex 70-77 : ASCII characters */ PATM_L, PATM_L, PATM_L, PATM_P, PATM_P, PATM_P, PATM_P, PATM_C, /* hex 78-7F : ASCII characters */ PATM_C, PATM_C, PATM_C, PATM_C, PATM_C, PATM_C, PATM_C, PATM_C, /* hex 80-87 : non-ASCII characters */ PATM_C, PATM_C, PATM_C, PATM_C, PATM_C, PATM_C, PATM_C, PATM_C, /* hex 88-8F : non-ASCII characters */ PATM_C, PATM_C, PATM_C, PATM_C, PATM_C, PATM_C, PATM_C, PATM_C, /* hex 90-97 : non-ASCII characters */ PATM_C, PATM_C, PATM_C, PATM_C, PATM_C, PATM_C, PATM_C, PATM_C, /* hex 98-9F : non-ASCII characters */ PATM_P, PATM_P, PATM_P, PATM_P, PATM_P, PATM_P, PATM_P, PATM_P, /* hex A0-A7 : non-ASCII characters */ PATM_P, PATM_P, PATM_L, PATM_P, PATM_P, PATM_P, PATM_P, PATM_P, /* hex A8-AF : non-ASCII characters */ PATM_P, PATM_P, PATM_P, PATM_P, PATM_P, PATM_P, PATM_P, PATM_P, /* hex B0-B7 : non-ASCII characters */ PATM_P, PATM_P, PATM_L, PATM_P, PATM_P, PATM_P, PATM_P, PATM_P, /* hex B8-BF : non-ASCII characters */ PATM_U, PATM_U, PATM_U, PATM_U, PATM_U, PATM_U, PATM_U, PATM_U, /* hex C0-C7 : non-ASCII characters */ PATM_U, PATM_U, PATM_U, PATM_U, PATM_U, PATM_U, PATM_U, PATM_U, /* hex C8-CF : non-ASCII characters */ PATM_P, PATM_U, PATM_U, PATM_U, PATM_U, PATM_U, PATM_U, PATM_U, /* hex D0-D7 : non-ASCII characters */ PATM_U, PATM_U, PATM_U, PATM_U, PATM_U, PATM_U, PATM_P, PATM_L, /* hex D8-DF : non-ASCII characters */ PATM_L, PATM_L, PATM_L, PATM_L, PATM_L, PATM_L, PATM_L, PATM_L, /* hex E0-E7 : non-ASCII characters */ PATM_L, PATM_L, PATM_L, PATM_L, PATM_L, PATM_L, PATM_L, PATM_L, /* hex E8-EF : non-ASCII characters */ PATM_P, PATM_L, PATM_L, PATM_L, PATM_L, PATM_L, PATM_L, PATM_L, /* hex F0-F7 : non-ASCII characters */ PATM_L, PATM_L, PATM_L, PATM_L, PATM_L, PATM_L, PATM_P, PATM_C /* hex F8-FF : non-ASCII characters */ }; GBLDEF uint4 pat_allmaskbits; /* universal set of valid pattern bit codes for currently active pattern table */ /* globals related to caching of pattern evaluation match result. * for a given tuple, we store the evaluation result. * in the above, * uniquely identifies a substring of the input string. * identifies the pattern atom that we are matching with * identifies the recursion depth of do_patalt() for this pattern atom ("repcnt" in code) * note that is a necessity in the above because the same alternation pattern atom can have different * match or not-match status for the same input string depending on the repetition count usage of the pattern atom * after a series of thoughts on an efficient structure for storing pattern evaluation, finally arrived at a simple * array of structures wherein for a given length (strlen) we have a fixed number of structures available. * we allocate an array of structures, say, 1024 structures. * this is a simple 1-1 mapping, wherein * for length 0, the available structures are the first 32 structures of the array, * for length 1, the available structures are the second 32 structures of the array. * ... * for length 47, the available structures are the 47th 32 structures of the array. * for length 48 and above, the available structures are all the remaining structures of the array. * whenever any new entry needs to be cached and there is no room among the available structures, we preempt the * most unfrequently used cache entry (to do this we do keep a count of every entry's frequency of usage) * the assumption is that substrings of length > 48 (an arbitrary reasonable small number) won't be used * so frequently so that they have lesser entries to fight for among themselves than lower values of length. * with the above caching in place, the program segment below took 15 seconds. * it was found that if the array size is increased to 16384 (as opposed to 1024 as above) and the available * structures for each length increased proportionally (i.e. 16 times = 16*32 structures instead of 32 as above) * the performance improved to the extent of taking 3 seconds. * but this raised an interesting question, that of "size" vs. "time" tradeoff. * with increasing array size, we get better "time" performance due to better caching. * but that has an overhead of increased "size" (memory) usage. * to arrive at a compromise, a dynamic algorithm emerged. the process will allocate a small array * beginning at 1024 entries and grow to a max of 16384 entries as and when it deems the hit ratio is not good. * the array only grows, i.e. there is no downsizing algorithm at play. * the dynamic algorithm addresses to an extent both the "size" and "time" issues and finishes the below in 1 second. * #defines for the dynamic algorithm growth can be found in patcode.h */ GBLDEF int4 curalt_depth = -1; /* depth of alternation nesting */ GBLDEF int4 do_patalt_calls[PTE_MAX_CURALT_DEPTH]; /* number of calls to do_patalt() */ GBLDEF int4 do_patalt_hits[PTE_MAX_CURALT_DEPTH]; /* number of pte_csh hits in do_patalt() */ GBLDEF int4 do_patalt_maxed_out[PTE_MAX_CURALT_DEPTH]; /* no. of pte_csh misses after maxing on allocation size */ GBLDEF pte_csh *pte_csh_array[PTE_MAX_CURALT_DEPTH]; /* pte_csh array (per curalt_depth) */ GBLDEF int4 pte_csh_cur_size[PTE_MAX_CURALT_DEPTH]; /* current pte_csh size (per curalt_depth) */ GBLDEF int4 pte_csh_alloc_size[PTE_MAX_CURALT_DEPTH]; /* current allocated pte_csh size (per curalt_depth) */ GBLDEF int4 pte_csh_entries_per_len[PTE_MAX_CURALT_DEPTH]; /* current number of entries per len */ GBLDEF int4 pte_csh_tail_count[PTE_MAX_CURALT_DEPTH]; /* count of non 1-1 corresponding pte_csh_array members */ GBLDEF pte_csh *cur_pte_csh_array; /* copy of pte_csh_array corresponding to curalt_depth */ GBLDEF int4 cur_pte_csh_size; /* copy of pte_csh_cur_size corresponding to curalt_depth */ GBLDEF int4 cur_pte_csh_entries_per_len; /* copy of pte_csh_entries_per_len corresponding to curalt_depth */ GBLDEF int4 cur_pte_csh_tail_count; /* copy of pte_csh_tail_count corresponding to curalt_depth */ GBLDEF readonly char *before_image_lit[] = {"NOBEFORE_IMAGES", "BEFORE_IMAGES"}; GBLDEF readonly char *jnl_state_lit[] = {"DISABLED", "OFF", "ON"}; GBLDEF readonly char *repl_state_lit[] = {"OFF", "ON", "WAS_ON"}; GBLDEF boolean_t crit_sleep_expired; /* mutex.mar: signals that a timer waiting for crit has expired */ GBLDEF uint4 crit_deadlock_check_cycle; /* compared to csa->crit_check_cycle to determine if a given region in a transaction legitimately has crit or not */ GBLDEF node_local_ptr_t locknl; /* if non-NULL, indicates node-local of interest to the LOCK_HIST macro */ GBLDEF boolean_t in_mutex_deadlock_check; /* if TRUE, mutex_deadlock_check() is part of our current C-stack trace */ /* $ECODE and $STACK related variables. * error_frame and skip_error_ret should ideally be part of dollar_ecode structure. since sr_avms/opp_ret.m64 uses these * global variables and it was felt risky changing it to access a member of a structure, they are kept as separate globals */ GBLDEF stack_frame *error_frame; /* ptr to frame where last error occurred or was rethrown */ GBLDEF boolean_t skip_error_ret; /* set to TRUE by golevel(), used and reset by op_unwind() */ GBLDEF dollar_ecode_type dollar_ecode; /* structure containing $ECODE related information */ GBLDEF dollar_stack_type dollar_stack; /* structure containing $STACK related information */ GBLDEF boolean_t ztrap_explicit_null; /* whether $ZTRAP was explicitly set to NULL in the current frame */ GBLDEF int4 gtm_object_size; /* Size of entire gtm object for compiler use */ GBLDEF int4 linkage_size; /* Size of linkage section during compile */ GBLDEF uint4 lnkrel_cnt; /* number of entries in linkage Psect to relocate */ GBLDEF int4 sym_table_size; /* size of the symbol table during compilation */ GBLDEF boolean_t stop_non_mandatory_expansion, non_mandatory_expansion; /* Used in stringpool managment */ GBLDEF jnl_fence_control jnl_fence_ctl; GBLDEF jnl_process_vector *prc_vec = NULL; /* for current process */ GBLDEF jnl_process_vector *originator_prc_vec = NULL; /* for client/originator */ LITDEF char *jrt_label[JRT_RECTYPES] = { #define JNL_TABLE_ENTRY(rectype, extract_rtn, label, update, fixed_size, is_replicated) label, #include "jnl_rec_table.h" /* BYPASSOK */ #undef JNL_TABLE_ENTRY }; LITDEF int jrt_update[JRT_RECTYPES] = { #define JNL_TABLE_ENTRY(rectype, extract_rtn, label, update, fixed_size, is_replicated) update, #include "jnl_rec_table.h" /* BYPASSOK */ #undef JNL_TABLE_ENTRY }; LITDEF boolean_t jrt_fixed_size[JRT_RECTYPES] = { #define JNL_TABLE_ENTRY(rectype, extract_rtn, label, update, fixed_size, is_replicated) fixed_size, #include "jnl_rec_table.h" /* BYPASSOK */ #undef JNL_TABLE_ENTRY }; LITDEF boolean_t jrt_is_replicated[JRT_RECTYPES] = { #define JNL_TABLE_ENTRY(rectype, extract_rtn, label, update, fixed_size, is_replicated) is_replicated, #include "jnl_rec_table.h" /* BYPASSOK */ #undef JNL_TABLE_ENTRY }; /* Change the initialization if struct_jrec_tcom in jnl.h changes */ GBLDEF struct_jrec_tcom tcom_record = {{JRT_TCOM, TCOM_RECLEN, 0, 0, 0}, 0, 0, 0, "", {TCOM_RECLEN, JNL_REC_SUFFIX_CODE}}; GBLDEF jnl_gbls_t jgbl; GBLDEF short crash_count; GBLDEF trans_num start_tn; GBLDEF cw_set_element cw_set[CDB_CW_SET_SIZE]; GBLDEF unsigned char cw_set_depth, cw_map_depth; GBLDEF unsigned int t_tries; GBLDEF uint4 t_err; GBLDEF uint4 update_trans; /* Bitmask indicating among other things whether this region was updated; * See gdsfhead.h for UPDTRNS_* bitmasks * Bit-0 is 1 if cw_set_depth is non-zero or if it is a duplicate set * (cw_set_depth is zero in that case). * Bit-1 is unused for non-TP. * Bit-2 is 1 if transaction commit in this region is beyond point of rollback. */ GBLDEF boolean_t mu_rndwn_file_dbjnl_flush; /* to indicate standalone access is available to shared memory so * wcs_recover() need not increment db curr_tn or write inctn record */ GBLDEF boolean_t is_uchar_wcs_code[] = /* uppercase failure codes that imply database cache related problem */ { /* if any of the following failure codes are seen in the final retry, wc_blocked will be set to trigger cache recovery */ #define CDB_SC_NUM_ENTRY(code, value) #define CDB_SC_UCHAR_ENTRY(code, is_wcs_code, value) is_wcs_code, #define CDB_SC_LCHAR_ENTRY(code, is_wcs_code, value) #include "cdb_sc_table.h" /* BYPASSOK */ #undef CDB_SC_NUM_ENTRY #undef CDB_SC_UCHAR_ENTRY #undef CDB_SC_LCHAR_ENTRY }; GBLDEF boolean_t is_lchar_wcs_code[] = /* lowercase failure codes that imply database cache related problem */ { /* if any of the following failure codes are seen in the final retry, wc_blocked will be set to trigger cache recovery */ #define CDB_SC_NUM_ENTRY(code, value) #define CDB_SC_UCHAR_ENTRY(code, is_wcs_code, value) #define CDB_SC_LCHAR_ENTRY(code, is_wcs_code, value) is_wcs_code, #include "cdb_sc_table.h" /* BYPASSOK */ #undef CDB_SC_NUM_ENTRY #undef CDB_SC_UCHAR_ENTRY #undef CDB_SC_LCHAR_ENTRY }; GBLDEF boolean_t gvdupsetnoop = FALSE; /* if TRUE, duplicate SETs do not change GDS block (and therefore no PBLK journal * records will be written) although the database transaction number will be * incremented and logical SET journal records will be written. */ GBLDEF boolean_t gtm_fullblockwrites; /* Do full (not partial) database block writes T/F */ UNIX_ONLY(GBLDEF int4 gtm_shmflags;) /* Extra flags for shmat */ #ifdef VMS GBLDEF uint4 gtm_memory_noaccess_defined; /* count of the number of GTM_MEMORY_NOACCESS_ADDR logicals which are defined */ GBLDEF uint4 gtm_memory_noaccess[GTM_MEMORY_NOACCESS_COUNT]; /* see VMS gtm_env_init_sp.c */ #endif GBLDEF volatile boolean_t in_wcs_recover = FALSE; /* TRUE if in "wcs_recover", used by "bt_put" and "generic_exit_handler" */ GBLDEF boolean_t in_gvcst_incr = FALSE; /* set to TRUE by gvcst_incr, set to FALSE by gvcst_put * distinguishes to gvcst_put, if the current db operation is a SET or $INCR */ GBLDEF mval *post_incr_mval; /* mval pointing to the post-$INCR value */ GBLDEF mval increment_delta_mval; /* mval holding the INTEGER increment value, set by gvcst_incr, * used by gvcst_put/gvincr_recompute_upd_array which is invoked by t_end */ GBLDEF boolean_t is_dollar_incr = FALSE; /* valid only if gvcst_put is in the call-stack (i.e. t_err == ERR_GVPUTFAIL); * is a copy of "in_gvcst_incr" just before it got reset to FALSE */ GBLDEF int indir_cache_mem_size; /* Amount of memory currently in use by indirect cache */ GBLDEF hash_table_objcode cache_table; GBLDEF int cache_hits, cache_fails; /* The alignment feature is disabled due to some issues in stringpool garbage collection. * TODO: When we sort out stringpool issues, change mstr_native_align to TRUE below */ GBLDEF boolean_t mstr_native_align = FALSE; GBLDEF boolean_t save_mstr_native_align; GBLDEF mvar *mvartab; GBLDEF mvax *mvaxtab,*mvaxtab_end; GBLDEF mlabel *mlabtab; GBLDEF mline mline_root; GBLDEF mline *mline_tail; GBLDEF short int block_level; GBLDEF triple t_orig; GBLDEF int mvmax, mlmax, mlitmax; static char routine_name_buff[SIZEOF(mident_fixed)], module_name_buff[SIZEOF(mident_fixed)]; static char int_module_name_buff[SIZEOF(mident_fixed)]; GBLDEF MIDENT_DEF(routine_name, 0, &routine_name_buff[0]); GBLDEF MIDENT_DEF(module_name, 0, &module_name_buff[0]); GBLDEF MIDENT_DEF(int_module_name, 0, &int_module_name_buff[0]); GBLDEF char rev_time_buf[REV_TIME_BUFF_LEN]; GBLDEF unsigned short source_name_len; GBLDEF short object_name_len; UNIX_ONLY( GBLDEF unsigned char source_file_name[MAX_FBUFF + 1]; GBLDEF unsigned char object_file_name[MAX_FBUFF + 1]; GBLDEF int object_file_des; ) VMS_ONLY( GBLDEF char source_file_name[PATH_MAX]; GBLDEF char object_file_name[256]; GBLDEF struct FAB obj_fab; /* file access block for the object file */ ) GBLDEF int4 curr_addr, code_size; GBLDEF mident_fixed zlink_mname; GBLDEF sm_uc_ptr_t reformat_buffer; GBLDEF int reformat_buffer_len; GBLDEF volatile int reformat_buffer_in_use; /* used only in DEBUG mode */ GBLDEF boolean_t mu_reorg_upgrd_dwngrd_in_prog; /* TRUE if MUPIP REORG UPGRADE/DOWNGRADE is in progress */ GBLDEF boolean_t mu_reorg_nosafejnl; /* TRUE if NOSAFEJNL explicitly specified */ GBLDEF trans_num mu_reorg_upgrd_dwngrd_blktn; /* tn in blkhdr of current block processed by MUPIP REORG {UP,DOWN}GRADE */ GBLDEF inctn_opcode_t inctn_opcode = inctn_invalid_op; GBLDEF inctn_detail_t inctn_detail; /* holds detail to fill in to inctn jnl record */ GBLDEF uint4 region_open_count; /* Number of region "opens" we have executed */ GBLDEF uint4 gtm_blkupgrade_flag = UPGRADE_IF_NEEDED; /* by default upgrade only if necessary */ GBLDEF boolean_t disk_blk_read; GBLDEF boolean_t gtm_dbfilext_syslog_disable = FALSE; /* by default, log every file extension message */ GBLDEF int4 cws_reorg_remove_index; /* see mu_swap_blk.c for comments on the need for these two */ GBLDEF block_id cws_reorg_remove_array[CWS_REORG_REMOVE_ARRAYSIZE]; GBLDEF uint4 log_interval; #ifdef UNIX GBLDEF uint4 gtm_principal_editing_defaults; /* ext_cap flags if tt */ GBLDEF boolean_t in_repl_inst_edit = FALSE; /* used by an assert in repl_inst_read/repl_inst_write */ GBLDEF boolean_t in_repl_inst_create; /* used by repl_inst_read/repl_inst_write */ GBLDEF boolean_t holds_sem[NUM_SEM_SETS][NUM_SRC_SEMS]; /* whether a particular replication semaphore is being held * by the current process or not. */ GBLDEF boolean_t print_offset; /* Set to TRUE if -DETAIL is specified in MUPIP REPLIC -JNLPOOL or -EDITINST */ GBLDEF boolean_t in_mupip_ftok; /* Used by an assert in repl_inst_read */ GBLDEF uint4 section_offset; /* Used by PRINT_OFFSET_PREFIX macro in repl_inst_dump.c */ GBLDEF uint4 mutex_per_process_init_pid; /* pid that invoked "mutex_per_process_init" */ GBLDEF boolean_t gtm_quiet_halt; /* Suppress FORCEDHALT message */ #endif #ifdef UNICODE_SUPPORTED /* Unicode line terminators. In addition to the following * codepoints, the sequence CR LF is considered a single * line terminator. */ LITDEF UChar32 u32_line_term[] = { 0x000A, /* Line Feed */ 0x000D, /* Carraige Return */ 0x0085, /* Next Line - EBCDIC mostly */ 0x000C, /* Form Feed */ UTF_LINE_SEPARATOR, /* Line Separator */ UTF_PARA_SEPARATOR, /* Paragraph Separator */ 0x0000 }; /* Given the first byte in a UTF-8 representation, the following array returns the total number of bytes in the encoding * 00-7F : 1 byte * C2-DF : 2 bytes * E0-EF : 3 bytes * F0-F4 : 4 bytes * All others: 1 byte * For details on the UTF-8 encoding see gtm_utf8.h */ LITDEF unsigned int utf8_bytelen[] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 00-1F */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 20-3F */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 40-5F */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 60-7F */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 80-9F */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* A0-BF */ 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, /* C0-DF */ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* E0-FF */ }; /* Given the first byte in a UTF-8 representation, the following array returns the number of bytes to follow * 00-7F : 0 byte * C2-DF : 1 byte * E0-EF : 2 bytes * F0-F4 : 3 bytes * All others: -1 bytes * For details on the UTF-8 encoding see gtm_utf8.h */ LITDEF signed int utf8_followlen[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 00-1F */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 20-3F */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 40-5F */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 60-7F */ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, /* 80-9F */ -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, /* A0-BF */ -1,-1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* C0-DF */ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, /* E0-FF */ }; GBLDEF gtm_wcswidth_fnptr_t gtm_wcswidth_fnptr; /* see comment in gtm_utf8.h about this typedef */ #endif GBLDEF uint4 gtm_max_sockets; /* Maximum sockets per socket device supported by this process */ GBLDEF d_socket_struct *newdsocket; /* Commonly used temp socket area */ GBLDEF boolean_t dse_all_dump; /* TRUE if DSE ALL -DUMP is specified */ GBLDEF int socketus_interruptus; /* How many times socket reads have been interrutped */ GBLDEF int4 pending_errtriplecode; /* if non-zero contains the error code to invoke ins_errtriple with */ GBLDEF uint4 process_id; GBLDEF uint4 image_count; /* not used in UNIX but defined to preserve VMS compatibility */ GBLDEF size_t totalRmalloc; /* Total storage currently (real) malloc'd (includes extent blocks) */ GBLDEF size_t totalAlloc; /* Total allocated (includes allocation overhead but not free space */ GBLDEF size_t totalUsed; /* Sum of user allocated portions (totalAlloc - overhead) */ GBLDEF size_t totalRallocGta; /* Total storage currently (real) mmap alloc'd */ GBLDEF size_t totalAllocGta; /* Total mmap allocated (includes allocation overhead but not free space */ GBLDEF size_t totalUsedGta; /* Sum of "in-use" portions (totalAllocGta - overhead) */ GBLDEF volatile char *outOfMemoryMitigation; /* Cache that we will freed to help cleanup if run out of memory */ GBLDEF uint4 outOfMemoryMitigateSize;/* Size of above cache (in Kbytes) */ GBLDEF int mcavail; GBLDEF mcalloc_hdr *mcavailptr, *mcavailbase; GBLDEF uint4 max_cache_memsize; /* Maximum bytes used for indirect cache object code */ GBLDEF uint4 max_cache_entries; /* Maximum number of cached indirect compilations */ GBLDEF void (*cache_table_relobjs)(void); /* Function pointer to call cache_table_rebuild() */ UNIX_ONLY(GBLDEF ch_ret_type (*ht_rhash_ch)()); /* Function pointer to hashtab_rehash_ch */ UNIX_ONLY(GBLDEF ch_ret_type (*jbxm_dump_ch)()); /* Function pointer to jobexam_dump_ch */ #ifdef VMS GBLDEF boolean_t tp_has_kill_t_cse; /* cse->mode of kill_t_write or kill_t_create got created in this transaction */ #endif GBLDEF cache_rec_ptr_t pin_fail_cr; /* Pointer to the cache-record that we failed while pinning */ GBLDEF cache_rec pin_fail_cr_contents; /* Contents of the cache-record that we failed while pinning */ GBLDEF cache_rec_ptr_t pin_fail_twin_cr; /* Pointer to twin of the cache-record that we failed to pin */ GBLDEF cache_rec pin_fail_twin_cr_contents; /* Contents of twin of the cache-record that we failed to pin */ GBLDEF bt_rec_ptr_t pin_fail_bt; /* Pointer to bt of the cache-record that we failed to pin */ GBLDEF bt_rec pin_fail_bt_contents; /* Contents of bt of the cache-record that we failed to pin */ GBLDEF int4 pin_fail_in_crit; /* Holder of crit at the time we failed to pin */ GBLDEF int4 pin_fail_wc_in_free; /* Number of write cache records in free queue when we failed to pin */ GBLDEF int4 pin_fail_wcs_active_lvl; /* Number of entries in active queue when we failed to pin */ GBLDEF int4 pin_fail_ref_cnt; /* Reference count when we failed to pin */ GBLDEF int4 pin_fail_in_wtstart; /* Count of processes in wcs_wtstart when we failed to pin */ GBLDEF int4 pin_fail_phase2_commit_pidcnt; /* Number of processes in phase2 commit when we failed to pin */ GBLDEF zwr_hash_table *zwrhtab; /* How we track aliases during zwrites */ GBLDEF uint4 zwrtacindx; /* When creating $ZWRTACxxx vars for ZWRite, this holds xxx */ GBLDEF uint4 tstartcycle; /* lv_val cycle for tstart operations */ GBLDEF uint4 lvtaskcycle; /* lv_val cycle for misc lv_val related tasks */ GBLDEF int4 SPGC_since_LVGC; /* stringpool GCs since the last lv_val GC */ GBLDEF int4 LVGC_interval = MIN_SPGC_PER_LVGC; /* dead data GC is done every LVGC_interval stringpool GCs */ GBLDEF lv_xnew_var *xnewvar_anchor; /* Anchor for unused lv_xnew_var blocks */ GBLDEF lv_xnew_ref *xnewref_anchor; /* Anchor for unused lv_xnew_ref blocks */ GBLDEF mval *alias_retarg; /* Points to an alias return arg created by a "QUIT *" recorded here so * symtab-unwind logic can find it and modify it if necessary if a * symtab popped during the return and the retarg points to an lv_val * that is going to be destroyed. */ #ifdef DEBUG_ALIAS GBLDEF boolean_t lvmon_enabled; /* Enable lv_val monitoring */ #endif GBLDEF block_id gtm_tp_allocation_clue; /* block# hint to start allocation for created blocks in TP */ #ifdef UNIX GBLDEF int4 gtm_zlib_cmp_level; /* zlib compression level specified at process startup */ GBLDEF int4 repl_zlib_cmp_level; /* zlib compression level currently in use in replication pipe. * This is a source-server specific variable and is non-zero only * if compression is enabled and works in the receiver server as well. */ GBLDEF zlib_cmp_func_t zlib_compress_fnptr; GBLDEF zlib_uncmp_func_t zlib_uncompress_fnptr; #endif GBLDEF mlk_stats_t mlk_stats; /* Process-private M-lock statistics */ #ifdef UNIX /* Initialized blockalrm and block_sigsent can be used by all */ GBLDEF boolean_t blocksig_initialized = FALSE; /* set to TRUE when blockalrm and block_sigsent are initialized */ GBLDEF sigset_t blockalrm; GBLDEF sigset_t block_sigsent; /* block all signals that can be sent externally (SIGINT, SIGQUIT, SIGTERM, SIGTSTP, SIGCONT) */ GBLDEF char *gtm_core_file; GBLDEF char *gtm_core_putenv; #endif #ifdef __MVS__ GBLDEF char *gtm_utf8_locale_object; GBLDEF boolean_t gtm_tag_utf8_as_ascii = TRUE; #endif #ifdef GTM_CRYPT GBLDEF int4 gtmcrypt_init_state; /* Represents the various states of encryption library */ GBLDEF int4 gbl_encryption_ecode; GBLDEF char dl_err[MAX_ERRSTR_LEN]; GBLDEF gtmcrypt_init_t gtmcrypt_init_fnptr; GBLDEF gtmcrypt_close_t gtmcrypt_close_fnptr; GBLDEF gtmcrypt_hash_gen_t gtmcrypt_hash_gen_fnptr; GBLDEF gtmcrypt_encode_t gtmcrypt_encode_fnptr; GBLDEF gtmcrypt_decode_t gtmcrypt_decode_fnptr; GBLDEF gtmcrypt_getkey_by_hash_t gtmcrypt_getkey_by_hash_fnptr; GBLDEF gtmcrypt_getkey_by_name_t gtmcrypt_getkey_by_name_fnptr; GBLDEF gtmcrypt_strerror_t gtmcrypt_strerror_fnptr; #endif /* GTM_CRYPT */ #ifdef DEBUG /* Following definitions are related to white_box testing */ GBLDEF boolean_t gtm_white_box_test_case_enabled = FALSE; GBLDEF int gtm_white_box_test_case_number = 0; GBLDEF int gtm_white_box_test_case_count = 0; GBLDEF int gtm_wbox_input_test_case_count = 0; /* VMS allows maximum 31 characters for external identifer */ GBLDEF boolean_t stringpool_unusable = FALSE; /* Set to TRUE by any function that does not expect any of its function * callgraph to use/expand the stringpool. */ GBLDEF boolean_t stringpool_unexpandable = FALSE;/* Set to TRUE by any function for a small period when it has ensured * enough space in the stringpool so it does not expect any more garbage * collections or expansions. */ GBLDEF boolean_t donot_INVOKE_MUMTSTART = FALSE; /* Set to TRUE whenever an implicit TSTART is done in gvcst_put/kill as * part of an explicit + trigger update. In this situation, we dont expect * MUM_TSTART macro to be invoked at all (see skip_INVOKE_RESTART below * for description on why this is needed). So we keep this debug-only * flag turned on throughout the gvcst_put/kill. An assert in * mdb_condition_handler (invoked by INVOKE_RESTART macro when it does * an rts_error) checks it never gets invoked while this is set. */ #endif GBLDEF boolean_t block_is_free; /* Set to TRUE if the caller wants to let t_qread know that the block it is * attempting to read is actually a FREE block */ GBLDEF int4 gv_keysize; GBLDEF gd_addr *gd_header; GBLDEF gd_binding *gd_map; GBLDEF gd_binding *gd_map_top; #ifdef GTM_TRIGGER GBLDEF int4 gtm_trigger_depth; /* 0 if no trigger, 1 if inside trigger; 2 if inside nested trigger etc. */ GBLDEF int4 tstart_trigger_depth; /* gtm_trigger_depth at the time of the outermost "op_tstart" * (i.e. explicit update). This should be used only if dollar_tlevel * is non-zero as it is not otherwise maintained. */ GBLDEF uint4 trigger_name_cntr; /* Counter from which trigger names are constructed */ GBLDEF boolean_t *ztvalue_changed_ptr; /* -> boolean in current gtm_trigger_parms signaling if ztvalue has been updated */ GBLDEF boolean_t ztwormhole_used; /* TRUE if $ztwormhole was used by trigger code */ GBLDEF mstr *dollar_ztname; GBLDEF mval *dollar_ztdata, *dollar_ztoldval, *dollar_ztriggerop, *dollar_ztupdate, *dollar_ztvalue, dollar_ztwormhole = DEFINE_MVAL_STRING(MV_STR, 0, 0, 0, NULL, 0, 0), dollar_ztslate = DEFINE_MVAL_STRING(MV_STR, 0, 0, 0, NULL, 0, 0), gtm_trigger_etrap; /* Holds $ETRAP value for inside trigger */ GBLDEF int tprestart_state; /* When triggers restart, multiple states possible. See tp_restart.h */ GBLDEF boolean_t skip_INVOKE_RESTART = FALSE; /* set to TRUE if caller of op_tcommit/t_retry does not want it to * use the INVOKE_RESTART macro (which uses an rts_error to trigger * the restart) instead return code. The reason we dont want to do * rts_error is that this is an implicit tstart situation where we * did not do opp_tstart.s so we dont want control to be transferred * using the MUM_TSTART macro by mdb_condition_handler (which assumes * opp_tstart.s invocation). */ GBLDEF boolean_t goframes_unwound_trigger; /* goframes() unwound a trigger base frame during its unwinds */ GBLDEF symval *trigr_symval_list; /* List of availalable symvals for use in (nested) triggers */ GBLDEF boolean_t dollar_ztrigger_invoked; /* $ZTRIGGER() was invoked on at least one region in this transaction */ # ifdef DEBUG GBLDEF gv_trigger_t *gtm_trigdsc_last; /* For debugging purposes - parms gtm_trigger called with */ GBLDEF gtm_trigger_parms *gtm_trigprm_last; GBLDEF ch_ret_type (*ch_at_trigger_init)(); /* Condition handler in effect when gtm_trigger called */ # endif GBLDEF boolean_t explicit_update_repl_state; /* Initialized just before an explicit update invokes any triggers. * Set to 1 if triggering update is to a replicated database. * Set to 0 if triggering update is to a non-replicated database. * Value stays untouched across nested trigger invocations. */ #endif GBLDEF boolean_t skip_dbtriggers = FALSE; /* Set to FALSE by default (i.e. triggers are invoked). Set to TRUE * unconditionally by MUPIP LOAD as it always skips triggers. Also set * to TRUE by journal recovery/update-process only when they encounter * updates done by MUPIP LOAD so they too skip trigger processing. In the * case of update process, this keeps primary/secondary in sync. In the * case of journal recovery, this keeps the db and jnl in sync. */ GBLDEF boolean_t expansion_failed, retry_if_expansion_fails; /* used by string pool when trying to expand */ GBLDEF boolean_t mupip_exit_status_displayed; /* TRUE if mupip_exit has already displayed a message for non-zero status. * Used by mur_close_files to ensure some message gets printed in case * of abnormal exit status (in some cases mupip_exit might not have been * invoked but we will still go through mur_close_files e.g. if exit is * done directly without invoking mupip_exit). */ GBLDEF boolean_t implicit_trollback = FALSE; /* Set to TRUE by OP_TROLLBACK macro before calling op_trollback. Set * to FALSE by op_trollback. Used to indicate op_trollback as to * whether it is being called from generated code (opp_trollback.s) * or from C runtime code. */ GBLDEF boolean_t hold_onto_locks; /* Currently TRUE for the lifetime of an online rollback. This means * a variety of locks (db crit locks, jnlpool crit locks, instance file * ftok locks, db access control semaphore etc.) are held for an extended * period of time by rollback until it terminates. To the database runtime * code, this global primarily signals it NOT to release the crit lock * on ANY region after each transaction commit. Since online rollback is * currently supported only in Unix, this variable is set to FALSE in VMS. * A field "hold_onto_crit" is similarly defined in the "sgmnt_addrs" * structure. This one pertains specifically to the db/jnlpool crit lock. * See comment there on how to decide which one to use in the runtime code. */ #ifdef DEBUG GBLDEF boolean_t ok_to_UNWIND_in_exit_handling; /* see gtm_exit_handler.c for comments */ GBLDEF boolean_t skip_block_chain_tail_check; #endif GBLDEF char gvcst_search_clue;