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
|
* 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
|
||||||
|
@ -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)
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user