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); void sched_resume_scheduler(FAR struct tcb_s *tcb);
#else #else
# define sched_resume_scheduler(tcb) # 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); void sched_suspend_scheduler(FAR struct tcb_s *tcb);
#else #else
# define sched_suspend_scheduler(tcb) # define sched_suspend_scheduler(tcb)

View File

@ -62,7 +62,8 @@ enum note_type_e
{ {
NOTE_START = 0, NOTE_START = 0,
NOTE_STOP, NOTE_STOP,
NOTE_SWITCH NOTE_SUSPEND,
NOTE_RESUME
#ifdef CONFIG_SCHED_INSTRUMENTATION_PREEMPTION #ifdef CONFIG_SCHED_INSTRUMENTATION_PREEMPTION
, ,
NOTE_PREEMPT_LOCK, NOTE_PREEMPT_LOCK,
@ -79,21 +80,23 @@ enum note_type_e
struct note_common_s struct note_common_s
{ {
uint8_t nc_length; /* Length of the note */ uint8_t nc_length; /* Length of the note */
uint8_t nc_type; /* See enum note_type_e */ uint8_t nc_type; /* See enum note_type_e */
uint8_t nc_systime[4]; /* Time when note buffered */ 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 */ /* This is the specific form of the NOTE_START note */
struct note_start_s struct note_start_s
{ {
uint8_t nst_length; /* Length of the note */ struct note_common_s nst_cmn; /* Common note parameters */
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 */
#if CONFIG_TASK_NAME_SIZE > 0 #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 #endif
}; };
@ -101,21 +104,14 @@ struct note_start_s
struct note_stop_s struct note_stop_s
{ {
uint8_t nsp_length; /* Length of the note */ struct note_common_s nsp_cmn; /* Common note parameters */
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 */
}; };
/* 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 struct note_switch_s
{ {
uint8_t nsw_length; /* Length of the note */ struct note_common_s nsw_cmn; /* Common note parameters */
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 */
}; };
#ifdef CONFIG_SCHED_INSTRUMENTATION_PREEMPTION #ifdef CONFIG_SCHED_INSTRUMENTATION_PREEMPTION
@ -123,11 +119,8 @@ struct note_switch_s
struct note_preempt_s struct note_preempt_s
{ {
uint8_t npr_length; /* Length of the note */ struct note_common_s npr_cmn; /* Common note parameters */
uint8_t npr_type; /* Must be NOTE_PREEMPT_LOCK or _UNLOCK */ uint8_t npr_count[2]; /* Count of nested locks */
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 */
}; };
#endif /* CONFIG_SCHED_INSTRUMENTATION_PREEMPTION */ #endif /* CONFIG_SCHED_INSTRUMENTATION_PREEMPTION */
@ -136,12 +129,9 @@ struct note_preempt_s
struct note_csection_s struct note_csection_s
{ {
uint8_t ncs_length; /* Length of the note */ struct note_common_s ncs_cmn; /* Common note parameters */
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 */
#ifdef CONFIG_SMP #ifdef CONFIG_SMP
uint8_t ncs_count[2]; /* Count of nested csections */ uint8_t ncs_count[2]; /* Count of nested csections */
#endif #endif
}; };
#endif /* CONFIG_SCHED_INSTRUMENTATION_CSECTION */ #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_start(FAR struct tcb_s *tcb);
void sched_note_stop(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 #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);
@ -249,7 +240,8 @@ int note_register(void);
# define sched_note_start(t) # define sched_note_start(t)
# define sched_note_stop(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_premption(t,l)
# define sched_note_csection(t,e) # 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_start(FAR struct tcb_s *tcb);
void sched_note_stop(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 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

View File

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

View File

@ -43,8 +43,6 @@
#include <queue.h> #include <queue.h>
#include <assert.h> #include <assert.h>
#include <nuttx/sched_note.h>
#include "irq/irq.h" #include "irq/irq.h"
#include "sched/sched.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)) 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 /* The new btcb was added at the head of the ready-to-run list. It
* is now the new active task! * 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 /* The new btcb was added at the head of the ready-to-run list. It
* is now the new active task! * 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 */ /* Assign the CPU and set the running state */
DEBUGASSERT(task_state == TSTATE_TASK_RUNNING); DEBUGASSERT(task_state == TSTATE_TASK_RUNNING);

View File

@ -44,8 +44,6 @@
#include <queue.h> #include <queue.h>
#include <assert.h> #include <assert.h>
#include <nuttx/sched_note.h>
#include "sched/sched.h" #include "sched/sched.h"
/**************************************************************************** /****************************************************************************
@ -123,11 +121,6 @@ bool sched_mergepending(void)
if (!rprev) if (!rprev)
{ {
/* Special case: Inserting ptcb at the head of the list */ /* 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->flink = rtcb;
ptcb->blink = NULL; ptcb->blink = NULL;

View File

@ -67,12 +67,9 @@ struct note_info_s
struct note_startalloc_s struct note_startalloc_s
{ {
uint8_t nsa_length; struct note_common_s nsa_cmn; /* Common note parameters */
uint8_t nsa_type;
uint8_t nsa_systime[4];
uint8_t nsa_pid[2];
#if CONFIG_TASK_NAME_SIZE > 0 #if CONFIG_TASK_NAME_SIZE > 0
char nsa_name[CONFIG_TASK_NAME_SIZE + 1]; char nsa_name[CONFIG_TASK_NAME_SIZE + 1];
#endif #endif
}; };
@ -266,6 +263,45 @@ static void note_add(FAR const uint8_t *note, uint8_t notelen)
g_note_info.ni_head = head; 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 * Public Functions
****************************************************************************/ ****************************************************************************/
@ -312,10 +348,14 @@ void sched_note_start(FAR struct tcb_s *tcb)
/* Finish formatting the note */ /* Finish formatting the note */
note.nsa_length = length; note.nsa_cmn.nc_length = length;
note.nsa_type = NOTE_START; note.nsa_cmn.nc_type = NOTE_START;
note.nsa_pid[0] = (uint8_t)(tcb->pid & 0xff); note.nsa_cmn.nc_priority = tcb->sched_priority;
note.nsa_pid[1] = (uint8_t)((tcb->pid >> 8) & 0xff); #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); note_systime((FAR struct note_common_s *)&note);
@ -330,10 +370,14 @@ void sched_note_stop(FAR struct tcb_s *tcb)
/* Format the note */ /* Format the note */
note.nsp_length = sizeof(struct note_stop_s); note.nsp_cmn.nc_length = sizeof(struct note_stop_s);
note.nsp_type = NOTE_STOP; note.nsp_cmn.nc_type = NOTE_STOP;
note.nsp_pid[0] = (uint8_t)(tcb->pid & 0xff); note.nsp_cmn.nc_priority = tcb->sched_priority;
note.nsp_pid[1] = (uint8_t)((tcb->pid >> 8) & 0xff); #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); 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)); 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 */ void sched_note_resume(FAR struct tcb_s *tcb)
{
note.nsw_length = sizeof(struct note_switch_s); sched_note_switch(tcb, NOTE_RESUME);
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));
} }
#ifdef CONFIG_SCHED_INSTRUMENTATION_PREEMPTION #ifdef CONFIG_SCHED_INSTRUMENTATION_PREEMPTION
@ -369,12 +403,16 @@ void sched_note_premption(FAR struct tcb_s *tcb, bool locked)
/* Format the note */ /* Format the note */
note.npr_length = sizeof(struct note_preempt_s); note.npr_cmn.nc_length = sizeof(struct note_preempt_s);
note.npr_type = locked ? NOTE_PREEMPT_LOCK : NOTE_PREEMPT_UNLOCK; note.npr_cmn.nc_type = locked ? NOTE_PREEMPT_LOCK : NOTE_PREEMPT_UNLOCK;
note.npr_pid[0] = (uint8_t)(tcb->pid & 0xff); note.npr_cmn.nc_priority = tcb->sched_priority;
note.npr_pid[1] = (uint8_t)((tcb->pid >> 8) & 0xff); #ifdef CONFIG_SMP
note.npr_count[0] = (uint8_t)(tcb->lockcount & 0xff); note.npr_cmn.nc_cpu = tcb->cpu;
note.npr_count[1] = (uint8_t)((tcb->lockcount >> 8) & 0xff); #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); 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 */ /* Format the note */
note.ncs_length = sizeof(struct note_preempt_s); note.ncs_cmn.nc_length = sizeof(struct note_preempt_s);
note.ncs_type = enter ? NOTE_CSECTION_ENTER : NOTE_CSECTION_LEAVE; note.ncs_cmn.nc_type = enter ? NOTE_CSECTION_ENTER : NOTE_CSECTION_LEAVE;
note.ncs_pid[0] = (uint8_t)(tcb->pid & 0xff); note.ncs_cmn.nc_priority = tcb->sched_priority;
note.ncs_pid[1] = (uint8_t)((tcb->pid >> 8) & 0xff);
#ifdef CONFIG_SMP #ifdef CONFIG_SMP
note.ncs_count[0] = (uint8_t)(tcb->irqcount & 0xff); note.ncs_cmn.nc_cpu = tcb->cpu;
note.ncs_count[1] = (uint8_t)((tcb->irqcount >> 8) & 0xff); #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 #endif
note_systime((FAR struct note_common_s *)&note); note_systime((FAR struct note_common_s *)&note);

View File

@ -43,8 +43,6 @@
#include <queue.h> #include <queue.h>
#include <assert.h> #include <assert.h>
#include <nuttx/sched_note.h>
#include "irq/irq.h" #include "irq/irq.h"
#include "sched/sched.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; FAR struct tcb_s *ntcb = (FAR struct tcb_s *)rtcb->flink;
DEBUGASSERT(ntcb != NULL); DEBUGASSERT(ntcb != NULL);
/* Inform the instrumentation layer that we are switching tasks */
sched_note_switch(rtcb, ntcb);
ntcb->task_state = TSTATE_TASK_RUNNING; ntcb->task_state = TSTATE_TASK_RUNNING;
doswitch = true; doswitch = true;
} }
@ -224,9 +219,6 @@ bool sched_removereadytorun(FAR struct tcb_s *rtcb)
&g_cpu_irqlock); &g_cpu_irqlock);
} }
/* Inform the instrumentation layer that we are switching tasks */
sched_note_switch(rtcb, ntcb);
ntcb->task_state = TSTATE_TASK_RUNNING; ntcb->task_state = TSTATE_TASK_RUNNING;
/* The task is running but the CPU that it was running on has been /* 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/sched.h>
#include <nuttx/clock.h> #include <nuttx/clock.h>
#include <nuttx/sched_note.h>
#include "sched/sched.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 * Public Functions
@ -92,6 +94,13 @@ void sched_resume_scheduler(FAR struct tcb_s *tcb)
DEBUGVERIFY(sched_sporadic_resume(tcb)); DEBUGVERIFY(sched_sporadic_resume(tcb));
} }
#endif #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 * 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> * 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
@ -45,11 +45,12 @@
#include <nuttx/arch.h> #include <nuttx/arch.h>
#include <nuttx/sched.h> #include <nuttx/sched.h>
#include <nuttx/clock.h> #include <nuttx/clock.h>
#include <nuttx/sched_note.h>
#include "clock/clock.h" #include "clock/clock.h"
#include "sched/sched.h" #include "sched/sched.h"
#ifdef CONFIG_SCHED_SPORADIC #if defined(CONFIG_SCHED_SPORADIC) || defined(CONFIG_SCHED_INSTRUMENTATION)
/**************************************************************************** /****************************************************************************
* Public Functions * Public Functions
@ -73,10 +74,20 @@
void sched_suspend_scheduler(FAR struct tcb_s *tcb) 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) if ((tcb->flags & TCB_FLAG_POLICY_MASK) == TCB_FLAG_SCHED_SPORADIC)
{ {
DEBUGVERIFY(sched_sporadic_suspend(tcb)); 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 */