Example #1
0
/****************************************************************************
 * Function Name: ncs_tmr_wait
 *
 * Purpose: Goto counting semephore and block until tmr_pulse is felt. This
 *          means the actual expiry task no longer services the sysfTmrExpiry
 *          function any more. This should eliminate timer drift.
 *
 ****************************************************************************/
static uint32_t ncs_tmr_wait(void)
{

	unsigned rc;
	int inds_rmvd;

	uint64_t next_delay = 0;

	struct timeval tv = { 0xffffff, 0 };
	struct timespec ts_current = { 0, 0 };
	struct timespec ts;
	struct pollfd set;

	if (clock_gettime(CLOCK_MONOTONIC, &ts_start)) {
		perror("clock_gettime with MONOTONIC Failed \n");
		return NCSCC_RC_FAILURE;
	}

	ts_current = ts_start;

	while (true) {
		set.fd = m_GET_FD_FROM_SEL_OBJ(gl_tcb.sel_obj);
		set.events = POLLIN;
		osaf_timeval_to_timespec(&tv, &ts);
		rc = osaf_ppoll(&set, 1, next_delay != 0 ? &ts : NULL, NULL);
		m_NCS_LOCK(&gl_tcb.safe.enter_lock, NCS_LOCK_WRITE);

		if (rc == 1) {
			if (set.revents != POLLIN) osaf_abort(set.revents);

			/* if select returned because of indication on sel_obj from sysfTmrDestroy */
			if (tmr_destroying == true) {
				/* Raise An indication */
				m_NCS_SEL_OBJ_IND(&tmr_destroy_syn_obj);
				m_NCS_UNLOCK(&gl_tcb.safe.enter_lock, NCS_LOCK_WRITE);
				return NCSCC_RC_SUCCESS;
			}

			gl_tcb.msg_count--;

			if (gl_tcb.msg_count == 0) {
				inds_rmvd = m_NCS_SEL_OBJ_RMV_IND(&gl_tcb.sel_obj, true, true);
				if (inds_rmvd <= 0) {
					if (inds_rmvd != -1) {
						/* The object has not been destroyed and it has no indication
						   raised on it inspite of msg_count being non-zero.
						 */
						m_NCS_UNLOCK(&gl_tcb.safe.enter_lock, NCS_LOCK_WRITE);
						return m_LEAP_DBG_SINK(NCSCC_RC_FAILURE);
					}

					m_NCS_UNLOCK(&gl_tcb.safe.enter_lock, NCS_LOCK_WRITE);

					/* The mbox must have been destroyed */
					return NCSCC_RC_FAILURE;
				}
			}
		}

		rc = ncs_tmr_engine(&tv, &next_delay);
		if (rc == NCSCC_RC_FAILURE) {
			m_NCS_UNLOCK(&gl_tcb.safe.enter_lock, NCS_LOCK_WRITE);
			return NCSCC_RC_FAILURE;
		}

		m_NCS_UNLOCK(&gl_tcb.safe.enter_lock, NCS_LOCK_WRITE);
		ts_current.tv_sec = ts_current.tv_nsec = 0;

		if (clock_gettime(CLOCK_MONOTONIC, &ts_current)) {
			perror("clock_gettime with MONOTONIC Failed \n");
			return NCSCC_RC_FAILURE;
		}
	}

	return NCSCC_RC_SUCCESS;
}
Example #2
0
/****************************************************************************
 * Function Name: ncs_tmr_wait
 *
 * Purpose: Goto counting semephore and block until tmr_pulse is felt. This
 *          means the actual expiry task no longer services the sysfTmrExpiry
 *          function any more. This should eliminate timer drift.
 *
 ****************************************************************************/
static uns32 ncs_tmr_wait(void)
{

	int rc = 0;
	int inds_rmvd;
	int save_errno = 0;

	uns64 next_delay = 0;

	NCS_SEL_OBJ mbx_fd = gl_tcb.sel_obj;
	NCS_SEL_OBJ highest_sel_obj;
	NCS_SEL_OBJ_SET all_sel_obj;
	struct timeval tv = { 0xffffff, 0 };
	struct timespec ts_current = { 0, 0 };

	m_NCS_SEL_OBJ_ZERO(&all_sel_obj);
	highest_sel_obj = mbx_fd;

	if (clock_gettime(CLOCK_MONOTONIC, &ts_start)) {
		perror("clock_gettime with MONOTONIC Failed \n");
		return NCSCC_RC_FAILURE;
	}

	ts_current = ts_start;

	while (TRUE) {
 select_sleep:
		m_NCS_SEL_OBJ_SET(mbx_fd, &all_sel_obj);
		rc = select(highest_sel_obj.rmv_obj + 1, &all_sel_obj, NULL, NULL, &tv);
		save_errno = errno;
		m_NCS_LOCK(&gl_tcb.safe.enter_lock, NCS_LOCK_WRITE);

		if (rc < 0) {
			if (save_errno != EINTR)
				assert(0);

			if (ncs_tmr_select_intr_process(&tv, &ts_current, next_delay) == NCSCC_RC_SUCCESS) {
				m_NCS_UNLOCK(&gl_tcb.safe.enter_lock, NCS_LOCK_WRITE);
				goto select_sleep;
			} else {
				m_NCS_UNLOCK(&gl_tcb.safe.enter_lock, NCS_LOCK_WRITE);
				return NCSCC_RC_FAILURE;
			}
		} else if (rc == 1) {
			/* if select returned because of indication on sel_obj from sysfTmrDestroy */
			if (tmr_destroying == TRUE) {
				/* Raise An indication */
				m_NCS_SEL_OBJ_IND(tmr_destroy_syn_obj);
				m_NCS_UNLOCK(&gl_tcb.safe.enter_lock, NCS_LOCK_WRITE);
				return NCSCC_RC_SUCCESS;
			}

			gl_tcb.msg_count--;

			if (gl_tcb.msg_count == 0) {
				inds_rmvd = m_NCS_SEL_OBJ_RMV_IND(gl_tcb.sel_obj, TRUE, TRUE);
				if (inds_rmvd <= 0) {
					if (inds_rmvd != -1) {
						/* The object has not been destroyed and it has no indication
						   raised on it inspite of msg_count being non-zero.
						 */
						m_NCS_UNLOCK(&gl_tcb.safe.enter_lock, NCS_LOCK_WRITE);
						return m_LEAP_DBG_SINK(NCSCC_RC_FAILURE);
					}

					m_NCS_UNLOCK(&gl_tcb.safe.enter_lock, NCS_LOCK_WRITE);

					/* The mbox must have been destroyed */
					return NCSCC_RC_FAILURE;
				}
			}
		}

		rc = ncs_tmr_engine(&tv, &next_delay);
		if (rc == NCSCC_RC_FAILURE) {
			m_NCS_UNLOCK(&gl_tcb.safe.enter_lock, NCS_LOCK_WRITE);
			return NCSCC_RC_FAILURE;
		}

		m_NCS_UNLOCK(&gl_tcb.safe.enter_lock, NCS_LOCK_WRITE);
		ts_current.tv_sec = ts_current.tv_nsec = 0;

		if (clock_gettime(CLOCK_MONOTONIC, &ts_current)) {
			perror("clock_gettime with MONOTONIC Failed \n");
			return NCSCC_RC_FAILURE;
		}
	}

	return NCSCC_RC_SUCCESS;
}