bool gtcml_lcktime(cm_lckblklck *lck) { ABS_TIME new_blktime; uint4 status; add_int_to_abs_time(&lck->blktime, CM_LKBLK_TIME, &new_blktime); return (0 > abs_time_comp(&chkreg_time, &new_blktime) ? FALSE : TRUE); }
/* Timer handler. This is the main handler routine that is being called by the kernel upon receipt * of timer signal. It dispatches to the user handler routine, and removes first timer in a timer * queue. If the queue is not empty, it starts the first timer in the queue. The why parameter is a * no-op in our case, but is required to maintain compatibility with the system type of __sighandler_t, * which is (void*)(int). */ STATICFNDEF void timer_handler(int why) { int4 cmp; GT_TIMER *tpop, *tpop_prev = NULL; ABS_TIME at; sigset_t savemask; int save_errno, timer_defer_cnt, offset; TID *deferred_tid; boolean_t tid_found; char *save_util_outptr; va_list save_last_va_list_ptr; boolean_t util_copy_saved = FALSE; DCL_THREADGBL_ACCESS; SETUP_THREADGBL_ACCESS; # ifdef DEBUG if (IS_GTM_IMAGE) { tpop = find_timer((TID)heartbeat_timer_ptr, &tpop); assert(process_exiting || (((NULL != tpop) && heartbeat_started) || ((NULL == tpop) && !heartbeat_started))); } # endif if (0 < timer_stack_count) return; timer_stack_count++; deferred_timers_check_needed = FALSE; save_errno = errno; timer_active = FALSE; /* timer has popped; system timer not active anymore */ sys_get_curr_time(&at); tpop = (GT_TIMER *)timeroot; timer_defer_cnt = 0; /* reset the deferred timer count, since we are in timer_handler */ SAVE_UTIL_OUT_BUFFER(save_util_outptr, save_last_va_list_ptr, util_copy_saved); while (tpop) /* fire all handlers that expired */ { cmp = abs_time_comp(&at, (ABS_TIME *)&tpop->expir_time); if (cmp < 0) break; /* A timer might pop while we are in the non-zero intrpt_ok_state zone, which could cause collisions. Instead, * we will defer timer events and drive them once the deferral is removed, unless the timer is safe. */ if ((INTRPT_OK_TO_INTERRUPT == intrpt_ok_state) && (FALSE == process_exiting) || tpop->safe) { if (NULL != tpop_prev) tpop_prev->next = tpop->next; else timeroot = tpop->next; if (tpop->safe) { safe_timer_cnt--; assert(0 <= safe_timer_cnt); } if (NULL != tpop->handler) /* if there is a handler, call it */ { # ifdef DEBUG if (gtm_white_box_test_case_enabled && (WBTEST_DEFERRED_TIMERS == gtm_white_box_test_case_number) && ((void *)tpop->handler != (void*)heartbeat_timer_ptr)) { DBGFPF((stderr, "TIMER_HANDLER: handled a timer\n")); timer_pop_cnt++; } # endif timer_in_handler = TRUE; (*tpop->handler)(tpop->tid, tpop->hd_len, tpop->hd_data); timer_in_handler = FALSE; if (!tpop->safe) /* if safe, avoid a system call */ sys_get_curr_time(&at); /* refresh current time if called a handler */ } tpop->next = (GT_TIMER *)timefree; /* put timer block on the free chain */ timefree = tpop; if (NULL != tpop_prev) tpop = tpop_prev->next; else tpop = (GT_TIMER *)timeroot; num_timers_free++; assert(0 < num_timers_free); } else { timer_defer_cnt++; # ifdef DEBUG if (gtm_white_box_test_case_enabled && (WBTEST_DEFERRED_TIMERS == gtm_white_box_test_case_number)) { if (!deferred_tids) { deferred_tids = (TID *)malloc(SIZEOF(TID) * 2); *deferred_tids = tpop->tid; *(deferred_tids + 1) = -1; DBGFPF((stderr, "TIMER_HANDLER: deferred a timer\n")); } else { tid_found = FALSE; deferred_tid = deferred_tids; while (-1 != *deferred_tid) { if (*deferred_tid == tpop->tid) { tid_found = TRUE; break; } deferred_tid++; } if (!tid_found) { offset = deferred_tid - deferred_tids; deferred_tid = (TID *)malloc((offset + 2) * SIZEOF(TID)); memcpy(deferred_tid, deferred_tids, offset * SIZEOF(TID)); free(deferred_tids); deferred_tids = deferred_tid; *(deferred_tids + offset++) = tpop->tid; *(deferred_tids + offset) = -1; DBGFPF((stderr, "TIMER_HANDLER: deferred a timer\n")); } } } # endif tpop_prev = tpop; tpop = tpop->next; if (0 == safe_timer_cnt) /* no more safe timers left, so quit */ break; } } RESTORE_UTIL_OUT_BUFFER(save_util_outptr, save_last_va_list_ptr, util_copy_saved); if (((FALSE == process_exiting) && (INTRPT_OK_TO_INTERRUPT == intrpt_ok_state)) || (0 < safe_timer_cnt)) start_first_timer(&at); else if ((NULL != timeroot) || (0 < timer_defer_cnt)) deferred_timers_check_needed = TRUE; errno = save_errno; /* restore mainline errno */ timer_stack_count--; }
/* Add timer to timer chain. Allocate a new link for a timer. Convert time to expiration into absolute time. * Insert new link into chain in timer order. * Arguments: tid - timer id * time_to_expir - elapsed time to expiration * handler - pointer to handler routine * hdata_len - length of data to follow * hdata - data to pass to timer rtn if any */ STATICFNDEF void add_timer(ABS_TIME *atp, TID tid, int4 time_to_expir, void (*handler)(), int4 hdata_len, void *hdata) { GT_TIMER *tp, *tpp, *ntp, *lastntp; int4 cmp, i; st_timer_alloc *new_alloc; boolean_t safe_to_add = FALSE; DCL_THREADGBL_ACCESS; SETUP_THREADGBL_ACCESS; /* assert that no timer entry with the same "tid" exists in the timer chain */ assert(NULL == find_timer(tid, &tpp)); /* obtain a new timer block */ ntp = (GT_TIMER *)timefree; lastntp = NULL; for ( ; NULL != ntp; ) { /* we expect all callers of timer functions to not require more than 8 bytes of data; any violations * of this assumption need to be caught---hence the assert below */ assert(GT_TIMER_INIT_DATA_LEN == ntp->hd_len_max); assert(ntp->hd_len_max >= hdata_len); if (ntp->hd_len_max >= hdata_len) /* found one that can hold our data */ { /* dequeue block */ if (NULL == lastntp) /* first one on queue */ timefree = ntp->next; /* dequeue 1st element */ else /* is not 1st on queue -- use simple dequeue */ lastntp->next = ntp->next; assert(0 < num_timers_free); num_timers_free--; break; } lastntp = ntp; /* still looking, try next block */ ntp = ntp->next; } /* if didn't find one, fail if dbg; else malloc a new one */ if (NULL == ntp) { assert(FALSE); /* if dbg, we should have enough already */ ntp = (GT_TIMER *)malloc(timeblk_hdrlen + hdata_len); /* if we are in a timer, malloc may error out */ new_alloc = (st_timer_alloc *)malloc(SIZEOF(st_timer_alloc)); /* insert in front of the list */ new_alloc->addr = ntp; new_alloc->next = (st_timer_alloc *)timer_allocs; timer_allocs = new_alloc; ntp->hd_len_max = hdata_len; } ntp->tid = tid; ntp->handler = handler; ntp->safe = FALSE; if (NULL == handler) { ntp->safe = TRUE; safe_timer_cnt++; assert(0 < safe_timer_cnt); } else { for (i = 0; NULL != safe_handlers[i]; i++) if (safe_handlers[i] == handler) { ntp->safe = TRUE; /* known to just set flags, etc. */ safe_timer_cnt++; break; } } if (ntp->safe || (wcs_clean_dbsync_fptr == handler) || (wcs_stale_fptr == handler)) safe_to_add = TRUE; if ((INTRPT_OK_TO_INTERRUPT != intrpt_ok_state) && !safe_to_add) GTMASSERT; if (process_exiting && !safe_to_add) GTMASSERT; ntp->hd_len = hdata_len; if (0 < hdata_len) memcpy(ntp->hd_data, hdata, hdata_len); add_int_to_abs_time(atp, time_to_expir, &ntp->expir_time); ntp->start_time.at_sec = atp->at_sec; ntp->start_time.at_usec = atp->at_usec; tp = (GT_TIMER *)timeroot; tpp = NULL; while (tp) { cmp = abs_time_comp(&tp->expir_time, &ntp->expir_time); if (cmp >= 0) break; tpp = tp; tp = tp->next; } ntp->next = tp; if (NULL == tpp) timeroot = ntp; else tpp->next = ntp; return; }
bool io_open_try(io_log_name *naml, io_log_name *tl, mval *pp, int4 timeout, mval *mspace) { char buf1[MAX_TRANS_NAME_LEN]; /* buffer to hold translated name */ char dev_type[MAX_DEV_TYPE_LEN]; int n; mstr tn; /* translated name */ uint4 stat; /* status */ int p_offset; unsigned char ch; ABS_TIME cur_time, end_time; bool out_of_time = FALSE; if (0 == naml->iod) { if (0 == tl->iod) { tl->iod = (io_desc *)malloc(SIZEOF(io_desc)); memset((char*)tl->iod, 0, SIZEOF(io_desc)); tl->iod->pair.in = tl->iod; tl->iod->pair.out = tl->iod; tl->iod->trans_name = tl; p_offset = 0; while (iop_eol != *(pp->str.addr + p_offset)) { if ((iop_tmpmbx == (ch = *(pp->str.addr + p_offset++))) || (iop_prmmbx == ch)) tl->iod->type = mb; else if (iop_nl == ch) tl->iod->type = nl; p_offset += ((IOP_VAR_SIZE == io_params_size[ch]) ? (unsigned char)*(pp->str.addr + p_offset) + 1 : io_params_size[ch]); } if (!tl->iod->type && mspace && mspace->str.len) { lower_to_upper(dev_type, mspace->str.addr, mspace->str.len); if (((SIZEOF("SOCKET") - 1) == mspace->str.len) && (0 == memcmp(dev_type, LIT_AND_LEN("SOCKET")))) tl->iod->type = gtmsocket; else tl->iod->type = us; } if (!tl->iod->type) { tn.len = tl->len; tn.addr = &tl->dollar_io; tl->iod->type = io_type(&tn); } } naml->iod = tl->iod; } tl->iod->disp_ptr = &io_dev_dispatch[tl->iod->type]; assert(0 != naml->iod); active_device = naml->iod; if (dev_never_opened == naml->iod->state) { naml->iod->wrap = DEFAULT_IOD_WRAP; naml->iod->width = DEFAULT_IOD_WIDTH; naml->iod->length = DEFAULT_IOD_LENGTH; naml->iod->write_filter = write_filter; } if (dev_open != naml->iod->state) { naml->iod->dollar.x = 0; naml->iod->dollar.y = 0; naml->iod->dollar.za = 0; naml->iod->dollar.zb[0] = 0; naml->iod->dollar.zeof = FALSE; } if (0 == timeout) stat = (naml->iod->disp_ptr->open)(naml, pp, -1, mspace, timeout); /* ZY: add a parameter timeout */ else if (NO_M_TIMEOUT == timeout) { while (FALSE == (stat = (naml->iod->disp_ptr->open)(naml, pp, -1, mspace, timeout))) /* ZY: add timeout */ { hiber_start(1000); /* 1 second */ if (outofband) outofband_action(FALSE); } } else { sys_get_curr_time(&cur_time); add_int_to_abs_time(&cur_time, timeout * 1000, &end_time); while (FALSE == (stat = (naml->iod->disp_ptr->open)(naml, pp, -1, mspace, timeout)) /* ZY: add timeout */ && (!out_of_time)) { hiber_start(1000); /* 1 second */ if (outofband) outofband_action(FALSE); sys_get_curr_time(&cur_time); if (abs_time_comp(&end_time, &cur_time) <= 0) out_of_time = TRUE; } } if (TRUE == stat) { naml->iod->state = dev_open; if (27 == naml->iod->trans_name->dollar_io[0]) { tn.addr = &naml->iod->trans_name->dollar_io[4]; n = naml->iod->trans_name->len - 4; if (n < 0) n = 0; tn.len = n; naml->iod->trans_name = get_log_name(&tn, INSERT); naml->iod->trans_name->iod = naml->iod; } } else { if (dev_open == naml->iod->state && (gtmsocket != naml->iod->type)) naml->iod->state = dev_closed; else if ((gtmsocket == naml->iod->type) && naml->iod->newly_created) { assert(naml->iod->state != dev_open); iosocket_destroy(naml->iod); } } active_device = 0; if ((NO_M_TIMEOUT != timeout) && IS_MCODE_RUNNING) return (stat); return FALSE; }