patch-2.4.6 linux/arch/mips/kernel/process.c
Next file: linux/arch/mips/kernel/ptrace.c
Previous file: linux/arch/mips/kernel/proc.c
Back to the patch index
Back to the overall index
- Lines: 97
- Date:
Mon Jul 2 13:56:40 2001
- Orig file:
v2.4.5/linux/arch/mips/kernel/process.c
- Orig date:
Fri Apr 13 20:26:07 2001
diff -u --recursive --new-file v2.4.5/linux/arch/mips/kernel/process.c linux/arch/mips/kernel/process.c
@@ -162,21 +162,21 @@
long retval;
__asm__ __volatile__(
- ".set\tnoreorder\n\t"
- "move\t$6,$sp\n\t"
- "move\t$4,%5\n\t"
- "li\t$2,%1\n\t"
- "syscall\n\t"
- "beq\t$6,$sp,1f\n\t"
- "subu\t$sp,32\n\t" /* delay slot */
- "jalr\t%4\n\t"
- "move\t$4,%3\n\t" /* delay slot */
- "move\t$4,$2\n\t"
- "li\t$2,%2\n\t"
- "syscall\n"
- "1:\taddiu\t$sp,32\n\t"
- "move\t%0,$2\n\t"
- ".set\treorder"
+ ".set noreorder \n"
+ " move $6,$sp \n"
+ " move $4,%5 \n"
+ " li $2,%1 \n"
+ " syscall \n"
+ " beq $6,$sp,1f \n"
+ " subu $sp,32 \n" /* delay slot */
+ " jalr %4 \n"
+ " move $4,%3 \n" /* delay slot */
+ " move $4,$2 \n"
+ " li $2,%2 \n"
+ " syscall \n"
+ "1: addiu $sp,32 \n"
+ " move %0,$2 \n"
+ ".set reorder"
:"=r" (retval)
:"i" (__NR_clone), "i" (__NR_exit),
"r" (arg), "r" (fn),
@@ -199,27 +199,47 @@
#define first_sched ((unsigned long) scheduling_functions_start_here)
#define last_sched ((unsigned long) scheduling_functions_end_here)
+/* get_wchan - a maintenance nightmare ... */
unsigned long get_wchan(struct task_struct *p)
{
- unsigned long schedule_frame;
- unsigned long pc;
+ unsigned long frame, 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) {
+ return pc;
}
+
+ if (pc >= (unsigned long) sleep_on_timeout)
+ goto schedule_timeout_caller;
+ if (pc >= (unsigned long) sleep_on)
+ goto schedule_caller;
+ if (pc >= (unsigned long) interruptible_sleep_on_timeout)
+ goto schedule_timeout_caller;
+ if (pc >= (unsigned long)interruptible_sleep_on)
+ goto schedule_caller;
+ goto schedule_timeout_caller;
+
+schedule_caller:
+ frame = ((unsigned long *)p->thread.reg30)[9];
+ pc = ((unsigned long *)frame)[11];
+ return pc;
+
+schedule_timeout_caller:
+ /* Must be schedule_timeout ... */
+ pc = ((unsigned long *)p->thread.reg30)[10];
+ frame = ((unsigned long *)p->thread.reg30)[9];
+
+ /* The schedule_timeout frame ... */
+ pc = ((unsigned long *)frame)[14];
+ frame = ((unsigned long *)frame)[13];
+
if (pc >= first_sched && pc < last_sched) {
- printk(KERN_DEBUG "Bug in %s\n", __FUNCTION__);
+ /* schedule_timeout called by interruptible_sleep_on_timeout */
+ pc = ((unsigned long *)frame)[11];
+ frame = ((unsigned long *)frame)[10];
}
return pc;
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)