sched/sched/sched_critmonitor.c: A correct a logic error. arch/sim/src/up_critmon.c: Use higher resolution timer.

This commit is contained in:
Gregory Nutt 2018-11-25 09:49:21 -06:00
parent 491ef22b63
commit 865cc85dfd
2 changed files with 47 additions and 15 deletions

View File

@ -44,6 +44,9 @@
* Pre-processor Definitions * Pre-processor Definitions
************************************************************************************/ ************************************************************************************/
#undef USE_CLOCK /* Too slow */
#define USE_CLOCK_GETTIME 1 /* Better */
/* From nuttx/clock.h */ /* From nuttx/clock.h */
#define NSEC_PER_SEC 1000000000 #define NSEC_PER_SEC 1000000000
@ -63,6 +66,10 @@
typedef int64_t b32_t; typedef int64_t b32_t;
/************************************************************************************
* Private Data
************************************************************************************/
/************************************************************************************ /************************************************************************************
* Public Functions * Public Functions
************************************************************************************/ ************************************************************************************/
@ -71,15 +78,25 @@ typedef int64_t b32_t;
* Name: up_critmon_gettime * Name: up_critmon_gettime
************************************************************************************/ ************************************************************************************/
#if defined(USE_CLOCK)
uint32_t up_critmon_gettime(void) uint32_t up_critmon_gettime(void)
{ {
return (uint32_t)clock() + 1; /* Avoid returning zero which means clock-not-ready */ return (uint32_t)clock() + 1; /* Avoid returning zero which means clock-not-ready */
} }
#else /* USE_CLOCK_GETTIME */
uint32_t up_critmon_gettime(void)
{
struct timespec ts;
(void)clock_gettime(CLOCK_MONOTONIC, &ts);
return (uint32_t)ts.tv_nsec;
}
#endif
/************************************************************************************ /************************************************************************************
* Name: up_critmon_gettime * Name: up_critmon_gettime
************************************************************************************/ ************************************************************************************/
#if defined(USE_CLOCK)
void up_critmon_convert(uint32_t elapsed, struct timespec *ts) void up_critmon_convert(uint32_t elapsed, struct timespec *ts)
{ {
b32_t b32elapsed; b32_t b32elapsed;
@ -88,3 +105,10 @@ void up_critmon_convert(uint32_t elapsed, struct timespec *ts)
ts->tv_sec = b32toi(b32elapsed); ts->tv_sec = b32toi(b32elapsed);
ts->tv_nsec = NSEC_PER_SEC * b32frac(b32elapsed) / b32ONE; ts->tv_nsec = NSEC_PER_SEC * b32frac(b32elapsed) / b32ONE;
} }
#else /* USE_CLOCK_GETTIME */
void up_critmon_convert(uint32_t elapsed, struct timespec *ts)
{
ts->tv_sec = 0;
ts->tv_nsec = elapsed;
}
#endif

View File

@ -121,7 +121,7 @@ void sched_critmon_preemption(FAR struct tcb_s *tcb, bool state)
/* Zero means that the timer is not ready */ /* Zero means that the timer is not ready */
if (tcb->premp_start != 0) if (tcb->premp_start != 0 && g_premp_start[cpu] == 0)
{ {
/* Save the global start time */ /* Save the global start time */
@ -145,6 +145,8 @@ void sched_critmon_preemption(FAR struct tcb_s *tcb, bool state)
/* Check for the global max elapsed time */ /* Check for the global max elapsed time */
if (g_premp_start[cpu] != 0)
{
elapsed = now - g_premp_start[cpu]; elapsed = now - g_premp_start[cpu];
g_premp_start[cpu] = 0; g_premp_start[cpu] = 0;
@ -153,6 +155,7 @@ void sched_critmon_preemption(FAR struct tcb_s *tcb, bool state)
g_premp_max[cpu] = elapsed; g_premp_max[cpu] = elapsed;
} }
} }
}
} }
/**************************************************************************** /****************************************************************************
@ -181,7 +184,7 @@ void sched_critmon_csection(FAR struct tcb_s *tcb, bool state)
/* Zero means that the timer is not ready */ /* Zero means that the timer is not ready */
if (tcb->crit_start != 0) if (tcb->crit_start != 0 && g_crit_start[cpu] == 0)
{ {
/* Set the global start time */ /* Set the global start time */
@ -205,6 +208,8 @@ void sched_critmon_csection(FAR struct tcb_s *tcb, bool state)
/* Check for the global max elapsed time */ /* Check for the global max elapsed time */
if (g_crit_start[cpu] != 0)
{
elapsed = now - g_crit_start[cpu]; elapsed = now - g_crit_start[cpu];
g_crit_start[cpu] = 0; g_crit_start[cpu] = 0;
@ -213,6 +218,7 @@ void sched_critmon_csection(FAR struct tcb_s *tcb, bool state)
g_crit_max[cpu] = elapsed; g_crit_max[cpu] = elapsed;
} }
} }
}
} }
/**************************************************************************** /****************************************************************************
@ -243,6 +249,8 @@ void sched_critmon_resume(FAR struct tcb_s *tcb)
tcb->premp_start = up_critmon_gettime(); tcb->premp_start = up_critmon_gettime();
DEBUGASSERT(tcb->premp_start != 0); DEBUGASSERT(tcb->premp_start != 0);
/* Zero means that the timer is not ready */
if (g_premp_start[cpu] == 0) if (g_premp_start[cpu] == 0)
{ {
g_premp_start[cpu] = tcb->premp_start; g_premp_start[cpu] = tcb->premp_start;
@ -294,7 +302,7 @@ void sched_critmon_resume(FAR struct tcb_s *tcb)
* *
* Description: * Description:
* Called when a thread suspends execution, perhaps terminating a * Called when a thread suspends execution, perhaps terminating a
* critical section or a non-pre-emptible state. * critical section or a non-preemptible state.
* *
* Assumptions: * Assumptions:
* Called within a critical section. * Called within a critical section.
@ -305,7 +313,7 @@ void sched_critmon_suspend(FAR struct tcb_s *tcb)
{ {
uint32_t elapsed; uint32_t elapsed;
/* Did this task disable pre-emption? */ /* Did this task disable preemption? */
if (tcb->lockcount > 0) if (tcb->lockcount > 0)
{ {