Listing 4. Context Switch Function
void _DSP_K_SWITCH( t__DSP_K_TSKID const new_task )
{
volatile t__DSP_K_tcb *tsk; /* context stack */
volatile t__DSP_K_TSKID next = new_task;
/* if task lock on then exit switcher */
asm( "bit tst ustat2 0x4;" );
asm( "if tf jump( pc, switchend );" );
/* switch to same task? */
if( next != __DSP_K_context.current )
{
/*
* perform context switch
*/
tsk = &__DSP_K_context.tasks
[ __DSP_K_context.current ];
/* no save if deleted */
if( tsk->state != DSP_K_STATE_NULL )
{
/* is current thread pended? */
if( tsk->state == DSP_K_STATE_RUN )
{
/* return it to ready state */
tsk->state = DSP_K_STATE_READY;
}
/* push current thread context */
/* ...assembler detail omitted... */
}
__DSP_K_context.current = next;
__DSP_K_context.tasks[ next ].state =
DSP_K_STATE_RUN;
/* pop next context */
/* ...assembler detail omitted... */
/* set up a C stack frame and run next task */
/* ...assembler detail omitted... */
/* jump onto new task frame */
asm( "i12=dm( m7,i6 );" );
/* out ISR and no schedule pending */
asm( "bit clr ustat2 0x48;" );
__DSP_K_OUT_KERNEL;
asm( "jump( m14,i12 )(db);" );
/* preserve i12 (see dsp_K.asm) */
asm( "i12=dm( m6,i7 );" );
asm( "rframe;" );
}
else
{
__DSP_K_OUT_KERNEL;
}
asm( "switchend:" );
return;
}