mirror of
https://github.com/apache/nuttx.git
synced 2026-05-31 23:40:19 +08:00
sched/sched_foreach.c: sched_foreach() should not have to hold the critical section over the entire traversal. It should be acceptable to simply only the critical section while one entry is being processed (the caller can always call sched_foreach within a critical section is greater stability is needed. sched/sched_gettcb.c: Recent changes removed critical sections around calls to sched_gettcb.c. However, there is a very should sequence of instructions that actually does require the critical section. That short sequence no manages its own critical section.
This commit is contained in:
+17
-10
@@ -1,7 +1,7 @@
|
|||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* sched/sched/sched_foreach.c
|
* sched/sched/sched_foreach.c
|
||||||
*
|
*
|
||||||
* Copyright (C) 2007, 2009, 2016 Gregory Nutt. All rights reserved.
|
* Copyright (C) 2007, 2009, 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
|
||||||
@@ -51,9 +51,15 @@
|
|||||||
* Name: sched_foreach
|
* Name: sched_foreach
|
||||||
*
|
*
|
||||||
* Description:
|
* Description:
|
||||||
* Enumerate over each task and provide the TCB of each
|
* Enumerate over each task and provide the TCB of each task to a user
|
||||||
* task to a user callback functions. Interrupts will be
|
* callback functions.
|
||||||
* disabled throughout this enumeration!
|
*
|
||||||
|
* NOTE: This function examines the TCB and calls each handler within a
|
||||||
|
* critical section. However, that critical section is released and
|
||||||
|
* reacquired for each TCB. When it is released, there may be changes in
|
||||||
|
* tasking. If the caller requires absolute stability through the
|
||||||
|
* traversal, then the caller should establish the critical section BEFORE
|
||||||
|
* calling this function.
|
||||||
*
|
*
|
||||||
* Input Parameters:
|
* Input Parameters:
|
||||||
* handler - The function to be called with the TCB of
|
* handler - The function to be called with the TCB of
|
||||||
@@ -62,26 +68,27 @@
|
|||||||
* Returned Value:
|
* Returned Value:
|
||||||
* None
|
* None
|
||||||
*
|
*
|
||||||
* Assumptions:
|
|
||||||
*
|
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
void sched_foreach(sched_foreach_t handler, FAR void *arg)
|
void sched_foreach(sched_foreach_t handler, FAR void *arg)
|
||||||
{
|
{
|
||||||
irqstate_t flags = enter_critical_section();
|
irqstate_t flags;
|
||||||
int ndx;
|
int ndx;
|
||||||
|
|
||||||
/* Vist each active task */
|
/* Visit each active task */
|
||||||
|
|
||||||
for (ndx = 0; ndx < CONFIG_MAX_TASKS; ndx++)
|
for (ndx = 0; ndx < CONFIG_MAX_TASKS; ndx++)
|
||||||
{
|
{
|
||||||
|
/* This test and the function call must be atomic */
|
||||||
|
|
||||||
|
flags = enter_critical_section();
|
||||||
if (g_pidhash[ndx].tcb)
|
if (g_pidhash[ndx].tcb)
|
||||||
{
|
{
|
||||||
handler(g_pidhash[ndx].tcb, arg);
|
handler(g_pidhash[ndx].tcb, arg);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
leave_critical_section(flags);
|
leave_critical_section(flags);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* sched/sched/sched_gettcb.c
|
* sched/sched/sched_gettcb.c
|
||||||
*
|
*
|
||||||
* Copyright (C) 2007, 2009, 2011 Gregory Nutt. All rights reserved.
|
* Copyright (C) 2007, 2009, 2011, 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
|
||||||
@@ -41,6 +41,8 @@
|
|||||||
|
|
||||||
#include <sched.h>
|
#include <sched.h>
|
||||||
|
|
||||||
|
#include "nuttx/irq.h"
|
||||||
|
|
||||||
#include "sched/sched.h"
|
#include "sched/sched.h"
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
@@ -51,15 +53,22 @@
|
|||||||
* Name: sched_gettcb
|
* Name: sched_gettcb
|
||||||
*
|
*
|
||||||
* Description:
|
* Description:
|
||||||
* Given a task ID, this function will return
|
* Given a task ID, this function will return the a pointer to the
|
||||||
* the a pointer to the corresponding TCB (or NULL if there
|
* corresponding TCB (or NULL if there is no such task ID).
|
||||||
* is no such task ID).
|
*
|
||||||
|
* NOTE: This function holds a critical section while examining TCB data
|
||||||
|
* data structures but releases that critical section before returning.
|
||||||
|
* When it is released, the TCB may become unstable. If the caller
|
||||||
|
* requires absolute stability while using the TCB, then the caller
|
||||||
|
* should establish the critical section BEFORE calling this function and
|
||||||
|
* hold that critical section as long as necessary.
|
||||||
*
|
*
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
FAR struct tcb_s *sched_gettcb(pid_t pid)
|
FAR struct tcb_s *sched_gettcb(pid_t pid)
|
||||||
{
|
{
|
||||||
FAR struct tcb_s *ret = NULL;
|
FAR struct tcb_s *ret = NULL;
|
||||||
|
irqstate_t flags;
|
||||||
int hash_ndx;
|
int hash_ndx;
|
||||||
|
|
||||||
/* Verify that the PID is within range */
|
/* Verify that the PID is within range */
|
||||||
@@ -70,6 +79,14 @@ FAR struct tcb_s *sched_gettcb(pid_t pid)
|
|||||||
|
|
||||||
hash_ndx = PIDHASH(pid);
|
hash_ndx = PIDHASH(pid);
|
||||||
|
|
||||||
|
/* The test and the return setup should be atomic. This still does
|
||||||
|
* not provide proper protection if the recipient of the TCB does not
|
||||||
|
* also protect against the task associated with the TCB from
|
||||||
|
* terminating asynchronously.
|
||||||
|
*/
|
||||||
|
|
||||||
|
flags = spin_lock_irqsave();
|
||||||
|
|
||||||
/* Verify that the correct TCB was found. */
|
/* Verify that the correct TCB was found. */
|
||||||
|
|
||||||
if (pid == g_pidhash[hash_ndx].pid)
|
if (pid == g_pidhash[hash_ndx].pid)
|
||||||
@@ -78,6 +95,8 @@ FAR struct tcb_s *sched_gettcb(pid_t pid)
|
|||||||
|
|
||||||
ret = g_pidhash[hash_ndx].tcb;
|
ret = g_pidhash[hash_ndx].tcb;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
spin_unlock_irqsave();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Return the TCB. */
|
/* Return the TCB. */
|
||||||
|
|||||||
Reference in New Issue
Block a user