Critical Section Monitor: Add low level timer support for simulation. Fix serial bugs and logic errors in initial implementation. Still does not work; takes assertions.

This commit is contained in:
Gregory Nutt 2018-11-24 15:07:12 -06:00
parent 85c31fd4a2
commit 807d5bb4ae
7 changed files with 42 additions and 16 deletions

View File

@ -1,7 +1,8 @@
############################################################################ ############################################################################
# arch/sim/src/Makefile # arch/sim/src/Makefile
# #
# Copyright (C) 2007, 2008, 2011-2012, 2014, 2016 Gregory Nutt. All rights reserved. # Copyright (C) 2007, 2008, 2011-2012, 2014, 2016, 2018 Gregory Nutt. All
# rights reserved.
# Author: Gregory Nutt <gnutt@nuttx.org> # Author: Gregory Nutt <gnutt@nuttx.org>
# #
# Redistribution and use in source and binary forms, with or without # Redistribution and use in source and binary forms, with or without
@ -91,6 +92,10 @@ ifeq ($(CONFIG_ONESHOT),y)
CSRCS += up_oneshot.c CSRCS += up_oneshot.c
endif endif
ifeq ($(CONFIG_SCHED_CRITMONITOR),y)
HOSTSRCS += up_critmon.c
endif
ifeq ($(CONFIG_NX_LCDDRIVER),y) ifeq ($(CONFIG_NX_LCDDRIVER),y)
CSRCS += board_lcd.c CSRCS += board_lcd.c
else else

View File

@ -6,6 +6,7 @@ basename NXbasename
calloc NXcalloc calloc NXcalloc
chdir NXchdir chdir NXchdir
clearenv NXclearenv clearenv NXclearenv
clock NXclock
clock_gettime NXclock_gettime clock_gettime NXclock_gettime
close NXclose close NXclose
closedir NXclosedir closedir NXclosedir

View File

@ -305,18 +305,23 @@ static ssize_t critmon_read(FAR struct file *filep, FAR char *buffer,
DEBUGASSERT(attr); DEBUGASSERT(attr);
ret = 0; ret = 0;
offset = filep->f_pos;
#ifdef CONFIG_SMP #ifdef CONFIG_SMP
/* Get the status for each CPU */ /* Get the status for each CPU */
for (cpu = 0; cpu < CONFIG_SMP_NCPUS; cpu++) for (cpu = 0; cpu < CONFIG_SMP_NCPUS; cpu++)
{ {
ret += critmon_read_cpu(attr, buffer + ret, buflen -ret, ssize_t nbytes = critmon_read_cpu(attr, buffer + ret, buflen - ret,
&offset, cpu); &offset, cpu);
ret += nbytes;
if (ret > buflen) if (ret > buflen)
{ {
break; break;
} }
offset += nbytes;
} }
#else #else

View File

@ -637,7 +637,8 @@ struct tcb_s
#endif #endif
uint16_t flags; /* Misc. general status flags */ uint16_t flags; /* Misc. general status flags */
int16_t lockcount; /* 0=preemptable (not-locked) */ int16_t lockcount; /* 0=preemptable (not-locked) */
#ifdef CONFIG_SMP #if defined(CONFIG_SMP) || defined(CONFIG_SCHED_CRITMONITOR) || \
defined(CONFIG_SCHED_INSTRUMENTATION_CSECTION)
int16_t irqcount; /* 0=Not in critical section */ int16_t irqcount; /* 0=Not in critical section */
#endif #endif
#ifdef CONFIG_CANCELLATION_POINTS #ifdef CONFIG_CANCELLATION_POINTS

View File

@ -411,7 +411,14 @@ irqstate_t enter_critical_section(void)
FAR struct tcb_s *rtcb = this_task(); FAR struct tcb_s *rtcb = this_task();
DEBUGASSERT(rtcb != NULL); DEBUGASSERT(rtcb != NULL);
/* Yes.. Note that we have entered the critical section */ /* Have we just entered the critical section? Or is this a nested
* call to enter_critical_section.
*/
DEBUGASSERT(rtcb->irqcount >= 0 && rtcb->irqcount < UINT16_MAX);
if (++rtcb->irqcount == 1)
{
/* Note that we have entered the critical section */
#ifdef CONFIG_SCHED_CRITMONITOR #ifdef CONFIG_SCHED_CRITMONITOR
sched_critmon_csection(rtcb, true); sched_critmon_csection(rtcb, true);
@ -420,6 +427,7 @@ irqstate_t enter_critical_section(void)
sched_note_csection(rtcb, true); sched_note_csection(rtcb, true);
#endif #endif
} }
}
/* Return interrupt status */ /* Return interrupt status */
@ -591,7 +599,12 @@ void leave_critical_section(irqstate_t flags)
FAR struct tcb_s *rtcb = this_task(); FAR struct tcb_s *rtcb = this_task();
DEBUGASSERT(rtcb != NULL); DEBUGASSERT(rtcb != NULL);
/* Yes.. Note that we have left the critical section */ /* Have we left entered the critical section? Or are we still nested. */
DEBUGASSERT(rtcb->irqcount > 0);
if (--rtcb->irqcount <= 0)
{
/* Note that we have left the critical section */
#ifdef CONFIG_SCHED_CRITMONITOR #ifdef CONFIG_SCHED_CRITMONITOR
sched_critmon_csection(rtcb, false); sched_critmon_csection(rtcb, false);
@ -600,6 +613,7 @@ void leave_critical_section(irqstate_t flags)
sched_note_csection(rtcb, false); sched_note_csection(rtcb, false);
#endif #endif
} }
}
/* Restore the previous interrupt state. */ /* Restore the previous interrupt state. */

View File

@ -52,11 +52,11 @@
#define CRITMON_PREEMPT (1 << 0) /* Bit 0: Pre-emption is disabled */ #define CRITMON_PREEMPT (1 << 0) /* Bit 0: Pre-emption is disabled */
#define CRITMON_CSECTION (1 << 1) /* Bit 1: In a critical section */ #define CRITMON_CSECTION (1 << 1) /* Bit 1: In a critical section */
#define DISABLE_PREEMPT(t) do { (t)->flags |= CRITMON_PREEMPT; } while (0) #define DISABLE_PREEMPT(t) do { (t)->crit_flags |= CRITMON_PREEMPT; } while (0)
#define ENTER_CSECTION(t) do { (t)->flags |= CRITMON_PREEMPT; } while (0) #define ENTER_CSECTION(t) do { (t)->crit_flags |= CRITMON_CSECTION; } while (0)
#define ENABLE_PREEMPT(t) do { (t)->flags &= ~CRITMON_PREEMPT; } while (0) #define ENABLE_PREEMPT(t) do { (t)->crit_flags &= ~CRITMON_PREEMPT; } while (0)
#define LEAVE_CSECTION(t) do { (t)->flags &= ~CRITMON_PREEMPT; } while (0) #define LEAVE_CSECTION(t) do { (t)->crit_flags &= ~CRITMON_CSECTION; } while (0)
#define PREEMPT_ISDISABLED(t) (((t)->crit_flags & CRITMON_PREEMPT) != 0) #define PREEMPT_ISDISABLED(t) (((t)->crit_flags & CRITMON_PREEMPT) != 0)
#define IN_CSECTION(t) (((t)->crit_flags & CRITMON_CSECTION) != 0) #define IN_CSECTION(t) (((t)->crit_flags & CRITMON_CSECTION) != 0)

View File

@ -77,7 +77,7 @@
int nxsig_notification(pid_t pid, FAR struct sigevent *event, int code) int nxsig_notification(pid_t pid, FAR struct sigevent *event, int code)
{ {
sinfo("pid=%p signo=%d code=%d sival_ptr=%p\n", sinfo("pid=%p signo=%d code=%d sival_ptr=%p\n",
pid, event->sigev_signo, code, event->value.sival_ptr); pid, event->sigev_signo, code, event->sigev_value.sival_ptr);
/* Notify client via a signal? */ /* Notify client via a signal? */