Interrupts must be disabled in all low level context switches
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@89 42af7a65-404d-4744-a932-0658087f49c3
This commit is contained in:
parent
5719b443ff
commit
50dcba1464
@ -76,26 +76,27 @@
|
|||||||
static void _up_dumponexit(FAR _TCB *tcb, FAR void *arg)
|
static void _up_dumponexit(FAR _TCB *tcb, FAR void *arg)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
dbg(" TCB=%p name=%s\n", tcb, tcb->name);
|
|
||||||
|
lldbg(" TCB=%p name=%s\n", tcb, tcb->argv[0]);
|
||||||
if (tcb->filelist)
|
if (tcb->filelist)
|
||||||
{
|
{
|
||||||
dbg(" filelist refcount=%d\n",
|
lldbg(" filelist refcount=%d\n",
|
||||||
tcb->filelist->fl_crefs);
|
tcb->filelist->fl_crefs);
|
||||||
|
|
||||||
for (i = 0; i < CONFIG_NFILE_DESCRIPTORS; i++)
|
for (i = 0; i < CONFIG_NFILE_DESCRIPTORS; i++)
|
||||||
{
|
{
|
||||||
struct inode *inode = tcb->filelist->fl_files[i].f_inode;
|
struct inode *inode = tcb->filelist->fl_files[i].f_inode;
|
||||||
if (inode)
|
if (inode)
|
||||||
{
|
{
|
||||||
dbg(" fd=%d refcount=%d\n",
|
lldbg(" fd=%d refcount=%d\n",
|
||||||
i, inode->i_crefs);
|
i, inode->i_crefs);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tcb->streams)
|
if (tcb->streams)
|
||||||
{
|
{
|
||||||
dbg(" streamlist refcount=%d\n",
|
lldbg(" streamlist refcount=%d\n",
|
||||||
tcb->streams->sl_crefs);
|
tcb->streams->sl_crefs);
|
||||||
|
|
||||||
for (i = 0; i < CONFIG_NFILE_STREAMS; i++)
|
for (i = 0; i < CONFIG_NFILE_STREAMS; i++)
|
||||||
@ -103,9 +104,9 @@ static void _up_dumponexit(FAR _TCB *tcb, FAR void *arg)
|
|||||||
struct file_struct *filep = &tcb->streams->sl_streams[i];
|
struct file_struct *filep = &tcb->streams->sl_streams[i];
|
||||||
if (filep->fs_filedes >= 0)
|
if (filep->fs_filedes >= 0)
|
||||||
{
|
{
|
||||||
dbg(" fd=%d nbytes=%d\n",
|
lldbg(" fd=%d nbytes=%d\n",
|
||||||
filep->fs_filedes,
|
filep->fs_filedes,
|
||||||
filep->fs_bufpos - filep->fs_bufstart);
|
filep->fs_bufpos - filep->fs_bufstart);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -128,11 +129,12 @@ static void _up_dumponexit(FAR _TCB *tcb, FAR void *arg)
|
|||||||
void _exit(int status)
|
void _exit(int status)
|
||||||
{
|
{
|
||||||
_TCB* tcb = (_TCB*)g_readytorun.head;
|
_TCB* tcb = (_TCB*)g_readytorun.head;
|
||||||
|
irqstate_t flags = irqsave();
|
||||||
|
|
||||||
dbg("TCB=%p exitting\n", tcb);
|
lldbg("TCB=%p exitting\n", tcb);
|
||||||
|
|
||||||
#if defined(CONFIG_DUMP_ON_EXIT) && defined(CONFIG_DEBUG)
|
#if defined(CONFIG_DUMP_ON_EXIT) && defined(CONFIG_DEBUG)
|
||||||
dbg("Other tasks:\n");
|
lldbg("Other tasks:\n");
|
||||||
sched_foreach(_up_dumponexit, NULL);
|
sched_foreach(_up_dumponexit, NULL);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -162,7 +164,7 @@ void _exit(int status)
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
tcb = (_TCB*)g_readytorun.head;
|
tcb = (_TCB*)g_readytorun.head;
|
||||||
dbg("New Active Task TCB=%p\n", tcb);
|
lldbg("New Active Task TCB=%p\n", tcb);
|
||||||
|
|
||||||
/* Then switch contexts */
|
/* Then switch contexts */
|
||||||
|
|
||||||
|
@ -76,7 +76,7 @@
|
|||||||
static void _up_dumponexit(FAR _TCB *tcb, FAR void *arg)
|
static void _up_dumponexit(FAR _TCB *tcb, FAR void *arg)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
dbg(" TCB=%p name=%s\n", tcb, tcb->name);
|
dbg(" TCB=%p name=%s\n", tcb, tcb->argv[0]);
|
||||||
if (tcb->filelist)
|
if (tcb->filelist)
|
||||||
{
|
{
|
||||||
dbg(" filelist refcount=%d\n",
|
dbg(" filelist refcount=%d\n",
|
||||||
@ -128,8 +128,9 @@ static void _up_dumponexit(FAR _TCB *tcb, FAR void *arg)
|
|||||||
void _exit(int status)
|
void _exit(int status)
|
||||||
{
|
{
|
||||||
_TCB* tcb = (_TCB*)g_readytorun.head;
|
_TCB* tcb = (_TCB*)g_readytorun.head;
|
||||||
|
irqstate_t flags = irqsave();
|
||||||
|
|
||||||
dbg("TCB=%p exitting\n", tcb);
|
lldbg("TCB=%p exitting\n", tcb);
|
||||||
|
|
||||||
#if defined(CONFIG_DUMP_ON_EXIT) && defined(CONFIG_DEBUG)
|
#if defined(CONFIG_DUMP_ON_EXIT) && defined(CONFIG_DEBUG)
|
||||||
dbg("Other tasks:\n");
|
dbg("Other tasks:\n");
|
||||||
@ -162,7 +163,7 @@ void _exit(int status)
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
tcb = (_TCB*)g_readytorun.head;
|
tcb = (_TCB*)g_readytorun.head;
|
||||||
dbg("New Active Task TCB=%p\n", tcb);
|
lldbg("New Active Task TCB=%p\n", tcb);
|
||||||
|
|
||||||
/* Then switch contexts */
|
/* Then switch contexts */
|
||||||
|
|
||||||
|
@ -41,6 +41,7 @@
|
|||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sched.h>
|
#include <sched.h>
|
||||||
#include <debug.h>
|
#include <debug.h>
|
||||||
|
#include <8052.h>
|
||||||
#include <nuttx/arch.h>
|
#include <nuttx/arch.h>
|
||||||
#include "os_internal.h"
|
#include "os_internal.h"
|
||||||
#include "up_internal.h"
|
#include "up_internal.h"
|
||||||
@ -76,6 +77,12 @@ void _exit(int status)
|
|||||||
|
|
||||||
dbg("TCB=%p exitting\n", tcb);
|
dbg("TCB=%p exitting\n", tcb);
|
||||||
|
|
||||||
|
/* Disable interrupts. Interrupts will remain disabled until
|
||||||
|
* the new task is resumed below when the save IE is restored.
|
||||||
|
*/
|
||||||
|
|
||||||
|
EA = 0;
|
||||||
|
|
||||||
/* Remove the tcb task from the ready-to-run list. We can
|
/* Remove the tcb task from the ready-to-run list. We can
|
||||||
* ignore the return value because we know that a context
|
* ignore the return value because we know that a context
|
||||||
* switch is needed.
|
* switch is needed.
|
||||||
|
@ -200,6 +200,10 @@ EXTERN void up_release_stack(FAR _TCB *dtcb);
|
|||||||
* but has been prepped to execute. Move the TCB to the
|
* but has been prepped to execute. Move the TCB to the
|
||||||
* ready-to-run list, restore its context, and start execution.
|
* ready-to-run list, restore its context, and start execution.
|
||||||
*
|
*
|
||||||
|
* This function is called only from the NuttX scheduling
|
||||||
|
* logic. Interrupts will always be disabled when this
|
||||||
|
* function is called.
|
||||||
|
*
|
||||||
* Inputs:
|
* Inputs:
|
||||||
* tcb: Refers to the tcb to be unblocked. This tcb is
|
* tcb: Refers to the tcb to be unblocked. This tcb is
|
||||||
* in one of the waiting tasks lists. It must be moved to
|
* in one of the waiting tasks lists. It must be moved to
|
||||||
@ -218,6 +222,10 @@ EXTERN void up_unblock_task(FAR _TCB *tcb);
|
|||||||
* the ready to run list must be stopped. Save its context
|
* the ready to run list must be stopped. Save its context
|
||||||
* and move it to the inactive list specified by task_state.
|
* and move it to the inactive list specified by task_state.
|
||||||
*
|
*
|
||||||
|
* This function is called only from the NuttX scheduling
|
||||||
|
* logic. Interrupts will always be disabled when this
|
||||||
|
* function is called.
|
||||||
|
*
|
||||||
* Inputs:
|
* Inputs:
|
||||||
* tcb: Refers to a task in the ready-to-run list (normally
|
* tcb: Refers to a task in the ready-to-run list (normally
|
||||||
* the task at the the head of the list). It most be
|
* the task at the the head of the list). It most be
|
||||||
@ -241,6 +249,10 @@ EXTERN void up_block_task(FAR _TCB *tcb, tstate_t task_state);
|
|||||||
* context switch if a new task is placed at the head of
|
* context switch if a new task is placed at the head of
|
||||||
* the ready to run list.
|
* the ready to run list.
|
||||||
*
|
*
|
||||||
|
* This function is called only from the NuttX scheduling
|
||||||
|
* logic. Interrupts will always be disabled when this
|
||||||
|
* function is called.
|
||||||
|
*
|
||||||
************************************************************/
|
************************************************************/
|
||||||
|
|
||||||
EXTERN void up_release_pending(void);
|
EXTERN void up_release_pending(void);
|
||||||
@ -259,6 +271,10 @@ EXTERN void up_release_pending(void);
|
|||||||
* the priority of the current, running task and it now has the
|
* the priority of the current, running task and it now has the
|
||||||
* priority.
|
* priority.
|
||||||
*
|
*
|
||||||
|
* This function is called only from the NuttX scheduling
|
||||||
|
* logic. Interrupts will always be disabled when this
|
||||||
|
* function is called.
|
||||||
|
*
|
||||||
* Inputs:
|
* Inputs:
|
||||||
* tcb: The TCB of the task that has been reprioritized
|
* tcb: The TCB of the task that has been reprioritized
|
||||||
* priority: The new task priority
|
* priority: The new task priority
|
||||||
@ -274,6 +290,11 @@ EXTERN void up_reprioritize_rtr(FAR _TCB *tcb, ubyte priority);
|
|||||||
* This function causes the currently executing task to cease
|
* This function causes the currently executing task to cease
|
||||||
* to exist. This is a special case of task_delete().
|
* to exist. This is a special case of task_delete().
|
||||||
*
|
*
|
||||||
|
* Unlike other UP APIs, this function may be called
|
||||||
|
* directly from user programs in various states. The
|
||||||
|
* implementation of this function should diable interrupts
|
||||||
|
* before performing scheduling operations.
|
||||||
|
*
|
||||||
************************************************************/
|
************************************************************/
|
||||||
/* Prototype is in unistd.h */
|
/* Prototype is in unistd.h */
|
||||||
|
|
||||||
|
@ -175,7 +175,9 @@ int sched_setparam(pid_t pid, const struct sched_param *param)
|
|||||||
{
|
{
|
||||||
/* A context switch will occur. */
|
/* A context switch will occur. */
|
||||||
|
|
||||||
|
irqstate_t flags = irqsave();
|
||||||
up_reprioritize_rtr(tcb, (ubyte)sched_priority);
|
up_reprioritize_rtr(tcb, (ubyte)sched_priority);
|
||||||
|
irqrestore(flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Otherwise, we can just change priority since it has no effect */
|
/* Otherwise, we can just change priority since it has no effect */
|
||||||
@ -202,7 +204,9 @@ int sched_setparam(pid_t pid, const struct sched_param *param)
|
|||||||
{
|
{
|
||||||
/* A context switch will occur. */
|
/* A context switch will occur. */
|
||||||
|
|
||||||
|
irqstate_t flags = irqsave();
|
||||||
up_reprioritize_rtr(tcb, (ubyte)sched_priority);
|
up_reprioritize_rtr(tcb, (ubyte)sched_priority);
|
||||||
|
irqrestore(flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Otherwise, we can just change priority and re-schedule (since it
|
/* Otherwise, we can just change priority and re-schedule (since it
|
||||||
|
@ -93,6 +93,10 @@ STATUS sched_unlock(void)
|
|||||||
|
|
||||||
if (rtcb && !up_interrupt_context())
|
if (rtcb && !up_interrupt_context())
|
||||||
{
|
{
|
||||||
|
/* Prevent context switches throughout the following */
|
||||||
|
|
||||||
|
irqstate_t flags = irqsave();
|
||||||
|
|
||||||
/* Decrement the preemption lock counter */
|
/* Decrement the preemption lock counter */
|
||||||
|
|
||||||
if (rtcb->lockcount)
|
if (rtcb->lockcount)
|
||||||
@ -117,6 +121,7 @@ STATUS sched_unlock(void)
|
|||||||
up_release_pending();
|
up_release_pending();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
irqrestore(flags);
|
||||||
}
|
}
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
@ -90,9 +90,10 @@
|
|||||||
|
|
||||||
STATUS task_activate(FAR _TCB *tcb)
|
STATUS task_activate(FAR _TCB *tcb)
|
||||||
{
|
{
|
||||||
#ifdef CONFIG_SCHED_INSTRUMENTATION
|
|
||||||
irqstate_t flags = irqsave();
|
irqstate_t flags = irqsave();
|
||||||
|
|
||||||
|
#ifdef CONFIG_SCHED_INSTRUMENTATION
|
||||||
|
|
||||||
/* Check if this is really a re-start */
|
/* Check if this is really a re-start */
|
||||||
|
|
||||||
if (tcb->task_state != TSTATE_TASK_INACTIVE)
|
if (tcb->task_state != TSTATE_TASK_INACTIVE)
|
||||||
@ -109,9 +110,9 @@ STATUS task_activate(FAR _TCB *tcb)
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
sched_note_start(tcb);
|
sched_note_start(tcb);
|
||||||
irqrestore(flags);
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
up_unblock_task(tcb);
|
up_unblock_task(tcb);
|
||||||
|
irqrestore(flags);
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user