mirror of
https://github.com/apache/nuttx.git
synced 2026-06-06 08:36:24 +08:00
sched_note: Extend OS instrumentation to include some SMP events.
This commit is contained in:
@@ -44,6 +44,7 @@
|
|||||||
#include <nuttx/arch.h>
|
#include <nuttx/arch.h>
|
||||||
#include <nuttx/sched.h>
|
#include <nuttx/sched.h>
|
||||||
#include <nuttx/spinlock.h>
|
#include <nuttx/spinlock.h>
|
||||||
|
#include <nuttx/sched_note.h>
|
||||||
|
|
||||||
#include "up_internal.h"
|
#include "up_internal.h"
|
||||||
#include "gic.h"
|
#include "gic.h"
|
||||||
@@ -131,6 +132,12 @@ int up_cpu_paused(int cpu)
|
|||||||
|
|
||||||
sched_suspend_scheduler(tcb);
|
sched_suspend_scheduler(tcb);
|
||||||
|
|
||||||
|
#ifdef CONFIG_SCHED_INSTRUMENTATION
|
||||||
|
/* Notify that we are paused */
|
||||||
|
|
||||||
|
sched_note_cpu_paused(tcb);
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Save the current context at CURRENT_REGS into the TCB at the head
|
/* Save the current context at CURRENT_REGS into the TCB at the head
|
||||||
* of the assigned task list for this CPU.
|
* of the assigned task list for this CPU.
|
||||||
*/
|
*/
|
||||||
@@ -148,6 +155,12 @@ int up_cpu_paused(int cpu)
|
|||||||
|
|
||||||
tcb = this_task();
|
tcb = this_task();
|
||||||
|
|
||||||
|
#ifdef CONFIG_SCHED_INSTRUMENTATION
|
||||||
|
/* Notify that we have resumed */
|
||||||
|
|
||||||
|
sched_note_cpu_resumed(tcb);
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Reset scheduler parameters */
|
/* Reset scheduler parameters */
|
||||||
|
|
||||||
sched_resume_scheduler(tcb);
|
sched_resume_scheduler(tcb);
|
||||||
@@ -224,6 +237,12 @@ int up_cpu_pause(int cpu)
|
|||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
#ifdef CONFIG_SCHED_INSTRUMENTATION
|
||||||
|
/* Notify of the pause event */
|
||||||
|
|
||||||
|
sched_note_cpu_pause(this_task(), cpu);
|
||||||
|
#endif
|
||||||
|
|
||||||
DEBUGASSERT(cpu >= 0 && cpu < CONFIG_SMP_NCPUS && cpu != this_cpu());
|
DEBUGASSERT(cpu >= 0 && cpu < CONFIG_SMP_NCPUS && cpu != this_cpu());
|
||||||
|
|
||||||
/* Take the both spinlocks. The g_cpu_wait spinlock will prevent the SGI2
|
/* Take the both spinlocks. The g_cpu_wait spinlock will prevent the SGI2
|
||||||
@@ -287,6 +306,12 @@ int up_cpu_pause(int cpu)
|
|||||||
|
|
||||||
int up_cpu_resume(int cpu)
|
int up_cpu_resume(int cpu)
|
||||||
{
|
{
|
||||||
|
#ifdef CONFIG_SCHED_INSTRUMENTATION
|
||||||
|
/* Notify of the resume event */
|
||||||
|
|
||||||
|
sched_note_cpu_resume(this_task(), cpu);
|
||||||
|
#endif
|
||||||
|
|
||||||
DEBUGASSERT(cpu >= 0 && cpu < CONFIG_SMP_NCPUS && cpu != this_cpu());
|
DEBUGASSERT(cpu >= 0 && cpu < CONFIG_SMP_NCPUS && cpu != this_cpu());
|
||||||
|
|
||||||
/* Release the spinlock. Releasing the spinlock will cause the SGI2
|
/* Release the spinlock. Releasing the spinlock will cause the SGI2
|
||||||
|
|||||||
@@ -105,9 +105,8 @@ static inline void arm_registerdump(FAR struct tcb_s *tcb)
|
|||||||
int arm_start_handler(int irq, FAR void *context)
|
int arm_start_handler(int irq, FAR void *context)
|
||||||
{
|
{
|
||||||
FAR struct tcb_s *tcb;
|
FAR struct tcb_s *tcb;
|
||||||
int cpu = up_cpu_index();
|
|
||||||
|
|
||||||
sinfo("CPU%d Started\n", cpu);
|
sinfo("CPU%d Started\n", this_cpu());
|
||||||
|
|
||||||
/* Reset scheduler parameters */
|
/* Reset scheduler parameters */
|
||||||
|
|
||||||
|
|||||||
@@ -44,6 +44,7 @@
|
|||||||
#include <nuttx/arch.h>
|
#include <nuttx/arch.h>
|
||||||
#include <nuttx/sched.h>
|
#include <nuttx/sched.h>
|
||||||
#include <nuttx/spinlock.h>
|
#include <nuttx/spinlock.h>
|
||||||
|
#include <nuttx/sched_note.h>
|
||||||
|
|
||||||
#include "xtensa.h"
|
#include "xtensa.h"
|
||||||
#include "sched/sched.h"
|
#include "sched/sched.h"
|
||||||
@@ -117,6 +118,12 @@ int up_cpu_paused(int cpu)
|
|||||||
|
|
||||||
sched_suspend_scheduler(otcb);
|
sched_suspend_scheduler(otcb);
|
||||||
|
|
||||||
|
#ifdef CONFIG_SCHED_INSTRUMENTATION
|
||||||
|
/* Notify that we are paused */
|
||||||
|
|
||||||
|
sched_note_cpu_paused(otcb);
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Copy the CURRENT_REGS into the OLD TCB (otcb). The co-processor state
|
/* Copy the CURRENT_REGS into the OLD TCB (otcb). The co-processor state
|
||||||
* will be saved as part of the return from xtensa_irq_dispatch().
|
* will be saved as part of the return from xtensa_irq_dispatch().
|
||||||
*/
|
*/
|
||||||
@@ -134,6 +141,12 @@ int up_cpu_paused(int cpu)
|
|||||||
|
|
||||||
ntcb = this_task();
|
ntcb = this_task();
|
||||||
|
|
||||||
|
#ifdef CONFIG_SCHED_INSTRUMENTATION
|
||||||
|
/* Notify that we have resumed */
|
||||||
|
|
||||||
|
sched_note_cpu_resumed(ntcb);
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Reset scheduler parameters */
|
/* Reset scheduler parameters */
|
||||||
|
|
||||||
sched_resume_scheduler(ntcb);
|
sched_resume_scheduler(ntcb);
|
||||||
@@ -203,6 +216,12 @@ int up_cpu_pause(int cpu)
|
|||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
#ifdef CONFIG_SCHED_INSTRUMENTATION
|
||||||
|
/* Notify of the pause event */
|
||||||
|
|
||||||
|
sched_note_cpu_pause(this_task(), cpu);
|
||||||
|
#endif
|
||||||
|
|
||||||
DEBUGASSERT(cpu >= 0 && cpu < CONFIG_SMP_NCPUS && cpu != this_cpu());
|
DEBUGASSERT(cpu >= 0 && cpu < CONFIG_SMP_NCPUS && cpu != this_cpu());
|
||||||
|
|
||||||
/* Take the both spinlocks. The g_cpu_wait spinlock will prevent the SGI2
|
/* Take the both spinlocks. The g_cpu_wait spinlock will prevent the SGI2
|
||||||
@@ -266,6 +285,12 @@ int up_cpu_pause(int cpu)
|
|||||||
|
|
||||||
int up_cpu_resume(int cpu)
|
int up_cpu_resume(int cpu)
|
||||||
{
|
{
|
||||||
|
#ifdef CONFIG_SCHED_INSTRUMENTATION
|
||||||
|
/* Notify of the resume event */
|
||||||
|
|
||||||
|
sched_note_cpu_resume(this_task(), cpu);
|
||||||
|
#endif
|
||||||
|
|
||||||
DEBUGASSERT(cpu >= 0 && cpu < CONFIG_SMP_NCPUS && cpu != this_cpu());
|
DEBUGASSERT(cpu >= 0 && cpu < CONFIG_SMP_NCPUS && cpu != this_cpu());
|
||||||
|
|
||||||
/* Release the spinlock. Releasing the spinlock will cause the SGI2
|
/* Release the spinlock. Releasing the spinlock will cause the SGI2
|
||||||
|
|||||||
@@ -73,7 +73,7 @@ config DRIVER_NOTE
|
|||||||
depends on SCHED_INSTRUMENTATION_BUFFER
|
depends on SCHED_INSTRUMENTATION_BUFFER
|
||||||
---help---
|
---help---
|
||||||
Enable building a serial driver that can be used by an application
|
Enable building a serial driver that can be used by an application
|
||||||
to read data from the in-memory, scheduler instrumentatin "note"
|
to read data from the in-memory, scheduler instrumentation "note"
|
||||||
buffer.
|
buffer.
|
||||||
|
|
||||||
config SYSLOG_INTBUFFER
|
config SYSLOG_INTBUFFER
|
||||||
|
|||||||
@@ -64,6 +64,13 @@ enum note_type_e
|
|||||||
NOTE_STOP,
|
NOTE_STOP,
|
||||||
NOTE_SUSPEND,
|
NOTE_SUSPEND,
|
||||||
NOTE_RESUME
|
NOTE_RESUME
|
||||||
|
#ifdef CONFIG_SMP
|
||||||
|
,
|
||||||
|
NOTE_CPU_PAUSE,
|
||||||
|
NOTE_CPU_PAUSED,
|
||||||
|
NOTE_CPU_RESUME,
|
||||||
|
NOTE_CPU_RESUMED
|
||||||
|
#endif
|
||||||
#ifdef CONFIG_SCHED_INSTRUMENTATION_PREEMPTION
|
#ifdef CONFIG_SCHED_INSTRUMENTATION_PREEMPTION
|
||||||
,
|
,
|
||||||
NOTE_PREEMPT_LOCK,
|
NOTE_PREEMPT_LOCK,
|
||||||
@@ -122,6 +129,38 @@ struct note_resume_s
|
|||||||
struct note_common_s nre_cmn; /* Common note parameters */
|
struct note_common_s nre_cmn; /* Common note parameters */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#ifdef CONFIG_SMP
|
||||||
|
/* This is the specific form of the NOTE_CPU_PAUSE note */
|
||||||
|
|
||||||
|
struct note_cpu_pause_s
|
||||||
|
{
|
||||||
|
struct note_common_s ncp_cmn; /* Common note parameters */
|
||||||
|
uint8_t ncp_target; /* CPU being paused */
|
||||||
|
};
|
||||||
|
|
||||||
|
/* This is the specific form of the NOTE_CPU_PAUSED note */
|
||||||
|
|
||||||
|
struct note_cpu_paused_s
|
||||||
|
{
|
||||||
|
struct note_common_s ncp_cmn; /* Common note parameters */
|
||||||
|
};
|
||||||
|
|
||||||
|
/* This is the specific form of the NOTE_CPU_RESUME note */
|
||||||
|
|
||||||
|
struct note_cpu_resume_s
|
||||||
|
{
|
||||||
|
struct note_common_s ncr_cmn; /* Common note parameters */
|
||||||
|
uint8_t ncr_target; /* CPU being resumed */
|
||||||
|
};
|
||||||
|
|
||||||
|
/* This is the specific form of the NOTE_CPU_RESUMED note */
|
||||||
|
|
||||||
|
struct note_cpu_resumed_s
|
||||||
|
{
|
||||||
|
struct note_common_s ncr_cmn; /* Common note parameters */
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef CONFIG_SCHED_INSTRUMENTATION_PREEMPTION
|
#ifdef CONFIG_SCHED_INSTRUMENTATION_PREEMPTION
|
||||||
/* This is the specific form of the NOTE_PREEMPT_LOCK/UNLOCK note */
|
/* This is the specific form of the NOTE_PREEMPT_LOCK/UNLOCK note */
|
||||||
|
|
||||||
@@ -174,12 +213,28 @@ void sched_note_stop(FAR struct tcb_s *tcb);
|
|||||||
void sched_note_suspend(FAR struct tcb_s *tcb);
|
void sched_note_suspend(FAR struct tcb_s *tcb);
|
||||||
void sched_note_resume(FAR struct tcb_s *tcb);
|
void sched_note_resume(FAR struct tcb_s *tcb);
|
||||||
|
|
||||||
|
#ifdef CONFIG_SMP
|
||||||
|
void sched_note_cpu_pause(FAR struct tcb_s *tcb, int cpu);
|
||||||
|
void sched_note_cpu_paused(FAR struct tcb_s *tcb);
|
||||||
|
void sched_note_cpu_resume(FAR struct tcb_s *tcb, int cpu);
|
||||||
|
void sched_note_cpu_resumed(FAR struct tcb_s *tcb);
|
||||||
|
#else
|
||||||
|
# define sched_note_cpu_pause(t,c)
|
||||||
|
# define sched_note_cpu_paused(t)
|
||||||
|
# define sched_note_cpu_resume(t,c)
|
||||||
|
# define sched_note_cpu_resumed(t)
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef CONFIG_SCHED_INSTRUMENTATION_PREEMPTION
|
#ifdef CONFIG_SCHED_INSTRUMENTATION_PREEMPTION
|
||||||
void sched_note_premption(FAR struct tcb_s *tcb, bool locked);
|
void sched_note_premption(FAR struct tcb_s *tcb, bool locked);
|
||||||
|
#else
|
||||||
|
# define sched_note_premption(t,l)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef CONFIG_SCHED_INSTRUMENTATION_CSECTION
|
#ifdef CONFIG_SCHED_INSTRUMENTATION_CSECTION
|
||||||
void sched_note_csection(FAR struct tcb_s *tcb, bool enter);
|
void sched_note_csection(FAR struct tcb_s *tcb, bool enter);
|
||||||
|
#else
|
||||||
|
# define sched_note_csection(t,e)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
@@ -250,6 +305,10 @@ int note_register(void);
|
|||||||
# define sched_note_stop(t)
|
# define sched_note_stop(t)
|
||||||
# define sched_note_suspend(t)
|
# define sched_note_suspend(t)
|
||||||
# define sched_note_resume(t)
|
# define sched_note_resume(t)
|
||||||
|
# define sched_note_cpu_pause(t,c)
|
||||||
|
# define sched_note_cpu_paused(t)
|
||||||
|
# define sched_note_cpu_resume(t,c)
|
||||||
|
# define sched_note_cpu_resumed(t)
|
||||||
# define sched_note_premption(t,l)
|
# define sched_note_premption(t,l)
|
||||||
# define sched_note_csection(t,e)
|
# define sched_note_csection(t,e)
|
||||||
|
|
||||||
|
|||||||
@@ -661,6 +661,14 @@ config SCHED_INSTRUMENTATION
|
|||||||
void sched_note_suspend(FAR struct tcb_s *tcb);
|
void sched_note_suspend(FAR struct tcb_s *tcb);
|
||||||
void sched_note_resume(FAR struct tcb_s *tcb);
|
void sched_note_resume(FAR struct tcb_s *tcb);
|
||||||
|
|
||||||
|
If CONFIG_SMP is enabled, then these additional interfaces are
|
||||||
|
expected:
|
||||||
|
|
||||||
|
void sched_note_cpu_pause(FAR struct tcb_s *tcb, int cpu);
|
||||||
|
void sched_note_cpu_paused(FAR struct tcb_s *tcb);
|
||||||
|
void sched_note_cpu_resume(FAR struct tcb_s *tcb, int cpu);
|
||||||
|
void sched_note_cpu_resumed(FAR struct tcb_s *tcb);
|
||||||
|
|
||||||
NOTE: These are internal OS interfaces and are called at at very
|
NOTE: These are internal OS interfaces and are called at at very
|
||||||
critical locations in the OS. There is very little that can be
|
critical locations in the OS. There is very little that can be
|
||||||
done in these interfaces. For example, normal devices may not be
|
done in these interfaces. For example, normal devices may not be
|
||||||
|
|||||||
@@ -44,6 +44,7 @@
|
|||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
|
||||||
#include <nuttx/arch.h>
|
#include <nuttx/arch.h>
|
||||||
|
#include <nuttx/sched_note.h>
|
||||||
|
|
||||||
#include "sched/sched.h"
|
#include "sched/sched.h"
|
||||||
|
|
||||||
|
|||||||
@@ -369,6 +369,62 @@ void sched_note_resume(FAR struct tcb_s *tcb)
|
|||||||
note_add((FAR const uint8_t *)¬e, sizeof(struct note_resume_s));
|
note_add((FAR const uint8_t *)¬e, sizeof(struct note_resume_s));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_SMP
|
||||||
|
void sched_note_cpu_pause(FAR struct tcb_s *tcb, int cpu)
|
||||||
|
{
|
||||||
|
struct note_cpu_pause_s note;
|
||||||
|
|
||||||
|
/* Format the note */
|
||||||
|
|
||||||
|
note_common(tcb, ¬e.ncp_cmn, sizeof(struct note_cpu_pause_s), NOTE_CPU_PAUSE);
|
||||||
|
note.ncp_target = (uint8_t)cpu;
|
||||||
|
|
||||||
|
/* Add the note to circular buffer */
|
||||||
|
|
||||||
|
note_add((FAR const uint8_t *)¬e, sizeof(struct note_cpu_pause_s));
|
||||||
|
}
|
||||||
|
|
||||||
|
void sched_note_cpu_paused(FAR struct tcb_s *tcb)
|
||||||
|
{
|
||||||
|
struct note_cpu_paused_s note;
|
||||||
|
|
||||||
|
/* Format the note */
|
||||||
|
|
||||||
|
note_common(tcb, ¬e.ncp_cmn, sizeof(struct note_cpu_paused_s), NOTE_CPU_PAUSED);
|
||||||
|
|
||||||
|
/* Add the note to circular buffer */
|
||||||
|
|
||||||
|
note_add((FAR const uint8_t *)¬e, sizeof(struct note_cpu_paused_s));
|
||||||
|
}
|
||||||
|
|
||||||
|
void sched_note_cpu_resume(FAR struct tcb_s *tcb, int cpu)
|
||||||
|
{
|
||||||
|
struct note_cpu_resume_s note;
|
||||||
|
|
||||||
|
/* Format the note */
|
||||||
|
|
||||||
|
note_common(tcb, ¬e.ncr_cmn, sizeof(struct note_cpu_resume_s), NOTE_CPU_RESUME);
|
||||||
|
note.ncr_target = (uint8_t)cpu;
|
||||||
|
|
||||||
|
/* Add the note to circular buffer */
|
||||||
|
|
||||||
|
note_add((FAR const uint8_t *)¬e, sizeof(struct note_cpu_resume_s));
|
||||||
|
}
|
||||||
|
|
||||||
|
void sched_note_cpu_resumed(FAR struct tcb_s *tcb)
|
||||||
|
{
|
||||||
|
struct note_cpu_resumed_s note;
|
||||||
|
|
||||||
|
/* Format the note */
|
||||||
|
|
||||||
|
note_common(tcb, ¬e.ncr_cmn, sizeof(struct note_cpu_resumed_s), NOTE_CPU_RESUMED);
|
||||||
|
|
||||||
|
/* Add the note to circular buffer */
|
||||||
|
|
||||||
|
note_add((FAR const uint8_t *)¬e, sizeof(struct note_cpu_resumed_s));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef CONFIG_SCHED_INSTRUMENTATION_PREEMPTION
|
#ifdef CONFIG_SCHED_INSTRUMENTATION_PREEMPTION
|
||||||
void sched_note_premption(FAR struct tcb_s *tcb, bool locked)
|
void sched_note_premption(FAR struct tcb_s *tcb, bool locked)
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user