sched/: Move location (and form) of context switch instrumentation.

This commit is contained in:
Gregory Nutt 2016-03-21 14:08:31 -06:00
parent c49bd4179a
commit f7b58e9dfd
10 changed files with 140 additions and 105 deletions

View File

@ -815,7 +815,8 @@ void task_vforkabort(FAR struct task_tcb_s *child, int errcode);
*
********************************************************************************/
#if CONFIG_RR_INTERVAL > 0 || defined(CONFIG_SCHED_SPORADIC)
#if CONFIG_RR_INTERVAL > 0 || defined(CONFIG_SCHED_SPORADIC) || \
defined(CONFIG_SCHED_INSTRUMENTATION)
void sched_resume_scheduler(FAR struct tcb_s *tcb);
#else
# define sched_resume_scheduler(tcb)
@ -837,7 +838,7 @@ void sched_resume_scheduler(FAR struct tcb_s *tcb);
*
********************************************************************************/
#ifdef CONFIG_SCHED_SPORADIC
#if defined(CONFIG_SCHED_SPORADIC) || defined(CONFIG_SCHED_INSTRUMENTATION)
void sched_suspend_scheduler(FAR struct tcb_s *tcb);
#else
# define sched_suspend_scheduler(tcb)

View File

@ -62,7 +62,8 @@ enum note_type_e
{
NOTE_START = 0,
NOTE_STOP,
NOTE_SWITCH
NOTE_SUSPEND,
NOTE_RESUME
#ifdef CONFIG_SCHED_INSTRUMENTATION_PREEMPTION
,
NOTE_PREEMPT_LOCK,
@ -79,21 +80,23 @@ enum note_type_e
struct note_common_s
{
uint8_t nc_length; /* Length of the note */
uint8_t nc_type; /* See enum note_type_e */
uint8_t nc_systime[4]; /* Time when note buffered */
uint8_t nc_length; /* Length of the note */
uint8_t nc_type; /* See enum note_type_e */
uint8_t nc_priority; /* Thread/task priority */
#ifdef CONFIG_SMP
uint8_t nc_cpu; /* CPU thread/task running on */
#endif
uint8_t nc_pid[2]; /* ID of the thread/task */
uint8_t nc_systime[4]; /* Time when note buffered */
};
/* This is the specific form of the NOTE_START note */
struct note_start_s
{
uint8_t nst_length; /* Length of the note */
uint8_t nst_type; /* Must be NOTE_START */
uint8_t nst_systime[4]; /* Time when note buffered */
uint8_t nst_pid[2]; /* ID of the new thread/task */
struct note_common_s nst_cmn; /* Common note parameters */
#if CONFIG_TASK_NAME_SIZE > 0
char nst_name[1]; /* Start of the name of the thread/task */
char nst_name[1]; /* Start of the name of the thread/task */
#endif
};
@ -101,21 +104,14 @@ struct note_start_s
struct note_stop_s
{
uint8_t nsp_length; /* Length of the note */
uint8_t nsp_type; /* Must be NOTE_STOP */
uint8_t nsp_systime[4]; /* Time when note buffered */
uint8_t nsp_pid[2]; /* ID of the thread/task that stopped */
struct note_common_s nsp_cmn; /* Common note parameters */
};
/* This is the specific form of the NOTE_SWITCH note */
/* This is the specific form of the NOTE_SUSPEND/NOTE_RESUME note */
struct note_switch_s
{
uint8_t nsw_length; /* Length of the note */
uint8_t nsw_type; /* Must be NOTE_SWITCH */
uint8_t nsw_systime[4]; /* Time when note buffered */
uint8_t nsw_pidout[2]; /* ID of the thread/task that was blocked */
uint8_t nsw_pidin[2]; /* ID of the thread/task that was started */
struct note_common_s nsw_cmn; /* Common note parameters */
};
#ifdef CONFIG_SCHED_INSTRUMENTATION_PREEMPTION
@ -123,11 +119,8 @@ struct note_switch_s
struct note_preempt_s
{
uint8_t npr_length; /* Length of the note */
uint8_t npr_type; /* Must be NOTE_PREEMPT_LOCK or _UNLOCK */
uint8_t npr_systime[4]; /* Time when note buffered */
uint8_t npr_pid[2]; /* ID of the thread/task that change pre-emption */
uint8_t npr_count[2]; /* Count of nested locks */
struct note_common_s npr_cmn; /* Common note parameters */
uint8_t npr_count[2]; /* Count of nested locks */
};
#endif /* CONFIG_SCHED_INSTRUMENTATION_PREEMPTION */
@ -136,12 +129,9 @@ struct note_preempt_s
struct note_csection_s
{
uint8_t ncs_length; /* Length of the note */
uint8_t ncs_type; /* Must be NOTE_CSECTION_ENTER or _LEAVE */
uint8_t ncs_systime[4]; /* Time when note buffered */
uint8_t ncs_pid[2]; /* ID of the thread/task that changed critical section */
struct note_common_s ncs_cmn; /* Common note parameters */
#ifdef CONFIG_SMP
uint8_t ncs_count[2]; /* Count of nested csections */
uint8_t ncs_count[2]; /* Count of nested csections */
#endif
};
#endif /* CONFIG_SCHED_INSTRUMENTATION_CSECTION */
@ -173,7 +163,8 @@ struct note_csection_s
void sched_note_start(FAR struct tcb_s *tcb);
void sched_note_stop(FAR struct tcb_s *tcb);
void sched_note_switch(FAR struct tcb_s *fromtcb, FAR struct tcb_s *totcb);
void sched_note_suspend(FAR struct tcb_s *tcb);
void sched_note_resume(FAR struct tcb_s *tcb);
#ifdef CONFIG_SCHED_INSTRUMENTATION_PREEMPTION
void sched_note_premption(FAR struct tcb_s *tcb, bool locked);
@ -249,7 +240,8 @@ int note_register(void);
# define sched_note_start(t)
# define sched_note_stop(t)
# define sched_note_switch(t1, t2)
# define sched_note_suspend(t)
# define sched_note_resume(t)
# define sched_note_premption(t,l)
# define sched_note_csection(t,e)

View File

@ -603,7 +603,8 @@ config SCHED_INSTRUMENTATION
void sched_note_start(FAR struct tcb_s *tcb);
void sched_note_stop(FAR struct tcb_s *tcb);
void sched_note_switch(FAR struct tcb_s *pFromTcb, FAR struct tcb_s *pToTcb);
void sched_note_suspend(FAR struct tcb_s *tcb);
void sched_note_resume(FAR struct tcb_s *tcb);
NOTE: These are internal OS interfaces and are called at at very
critical locations in the OS. There is very little that can be

View File

@ -64,12 +64,16 @@ endif
ifeq ($(CONFIG_SCHED_SPORADIC),y)
CSRCS += sched_sporadic.c sched_suspendscheduler.c
else ifeq ($(CONFIG_SCHED_INSTRUMENTATION),y)
CSRCS += sched_suspendscheduler.c
endif
ifneq ($(CONFIG_RR_INTERVAL),0)
CSRCS += sched_resumescheduler.c
else ifeq ($(CONFIG_SCHED_SPORADIC),y)
CSRCS += sched_resumescheduler.c
else ifeq ($(CONFIG_SCHED_INSTRUMENTATION),y)
CSRCS += sched_resumescheduler.c
endif
ifeq ($(CONFIG_SCHED_CPULOAD),y)

View File

@ -43,8 +43,6 @@
#include <queue.h>
#include <assert.h>
#include <nuttx/sched_note.h>
#include "irq/irq.h"
#include "sched/sched.h"
@ -107,10 +105,6 @@ bool sched_addreadytorun(FAR struct tcb_s *btcb)
else if (sched_addprioritized(btcb, (FAR dq_queue_t *)&g_readytorun))
{
/* Inform the instrumentation logic that we are switching tasks */
sched_note_switch(rtcb, btcb);
/* The new btcb was added at the head of the ready-to-run list. It
* is now the new active task!
*/
@ -286,12 +280,8 @@ bool sched_addreadytorun(FAR struct tcb_s *btcb)
/* The new btcb was added at the head of the ready-to-run list. It
* is now the new active task!
*
* Inform the instrumentation logic that we are switching tasks.
*/
sched_note_switch(rtcb, btcb);
/* Assign the CPU and set the running state */
DEBUGASSERT(task_state == TSTATE_TASK_RUNNING);

View File

@ -44,8 +44,6 @@
#include <queue.h>
#include <assert.h>
#include <nuttx/sched_note.h>
#include "sched/sched.h"
/****************************************************************************
@ -123,11 +121,6 @@ bool sched_mergepending(void)
if (!rprev)
{
/* Special case: Inserting ptcb at the head of the list */
/* Inform the instrumentation layer that we are switching tasks */
sched_note_switch(rtcb, ptcb);
/* Then insert at the head of the list */
ptcb->flink = rtcb;
ptcb->blink = NULL;

View File

@ -67,12 +67,9 @@ struct note_info_s
struct note_startalloc_s
{
uint8_t nsa_length;
uint8_t nsa_type;
uint8_t nsa_systime[4];
uint8_t nsa_pid[2];
struct note_common_s nsa_cmn; /* Common note parameters */
#if CONFIG_TASK_NAME_SIZE > 0
char nsa_name[CONFIG_TASK_NAME_SIZE + 1];
char nsa_name[CONFIG_TASK_NAME_SIZE + 1];
#endif
};
@ -266,6 +263,45 @@ static void note_add(FAR const uint8_t *note, uint8_t notelen)
g_note_info.ni_head = head;
}
/****************************************************************************
* Name: sched_note_switch
*
* Description:
* Perform core logic for both sched_note_suspend and sched_note_resume
*
* Input Parameters:
* None
*
* Returned Value:
* None
*
* Assumptions:
* We are within a critical section.
*
****************************************************************************/
static void sched_note_switch(FAR struct tcb_s *tcb, uint8_t type)
{
struct note_switch_s note;
/* Format the note */
note.nsw_cmn.nc_length = sizeof(struct note_switch_s);
note.nsw_cmn.nc_type = type;
note.nsw_cmn.nc_priority = tcb->sched_priority;
#ifdef CONFIG_SMP
note.nsw_cmn.nc_cpu = tcb->cpu;
#endif
note.nsw_cmn.nc_pid[0] = (uint8_t)(tcb->pid & 0xff);
note.nsw_cmn.nc_pid[1] = (uint8_t)((tcb->pid >> 8) & 0xff);
note_systime((FAR struct note_common_s *)&note);
/* Add the note to circular buffer */
note_add((FAR const uint8_t *)&note, sizeof(struct note_switch_s));
}
/****************************************************************************
* Public Functions
****************************************************************************/
@ -312,10 +348,14 @@ void sched_note_start(FAR struct tcb_s *tcb)
/* Finish formatting the note */
note.nsa_length = length;
note.nsa_type = NOTE_START;
note.nsa_pid[0] = (uint8_t)(tcb->pid & 0xff);
note.nsa_pid[1] = (uint8_t)((tcb->pid >> 8) & 0xff);
note.nsa_cmn.nc_length = length;
note.nsa_cmn.nc_type = NOTE_START;
note.nsa_cmn.nc_priority = tcb->sched_priority;
#ifdef CONFIG_SMP
note.nsa_cmn.nc_cpu = tcb->cpu;
#endif
note.nsa_cmn.nc_pid[0] = (uint8_t)(tcb->pid & 0xff);
note.nsa_cmn.nc_pid[1] = (uint8_t)((tcb->pid >> 8) & 0xff);
note_systime((FAR struct note_common_s *)&note);
@ -330,10 +370,14 @@ void sched_note_stop(FAR struct tcb_s *tcb)
/* Format the note */
note.nsp_length = sizeof(struct note_stop_s);
note.nsp_type = NOTE_STOP;
note.nsp_pid[0] = (uint8_t)(tcb->pid & 0xff);
note.nsp_pid[1] = (uint8_t)((tcb->pid >> 8) & 0xff);
note.nsp_cmn.nc_length = sizeof(struct note_stop_s);
note.nsp_cmn.nc_type = NOTE_STOP;
note.nsp_cmn.nc_priority = tcb->sched_priority;
#ifdef CONFIG_SMP
note.nsp_cmn.nc_cpu = tcb->cpu;
#endif
note.nsp_cmn.nc_pid[0] = (uint8_t)(tcb->pid & 0xff);
note.nsp_cmn.nc_pid[1] = (uint8_t)((tcb->pid >> 8) & 0xff);
note_systime((FAR struct note_common_s *)&note);
@ -342,24 +386,14 @@ void sched_note_stop(FAR struct tcb_s *tcb)
note_add((FAR const uint8_t *)&note, sizeof(struct note_stop_s));
}
void sched_note_switch(FAR struct tcb_s *fromtcb, FAR struct tcb_s *totcb)
void sched_note_suspend(FAR struct tcb_s *tcb)
{
struct note_switch_s note;
sched_note_switch(tcb, NOTE_SUSPEND);
}
/* Format the note */
note.nsw_length = sizeof(struct note_switch_s);
note.nsw_type = NOTE_SWITCH;
note.nsw_pidout[0] = (uint8_t)(fromtcb->pid & 0xff);
note.nsw_pidout[1] = (uint8_t)((fromtcb->pid >> 8) & 0xff);
note.nsw_pidin[0] = (uint8_t)(totcb->pid & 0xff);
note.nsw_pidin[1] = (uint8_t)((totcb->pid >> 8) & 0xff);
note_systime((FAR struct note_common_s *)&note);
/* Add the note to circular buffer */
note_add((FAR const uint8_t *)&note, sizeof(struct note_switch_s));
void sched_note_resume(FAR struct tcb_s *tcb)
{
sched_note_switch(tcb, NOTE_RESUME);
}
#ifdef CONFIG_SCHED_INSTRUMENTATION_PREEMPTION
@ -369,12 +403,16 @@ void sched_note_premption(FAR struct tcb_s *tcb, bool locked)
/* Format the note */
note.npr_length = sizeof(struct note_preempt_s);
note.npr_type = locked ? NOTE_PREEMPT_LOCK : NOTE_PREEMPT_UNLOCK;
note.npr_pid[0] = (uint8_t)(tcb->pid & 0xff);
note.npr_pid[1] = (uint8_t)((tcb->pid >> 8) & 0xff);
note.npr_count[0] = (uint8_t)(tcb->lockcount & 0xff);
note.npr_count[1] = (uint8_t)((tcb->lockcount >> 8) & 0xff);
note.npr_cmn.nc_length = sizeof(struct note_preempt_s);
note.npr_cmn.nc_type = locked ? NOTE_PREEMPT_LOCK : NOTE_PREEMPT_UNLOCK;
note.npr_cmn.nc_priority = tcb->sched_priority;
#ifdef CONFIG_SMP
note.npr_cmn.nc_cpu = tcb->cpu;
#endif
note.npr_cmn.nc_pid[0] = (uint8_t)(tcb->pid & 0xff);
note.npr_cmn.nc_pid[1] = (uint8_t)((tcb->pid >> 8) & 0xff);
note.npr_count[0] = (uint8_t)(tcb->lockcount & 0xff);
note.npr_count[1] = (uint8_t)((tcb->lockcount >> 8) & 0xff);
note_systime((FAR struct note_common_s *)&note);
@ -391,13 +429,17 @@ void sched_note_csection(FAR struct tcb_s *tcb, bool enter)
/* Format the note */
note.ncs_length = sizeof(struct note_preempt_s);
note.ncs_type = enter ? NOTE_CSECTION_ENTER : NOTE_CSECTION_LEAVE;
note.ncs_pid[0] = (uint8_t)(tcb->pid & 0xff);
note.ncs_pid[1] = (uint8_t)((tcb->pid >> 8) & 0xff);
note.ncs_cmn.nc_length = sizeof(struct note_preempt_s);
note.ncs_cmn.nc_type = enter ? NOTE_CSECTION_ENTER : NOTE_CSECTION_LEAVE;
note.ncs_cmn.nc_priority = tcb->sched_priority;
#ifdef CONFIG_SMP
note.ncs_count[0] = (uint8_t)(tcb->irqcount & 0xff);
note.ncs_count[1] = (uint8_t)((tcb->irqcount >> 8) & 0xff);
note.ncs_cmn.nc_cpu = tcb->cpu;
#endif
note.ncs_cmn.nc_pid[0] = (uint8_t)(tcb->pid & 0xff);
note.ncs_cmn.nc_pid[1] = (uint8_t)((tcb->pid >> 8) & 0xff);
#ifdef CONFIG_SMP
note.ncs_count[0] = (uint8_t)(tcb->irqcount & 0xff);
note.ncs_count[1] = (uint8_t)((tcb->irqcount >> 8) & 0xff);
#endif
note_systime((FAR struct note_common_s *)&note);

View File

@ -43,8 +43,6 @@
#include <queue.h>
#include <assert.h>
#include <nuttx/sched_note.h>
#include "irq/irq.h"
#include "sched/sched.h"
@ -94,9 +92,6 @@ bool sched_removereadytorun(FAR struct tcb_s *rtcb)
FAR struct tcb_s *ntcb = (FAR struct tcb_s *)rtcb->flink;
DEBUGASSERT(ntcb != NULL);
/* Inform the instrumentation layer that we are switching tasks */
sched_note_switch(rtcb, ntcb);
ntcb->task_state = TSTATE_TASK_RUNNING;
doswitch = true;
}
@ -224,9 +219,6 @@ bool sched_removereadytorun(FAR struct tcb_s *rtcb)
&g_cpu_irqlock);
}
/* Inform the instrumentation layer that we are switching tasks */
sched_note_switch(rtcb, ntcb);
ntcb->task_state = TSTATE_TASK_RUNNING;
/* The task is running but the CPU that it was running on has been

View File

@ -43,10 +43,12 @@
#include <nuttx/sched.h>
#include <nuttx/clock.h>
#include <nuttx/sched_note.h>
#include "sched/sched.h"
#if CONFIG_RR_INTERVAL > 0 || defined(CONFIG_SCHED_SPORADIC)
#if CONFIG_RR_INTERVAL > 0 || defined(CONFIG_SCHED_SPORADIC) || \
defined(CONFIG_SCHED_INSTRUMENTATION)
/****************************************************************************
* Public Functions
@ -92,6 +94,13 @@ void sched_resume_scheduler(FAR struct tcb_s *tcb)
DEBUGVERIFY(sched_sporadic_resume(tcb));
}
#endif
#ifdef CONFIG_SCHED_INSTRUMENTATION
/* Inidicate the the task has been resumed */
sched_note_resume(tcb);
#endif
}
#endif /* CONFIG_RR_INTERVAL > 0 || CONFIG_SCHED_SPORADIC */
#endif /* CONFIG_RR_INTERVAL > 0 || CONFIG_SCHED_SPORADIC || CONFIG_SCHED_INSTRUMENTATION */

View File

@ -1,7 +1,7 @@
/****************************************************************************
* sched/sched/sched_suspendscheduler.c
*
* Copyright (C) 2015 Gregory Nutt. All rights reserved.
* Copyright (C) 2015-2016 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
@ -45,11 +45,12 @@
#include <nuttx/arch.h>
#include <nuttx/sched.h>
#include <nuttx/clock.h>
#include <nuttx/sched_note.h>
#include "clock/clock.h"
#include "sched/sched.h"
#ifdef CONFIG_SCHED_SPORADIC
#if defined(CONFIG_SCHED_SPORADIC) || defined(CONFIG_SCHED_INSTRUMENTATION)
/****************************************************************************
* Public Functions
@ -73,10 +74,20 @@
void sched_suspend_scheduler(FAR struct tcb_s *tcb)
{
#ifdef CONFIG_SCHED_SPORADIC
/* Perform sporadic schedule operations */
if ((tcb->flags & TCB_FLAG_POLICY_MASK) == TCB_FLAG_SCHED_SPORADIC)
{
DEBUGVERIFY(sched_sporadic_suspend(tcb));
}
#endif
#ifdef CONFIG_SCHED_INSTRUMENTATION
/* Inidicate the the task has been suspended */
sched_note_suspend(tcb);
#endif
}
#endif /* CONFIG_SCHED_SPORADIC */
#endif /* CONFIG_SCHED_SPORADIC || CONFIG_SCHED_INSTRUMENTATION */