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; }