diff options
Diffstat (limited to 'arch/mips/kernel/process.c')
-rw-r--r-- | arch/mips/kernel/process.c | 36 |
1 files changed, 35 insertions, 1 deletions
diff --git a/arch/mips/kernel/process.c b/arch/mips/kernel/process.c index f0c346b61..959e7b339 100644 --- a/arch/mips/kernel/process.c +++ b/arch/mips/kernel/process.c @@ -1,4 +1,4 @@ -/* $Id: process.c,v 1.16 1999/10/09 00:00:58 ralf Exp $ +/* $Id: process.c,v 1.17 1999/12/04 03:59:00 ralf Exp $ * * This file is subject to the terms and conditions of the GNU General Public * License. See the file "COPYING" in the main directory of this archive @@ -186,3 +186,37 @@ int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags) return retval; } + +/* + * These bracket the sleeping functions.. + */ +extern void scheduling_functions_start_here(void); +extern void scheduling_functions_end_here(void); +#define first_sched ((unsigned long) scheduling_functions_start_here) +#define last_sched ((unsigned long) scheduling_functions_end_here) + +unsigned long get_wchan(struct task_struct *p) +{ + unsigned long schedule_frame; + unsigned long pc; + + if (!p || p == current || p->state == TASK_RUNNING) + return 0; + + pc = thread_saved_pc(&p->thread); + if (pc == (unsigned long) interruptible_sleep_on + || pc == (unsigned long) sleep_on) { + schedule_frame = ((unsigned long *)p->thread.reg30)[9]; + return ((unsigned long *)schedule_frame)[15]; + } + if (pc == (unsigned long) interruptible_sleep_on_timeout + || pc == (unsigned long) sleep_on_timeout) { + schedule_frame = ((unsigned long *)p->thread.reg30)[9]; + return ((unsigned long *)schedule_frame)[16]; + } + if (pc >= first_sched && pc < last_sched) { + printk(KERN_DEBUG "Bug in %s\n", __FUNCTION__); + } + + return pc; +} |