/**************************************************************************** * 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; }
/**************************************************************************** * 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; }