コード例 #1
0
ファイル: gtcml_lcktime.c プロジェクト: 5HT/mumps
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);
}
コード例 #2
0
ファイル: gt_timers.c プロジェクト: ztmr/fis-gtm-openindiana
/* 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--;
}
コード例 #3
0
ファイル: gt_timers.c プロジェクト: ztmr/fis-gtm-openindiana
/* 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;
}
コード例 #4
0
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;
}