summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2007-03-19 14:22:43 +0000
committerpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2007-03-19 14:22:43 +0000
commitbf14d0a7cfb1c59f692cd24d9e97699b01e103b4 (patch)
treec94333bd8c43f9af9dcf280bf2eb76e1cf071765
parent35aaf2d6d6776ea47729eb80efb15e04671ab316 (diff)
downloadnuttx-bf14d0a7cfb1c59f692cd24d9e97699b01e103b4.tar.gz
nuttx-bf14d0a7cfb1c59f692cd24d9e97699b01e103b4.tar.bz2
nuttx-bf14d0a7cfb1c59f692cd24d9e97699b01e103b4.zip
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
-rw-r--r--nuttx/arch/c5471/src/up_exit.c26
-rw-r--r--nuttx/arch/dm320/src/up_exit.c7
-rw-r--r--nuttx/arch/pjrc-8051/src/up_exit.c7
-rw-r--r--nuttx/include/nuttx/arch.h21
-rw-r--r--nuttx/sched/sched_setparam.c4
-rw-r--r--nuttx/sched/sched_unlock.c5
-rw-r--r--nuttx/sched/task_activate.c5
7 files changed, 58 insertions, 17 deletions
diff --git a/nuttx/arch/c5471/src/up_exit.c b/nuttx/arch/c5471/src/up_exit.c
index 606ea097b..c6f544776 100644
--- a/nuttx/arch/c5471/src/up_exit.c
+++ b/nuttx/arch/c5471/src/up_exit.c
@@ -76,26 +76,27 @@
static void _up_dumponexit(FAR _TCB *tcb, FAR void *arg)
{
int i;
- dbg(" TCB=%p name=%s\n", tcb, tcb->name);
+
+ lldbg(" TCB=%p name=%s\n", tcb, tcb->argv[0]);
if (tcb->filelist)
{
- dbg(" filelist refcount=%d\n",
- tcb->filelist->fl_crefs);
+ lldbg(" filelist refcount=%d\n",
+ tcb->filelist->fl_crefs);
for (i = 0; i < CONFIG_NFILE_DESCRIPTORS; i++)
{
struct inode *inode = tcb->filelist->fl_files[i].f_inode;
if (inode)
{
- dbg(" fd=%d refcount=%d\n",
- i, inode->i_crefs);
+ lldbg(" fd=%d refcount=%d\n",
+ i, inode->i_crefs);
}
}
}
if (tcb->streams)
{
- dbg(" streamlist refcount=%d\n",
+ lldbg(" streamlist refcount=%d\n",
tcb->streams->sl_crefs);
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];
if (filep->fs_filedes >= 0)
{
- dbg(" fd=%d nbytes=%d\n",
- filep->fs_filedes,
- filep->fs_bufpos - filep->fs_bufstart);
+ lldbg(" fd=%d nbytes=%d\n",
+ filep->fs_filedes,
+ filep->fs_bufpos - filep->fs_bufstart);
}
}
}
@@ -128,11 +129,12 @@ static void _up_dumponexit(FAR _TCB *tcb, FAR void *arg)
void _exit(int status)
{
_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)
- dbg("Other tasks:\n");
+ lldbg("Other tasks:\n");
sched_foreach(_up_dumponexit, NULL);
#endif
@@ -162,7 +164,7 @@ void _exit(int status)
*/
tcb = (_TCB*)g_readytorun.head;
- dbg("New Active Task TCB=%p\n", tcb);
+ lldbg("New Active Task TCB=%p\n", tcb);
/* Then switch contexts */
diff --git a/nuttx/arch/dm320/src/up_exit.c b/nuttx/arch/dm320/src/up_exit.c
index 606ea097b..b96d5f824 100644
--- a/nuttx/arch/dm320/src/up_exit.c
+++ b/nuttx/arch/dm320/src/up_exit.c
@@ -76,7 +76,7 @@
static void _up_dumponexit(FAR _TCB *tcb, FAR void *arg)
{
int i;
- dbg(" TCB=%p name=%s\n", tcb, tcb->name);
+ dbg(" TCB=%p name=%s\n", tcb, tcb->argv[0]);
if (tcb->filelist)
{
dbg(" filelist refcount=%d\n",
@@ -128,8 +128,9 @@ static void _up_dumponexit(FAR _TCB *tcb, FAR void *arg)
void _exit(int status)
{
_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)
dbg("Other tasks:\n");
@@ -162,7 +163,7 @@ void _exit(int status)
*/
tcb = (_TCB*)g_readytorun.head;
- dbg("New Active Task TCB=%p\n", tcb);
+ lldbg("New Active Task TCB=%p\n", tcb);
/* Then switch contexts */
diff --git a/nuttx/arch/pjrc-8051/src/up_exit.c b/nuttx/arch/pjrc-8051/src/up_exit.c
index 5a98496a6..a9b641bab 100644
--- a/nuttx/arch/pjrc-8051/src/up_exit.c
+++ b/nuttx/arch/pjrc-8051/src/up_exit.c
@@ -41,6 +41,7 @@
#include <sys/types.h>
#include <sched.h>
#include <debug.h>
+#include <8052.h>
#include <nuttx/arch.h>
#include "os_internal.h"
#include "up_internal.h"
@@ -76,6 +77,12 @@ void _exit(int status)
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
* ignore the return value because we know that a context
* switch is needed.
diff --git a/nuttx/include/nuttx/arch.h b/nuttx/include/nuttx/arch.h
index a243a3f6a..163f30eda 100644
--- a/nuttx/include/nuttx/arch.h
+++ b/nuttx/include/nuttx/arch.h
@@ -200,6 +200,10 @@ EXTERN void up_release_stack(FAR _TCB *dtcb);
* but has been prepped to execute. Move the TCB to the
* 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:
* tcb: Refers to the tcb to be unblocked. This tcb is
* 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
* 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:
* tcb: Refers to a task in the ready-to-run list (normally
* 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
* 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);
@@ -259,6 +271,10 @@ EXTERN void up_release_pending(void);
* the priority of the current, running task and it now has the
* priority.
*
+ * This function is called only from the NuttX scheduling
+ * logic. Interrupts will always be disabled when this
+ * function is called.
+ *
* Inputs:
* tcb: The TCB of the task that has been reprioritized
* 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
* 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 */
diff --git a/nuttx/sched/sched_setparam.c b/nuttx/sched/sched_setparam.c
index c9a935a4d..52389ae49 100644
--- a/nuttx/sched/sched_setparam.c
+++ b/nuttx/sched/sched_setparam.c
@@ -175,7 +175,9 @@ int sched_setparam(pid_t pid, const struct sched_param *param)
{
/* A context switch will occur. */
+ irqstate_t flags = irqsave();
up_reprioritize_rtr(tcb, (ubyte)sched_priority);
+ irqrestore(flags);
}
/* 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. */
+ irqstate_t flags = irqsave();
up_reprioritize_rtr(tcb, (ubyte)sched_priority);
+ irqrestore(flags);
}
/* Otherwise, we can just change priority and re-schedule (since it
diff --git a/nuttx/sched/sched_unlock.c b/nuttx/sched/sched_unlock.c
index 773b3dd71..073f5e31f 100644
--- a/nuttx/sched/sched_unlock.c
+++ b/nuttx/sched/sched_unlock.c
@@ -93,6 +93,10 @@ STATUS sched_unlock(void)
if (rtcb && !up_interrupt_context())
{
+ /* Prevent context switches throughout the following */
+
+ irqstate_t flags = irqsave();
+
/* Decrement the preemption lock counter */
if (rtcb->lockcount)
@@ -117,6 +121,7 @@ STATUS sched_unlock(void)
up_release_pending();
}
}
+ irqrestore(flags);
}
return OK;
}
diff --git a/nuttx/sched/task_activate.c b/nuttx/sched/task_activate.c
index ce574428a..b216cc316 100644
--- a/nuttx/sched/task_activate.c
+++ b/nuttx/sched/task_activate.c
@@ -90,9 +90,10 @@
STATUS task_activate(FAR _TCB *tcb)
{
-#ifdef CONFIG_SCHED_INSTRUMENTATION
irqstate_t flags = irqsave();
+#ifdef CONFIG_SCHED_INSTRUMENTATION
+
/* Check if this is really a re-start */
if (tcb->task_state != TSTATE_TASK_INACTIVE)
@@ -109,9 +110,9 @@ STATUS task_activate(FAR _TCB *tcb)
*/
sched_note_start(tcb);
- irqrestore(flags);
#endif
up_unblock_task(tcb);
+ irqrestore(flags);
return OK;
}