From 807d5bb4aebdd0b6ba0ebf9c2eca057c70533b7a Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Sat, 24 Nov 2018 15:07:12 -0600 Subject: [PATCH] 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. --- arch/sim/src/Makefile | 7 ++++++- arch/sim/src/nuttx-names.dat | 1 + fs/procfs/fs_procfscritmon.c | 11 ++++++++--- include/nuttx/sched.h | 3 ++- sched/irq/irq_csection.c | 26 ++++++++++++++++++++------ sched/sched/sched_critmonitor.c | 8 ++++---- sched/signal/sig_notification.c | 2 +- 7 files changed, 42 insertions(+), 16 deletions(-) diff --git a/arch/sim/src/Makefile b/arch/sim/src/Makefile index 051085a829..7b9bf4b877 100644 --- a/arch/sim/src/Makefile +++ b/arch/sim/src/Makefile @@ -1,7 +1,8 @@ ############################################################################ # 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 # # Redistribution and use in source and binary forms, with or without @@ -91,6 +92,10 @@ ifeq ($(CONFIG_ONESHOT),y) CSRCS += up_oneshot.c endif +ifeq ($(CONFIG_SCHED_CRITMONITOR),y) + HOSTSRCS += up_critmon.c +endif + ifeq ($(CONFIG_NX_LCDDRIVER),y) CSRCS += board_lcd.c else diff --git a/arch/sim/src/nuttx-names.dat b/arch/sim/src/nuttx-names.dat index d7e76bb904..b063c2a279 100644 --- a/arch/sim/src/nuttx-names.dat +++ b/arch/sim/src/nuttx-names.dat @@ -6,6 +6,7 @@ basename NXbasename calloc NXcalloc chdir NXchdir clearenv NXclearenv +clock NXclock clock_gettime NXclock_gettime close NXclose closedir NXclosedir diff --git a/fs/procfs/fs_procfscritmon.c b/fs/procfs/fs_procfscritmon.c index 45c784d299..8518dc1ac8 100644 --- a/fs/procfs/fs_procfscritmon.c +++ b/fs/procfs/fs_procfscritmon.c @@ -304,19 +304,24 @@ static ssize_t critmon_read(FAR struct file *filep, FAR char *buffer, attr = (FAR struct critmon_file_s *)filep->f_priv; DEBUGASSERT(attr); - ret = 0; + ret = 0; + offset = filep->f_pos; #ifdef CONFIG_SMP /* Get the status for each CPU */ for (cpu = 0; cpu < CONFIG_SMP_NCPUS; cpu++) { - ret += critmon_read_cpu(attr, buffer + ret, buflen -ret, - &offset, cpu); + ssize_t nbytes = critmon_read_cpu(attr, buffer + ret, buflen - ret, + &offset, cpu); + + ret += nbytes; if (ret > buflen) { break; } + + offset += nbytes; } #else diff --git a/include/nuttx/sched.h b/include/nuttx/sched.h index 0ffc612bad..00aafcb655 100644 --- a/include/nuttx/sched.h +++ b/include/nuttx/sched.h @@ -637,7 +637,8 @@ struct tcb_s #endif uint16_t flags; /* Misc. general status flags */ 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 */ #endif #ifdef CONFIG_CANCELLATION_POINTS diff --git a/sched/irq/irq_csection.c b/sched/irq/irq_csection.c index 4df37aeee5..45577aefdc 100644 --- a/sched/irq/irq_csection.c +++ b/sched/irq/irq_csection.c @@ -411,14 +411,22 @@ irqstate_t enter_critical_section(void) FAR struct tcb_s *rtcb = this_task(); 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 - sched_critmon_csection(rtcb, true); + sched_critmon_csection(rtcb, true); #endif #ifdef CONFIG_SCHED_INSTRUMENTATION_CSECTION - sched_note_csection(rtcb, true); + sched_note_csection(rtcb, true); #endif + } } /* Return interrupt status */ @@ -591,14 +599,20 @@ void leave_critical_section(irqstate_t flags) FAR struct tcb_s *rtcb = this_task(); 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 - sched_critmon_csection(rtcb, false); + sched_critmon_csection(rtcb, false); #endif #ifdef CONFIG_SCHED_INSTRUMENTATION_CSECTION - sched_note_csection(rtcb, false); + sched_note_csection(rtcb, false); #endif + } } /* Restore the previous interrupt state. */ diff --git a/sched/sched/sched_critmonitor.c b/sched/sched/sched_critmonitor.c index 95dace5835..674c055ac0 100644 --- a/sched/sched/sched_critmonitor.c +++ b/sched/sched/sched_critmonitor.c @@ -52,11 +52,11 @@ #define CRITMON_PREEMPT (1 << 0) /* Bit 0: Pre-emption is disabled */ #define CRITMON_CSECTION (1 << 1) /* Bit 1: In a critical section */ -#define DISABLE_PREEMPT(t) do { (t)->flags |= CRITMON_PREEMPT; } while (0) -#define ENTER_CSECTION(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)->crit_flags |= CRITMON_CSECTION; } while (0) -#define ENABLE_PREEMPT(t) do { (t)->flags &= ~CRITMON_PREEMPT; } while (0) -#define LEAVE_CSECTION(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)->crit_flags &= ~CRITMON_CSECTION; } while (0) #define PREEMPT_ISDISABLED(t) (((t)->crit_flags & CRITMON_PREEMPT) != 0) #define IN_CSECTION(t) (((t)->crit_flags & CRITMON_CSECTION) != 0) diff --git a/sched/signal/sig_notification.c b/sched/signal/sig_notification.c index 088ed97a9a..0634e93a3e 100644 --- a/sched/signal/sig_notification.c +++ b/sched/signal/sig_notification.c @@ -77,7 +77,7 @@ int nxsig_notification(pid_t pid, FAR struct sigevent *event, int code) { 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? */