diff options
author | patacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3> | 2007-03-19 14:22:43 +0000 |
---|---|---|
committer | patacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3> | 2007-03-19 14:22:43 +0000 |
commit | bf14d0a7cfb1c59f692cd24d9e97699b01e103b4 (patch) | |
tree | c94333bd8c43f9af9dcf280bf2eb76e1cf071765 /nuttx | |
parent | 35aaf2d6d6776ea47729eb80efb15e04671ab316 (diff) | |
download | px4-nuttx-bf14d0a7cfb1c59f692cd24d9e97699b01e103b4.tar.gz px4-nuttx-bf14d0a7cfb1c59f692cd24d9e97699b01e103b4.tar.bz2 px4-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
Diffstat (limited to 'nuttx')
-rw-r--r-- | nuttx/arch/c5471/src/up_exit.c | 26 | ||||
-rw-r--r-- | nuttx/arch/dm320/src/up_exit.c | 7 | ||||
-rw-r--r-- | nuttx/arch/pjrc-8051/src/up_exit.c | 7 | ||||
-rw-r--r-- | nuttx/include/nuttx/arch.h | 21 | ||||
-rw-r--r-- | nuttx/sched/sched_setparam.c | 4 | ||||
-rw-r--r-- | nuttx/sched/sched_unlock.c | 5 | ||||
-rw-r--r-- | nuttx/sched/task_activate.c | 5 |
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; } |