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:
parent
491ef22b63
commit
865cc85dfd
@ -44,6 +44,9 @@
|
||||
* Pre-processor Definitions
|
||||
************************************************************************************/
|
||||
|
||||
#undef USE_CLOCK /* Too slow */
|
||||
#define USE_CLOCK_GETTIME 1 /* Better */
|
||||
|
||||
/* From nuttx/clock.h */
|
||||
|
||||
#define NSEC_PER_SEC 1000000000
|
||||
@ -63,6 +66,10 @@
|
||||
|
||||
typedef int64_t b32_t;
|
||||
|
||||
/************************************************************************************
|
||||
* Private Data
|
||||
************************************************************************************/
|
||||
|
||||
/************************************************************************************
|
||||
* Public Functions
|
||||
************************************************************************************/
|
||||
@ -71,15 +78,25 @@ typedef int64_t b32_t;
|
||||
* Name: up_critmon_gettime
|
||||
************************************************************************************/
|
||||
|
||||
#if defined(USE_CLOCK)
|
||||
uint32_t up_critmon_gettime(void)
|
||||
{
|
||||
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
|
||||
************************************************************************************/
|
||||
|
||||
#if defined(USE_CLOCK)
|
||||
void up_critmon_convert(uint32_t elapsed, struct timespec *ts)
|
||||
{
|
||||
b32_t b32elapsed;
|
||||
@ -88,3 +105,10 @@ void up_critmon_convert(uint32_t elapsed, struct timespec *ts)
|
||||
ts->tv_sec = b32toi(b32elapsed);
|
||||
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
|
||||
|
@ -121,7 +121,7 @@ void sched_critmon_preemption(FAR struct tcb_s *tcb, bool state)
|
||||
|
||||
/* 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 */
|
||||
|
||||
@ -145,12 +145,15 @@ void sched_critmon_preemption(FAR struct tcb_s *tcb, bool state)
|
||||
|
||||
/* Check for the global max elapsed time */
|
||||
|
||||
elapsed = now - g_premp_start[cpu];
|
||||
g_premp_start[cpu] = 0;
|
||||
|
||||
if (elapsed > g_premp_max[cpu])
|
||||
if (g_premp_start[cpu] != 0)
|
||||
{
|
||||
g_premp_max[cpu] = elapsed;
|
||||
elapsed = now - g_premp_start[cpu];
|
||||
g_premp_start[cpu] = 0;
|
||||
|
||||
if (elapsed > g_premp_max[cpu])
|
||||
{
|
||||
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 */
|
||||
|
||||
if (tcb->crit_start != 0)
|
||||
if (tcb->crit_start != 0 && g_crit_start[cpu] == 0)
|
||||
{
|
||||
/* Set the global start time */
|
||||
|
||||
@ -205,12 +208,15 @@ void sched_critmon_csection(FAR struct tcb_s *tcb, bool state)
|
||||
|
||||
/* Check for the global max elapsed time */
|
||||
|
||||
elapsed = now - g_crit_start[cpu];
|
||||
g_crit_start[cpu] = 0;
|
||||
|
||||
if (elapsed > g_crit_max[cpu])
|
||||
if (g_crit_start[cpu] != 0)
|
||||
{
|
||||
g_crit_max[cpu] = elapsed;
|
||||
elapsed = now - g_crit_start[cpu];
|
||||
g_crit_start[cpu] = 0;
|
||||
|
||||
if (elapsed > g_crit_max[cpu])
|
||||
{
|
||||
g_crit_max[cpu] = elapsed;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -243,6 +249,8 @@ void sched_critmon_resume(FAR struct tcb_s *tcb)
|
||||
tcb->premp_start = up_critmon_gettime();
|
||||
DEBUGASSERT(tcb->premp_start != 0);
|
||||
|
||||
/* Zero means that the timer is not ready */
|
||||
|
||||
if (g_premp_start[cpu] == 0)
|
||||
{
|
||||
g_premp_start[cpu] = tcb->premp_start;
|
||||
@ -294,7 +302,7 @@ void sched_critmon_resume(FAR struct tcb_s *tcb)
|
||||
*
|
||||
* Description:
|
||||
* 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:
|
||||
* Called within a critical section.
|
||||
@ -305,7 +313,7 @@ void sched_critmon_suspend(FAR struct tcb_s *tcb)
|
||||
{
|
||||
uint32_t elapsed;
|
||||
|
||||
/* Did this task disable pre-emption? */
|
||||
/* Did this task disable preemption? */
|
||||
|
||||
if (tcb->lockcount > 0)
|
||||
{
|
||||
@ -336,4 +344,4 @@ void sched_critmon_suspend(FAR struct tcb_s *tcb)
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user