コード例 #1
0
/*******************************************************************************
*Function:    delay
*Description: delays program execution by a certain number of miliseconds
*Parameters: 
*             DWORD time            Number of miliseconds to pause
*Returns:
*             none
*******************************************************************************/
void delay(unsigned int time) /* exported! */
{ 
#ifndef WIN32
  unsigned long int startTime= GetTickCount();
  while (calcTimeout(startTime) < time);
#else
  Sleep(time);
#endif
}
コード例 #2
0
ファイル: seq_task.c プロジェクト: A2-Collaboration/epics
/*
 * ss_entry() - Thread entry point for all state sets.
 * Provides the main loop for state set processing.
 */
static void ss_entry(void *arg)
{
	SSCB		*ss = (SSCB *)arg;
	SPROG		*sp = ss->sprog;
	USER_VAR	*var;

	if (sp->options & OPT_SAFE)
		var = ss->var;
	else
		var = sp->var;

	/* Attach to PV system; was already done for the first state set */
	if (ss != sp->ss)
	{
		ss->threadId = epicsThreadGetIdSelf();
		pvSysAttach(sp->pvSys);
	}

	/* Register this thread with the EPICS watchdog (no callback func) */
	taskwdInsert(ss->threadId, 0, 0);

	/* In safe mode, update local var buffer with global one before
	   entering the event loop. Must do this using
	   ss_read_all_buffer since CA and other state sets could
	   already post events resp. pvPut. */
	if (sp->options & OPT_SAFE)
		ss_read_all_buffer(sp, ss);

	/* Initial state is the first one */
	ss->currentState = 0;
	ss->nextState = -1;
	ss->prevState = -1;

	DEBUG("ss %s: entering main loop\n", ss->ssName);

	/*
	 * ============= Main loop ==============
	 */
	while (TRUE)
	{
		boolean	ev_trig;
		int	transNum = 0;	/* highest prio trans. # triggered */
		STATE	*st = ss->states + ss->currentState;

		/* Set state to current state */
		assert(ss->currentState >= 0);

		/* Set state set event mask to this state's event mask */
		ss->mask = st->eventMask;

		/* If we've changed state, do any entry actions. Also do these
		 * even if it's the same state if option to do so is enabled.
		 */
		if (st->entryFunc && (ss->prevState != ss->currentState
			|| (st->options & OPT_DOENTRYFROMSELF)))
		{
			st->entryFunc(ss, var);
		}

		/* Flush any outstanding DB requests */
		pvSysFlush(sp->pvSys);

		clearDelays(ss, st); /* Clear delay list */
		st->delayFunc(ss, var); /* Set up new delay list */

		/* Setting this semaphore here guarantees that a when() is
		 * always executed at least once when a state is first
		 * entered.
		 */
		epicsEventSignal(ss->syncSemId);

		/* Loop until an event is triggered, i.e. when() returns TRUE
		 */
		do {
			double delay = 0.0;

			/* Wake up on PV event, event flag, or expired delay */
			if (calcTimeout(ss, &delay))
			{
				DEBUG("before epicsEventWaitWithTimeout(ss=%d,delay=%f)\n",
					ss - sp->ss, delay);
				epicsEventWaitWithTimeout(ss->syncSemId, delay);
				DEBUG("after epicsEventWaitWithTimeout()\n");
			}
			else
			{
				DEBUG("before epicsEventWait\n");
				epicsEventWait(ss->syncSemId);
				DEBUG("after epicsEventWait\n");
			}

			/* Check whether we have been asked to exit */
			if (sp->die) goto exit;

			/* Copy dirty variable values from CA buffer
			 * to user (safe mode only).
			 */
			if (sp->options & OPT_SAFE)
				ss_read_all_buffer(sp, ss);

			/* Check state change conditions */
			ev_trig = st->eventFunc(ss, var,
				&transNum, &ss->nextState);

			/* Clear all event flags (old ef mode only) */
			if (ev_trig && !(sp->options & OPT_NEWEF))
			{
				unsigned i;
				for (i = 0; i < NWORDS(sp->numEvFlags); i++)
				{
					sp->evFlags[i] &= ~ss->mask[i];
				}
			}
		} while (!ev_trig);

		/* Execute the state change action */
		st->actionFunc(ss, var, transNum, &ss->nextState);

		/* Check whether we have been asked to exit */
		if (sp->die) goto exit;

		/* If changing state, do exit actions */
		if (st->exitFunc && (ss->currentState != ss->nextState
			|| (st->options & OPT_DOEXITTOSELF)))
		{
			st->exitFunc(ss, var);
		}

		/* Change to next state */
		ss->prevState = ss->currentState;
		ss->currentState = ss->nextState;
	}

	/* Thread exit has been requested */
exit:
	taskwdRemove(ss->threadId);
	/* Declare ourselves dead */
	if (ss != sp->ss)
		epicsEventSignal(ss->dead);
}