pls help: Context Switching in Irix doesn't work

Jim Barton jmb at patton.wpd.sgi.com
Wed Feb 6 05:55:59 AEST 1991


I assure you, context switching works fine in Irix :-)

I assume that what your are porting is an application which does some
kind of non-preemptive tasking within a single process. These kind of
packages generally have two components to support context switching (and
then you need a scheduler on top of them).

First is a way to create a new stack for a thread of execution. This
code is usually written in assembler, since it must change the stack
pointer and create a new stack frame. When writing such code, a portion
of the original stack must be copied because you want to return to the
calling subroutine on the new stack. Clearly, you can never return from
that routine, so it becomes a new "main", if you will, for that thread.
The new stack area is usually statically allocated to some fixed size.
Irix stores the complete context of an interrupted process on top of
wherever the current stack pointer is pointing. It may be possible that
the stack area allocated is not big enough for the threads.

The second mechanism is setjmp/longjmp, which is used to switch tasks.
So, to create a new task, one might code the following:

#include <setjmp.h>

extern jmp_buf	scheduler;

threadmain(char *threadstack, jmp_buf newthread, int (*func)())
{
	newstack(threadstack);		<- running on passed stack area
	if (setjmp(newthread)) {
		(*func)();
		longjmp(scheduler, 1);
		/*NOTREACHED*/
	}
	oldstack(threadstack);
}

...

thescheduler() {
	setjmp(scheduler);
	/* ... pick a task to run ... */
	longjmp(somethread, 1);
	/*NOTREACHED*/
}

The following (working) stack switching code I produced some years ago:

# include <regdef.h>
# include <asm.h>

LEAF(newstack)
	addu	t5,a0,a1	# base of new stack
	li	t0,6		# save 5 words of stack, + old sp
	sll	t0,t0,2		# number of bytes
	subu	t2,t5,t0	# start for copy
	move	t0,t2		# save new sp 
	addu	t1,t0,sp	# copy end address
	move	t3,sp		# copy start address
	sw	sp,(t5)		# save old sp

loop:
	lw	t4,(t3)		# get a word
	addiu	t3,t3,4		# bump count
	sw	t4,(t2)		# store the word
	addiu	t2,t2,4		# and bump the destination count
	blt	t3,t1,loop	# do it again

	move	sp,t0		# set top of new stack
	move	fp,t0		# set new frame
	j	ra		# back to caller
END(newstack)

LEAF(oldstack)
	addu	t5,a0,a1	# base of new stack
	lw	sp,(t5)		# get back old sp
	move	fp,sp		# get back old frame
	j	ra		# back to caller
END(oldstack)


-- Jim Barton
   Silicon Graphics Computer Systems
   jmb at sgi.com



More information about the Comp.sys.sgi mailing list