how to suspend current running thread from within exception level handler

Hill, Jeffrey O johill at lanl.gov
Tue May 1 19:08:32 UTC 2012


Hi,

I am writing a last chance RTEMS exception handler function for the nios2 processor. In this function I attempt to suspend the current running thread, and switch to the next runable thread. Here is the (probably naïve) code I tried to write to accomplish that aim, but I don't know if it's even close to correct. Any comments from the gurus? 

        if ( !_States_Is_suspended ( _Thread_Executing->current_state ) ) {
            _Thread_Suspend ( _Thread_Executing );
            /*
             * we cant call _Thread_Dispatch here because interrupts
             * are currently disabled
             */
#if 0
            if ( !_Thread_Dispatch_in_critical_section() ) {
                _CPU_ISR_Enable( isrCookie );
                _Thread_Dispatch();
                _CPU_ISR_Disable( isrCookie );
            }
#endif
        }

Attached is also the current state of the (somewhat) complete last chance exception handler for context. When I attach with the debugger after the fault has already occurred I don't appear to see the faulting thread in the thread list whereas I can at least sometimes see the faulting thread if the debugger is already attached when the exception happens (in that situation my last chance exception handler doesn't run).

Thanks for your help,

Jeff

static void __Exception_Handler_Last_Resort ( uint32_t cause, CPU_Exception_frame * pefr )
{
    printk ( "\n" );
    printk ( "\07" ); /* ding */
    printk (
        "**** Unexpected nios2 \"%s\" exception\07\n",
        _Nios2_Exception_Cause_Name ( cause ) );
    static const char * const pCloseMsg =
        "*****************************************************************\n";
    if ( _ISR_Is_in_progress () ) {
        printk (
        "**** Executing in an interrupt service routine, halting processor\n" );
        printk ( pCloseMsg );
        _CPU_Fatal_halt(0xECC0);
    }
    else if ( _Thread_Executing ) {
        char threadName[32]; /* maybe only needs to be 4 characters */
        const char * pName;
        {
            uint32_t isrCookie;
            _CPU_ISR_Disable( isrCookie );
            pName = _Objects_Get_name_as_string (
                                _Thread_Executing->Object.id,
                                sizeof ( threadName ), threadName );
            _CPU_ISR_Enable( isrCookie );
        }
        if ( ! pName ) {
            pName = "anonymous";
        }
        printk ( "**** Suspending thread \"%s\"\n", pName );
        printk ( pCloseMsg );
        /*
         * I am operating under the assumption that interrupts are locked
         * out while the exception handler is running so this code would
         * need to change if that situation changes.
         */
        if ( !_States_Is_suspended ( _Thread_Executing->current_state ) ) {
            _Thread_Suspend ( _Thread_Executing );
            /*
             * we cant call _Thread_Dispatch here because interrupts
             * are currently disabled
             */
#if 0
            if ( !_Thread_Dispatch_in_critical_section() ) {
                _CPU_ISR_Enable( isrCookie );
                _Thread_Dispatch();
                _CPU_ISR_Disable( isrCookie );
            }
#endif
        }
    }
    else {
        printk ( "**** Multitasking hasn't started, halting processor\n" );
        printk ( pCloseMsg );
        _CPU_Fatal_halt(0xECC0);
    }
}




More information about the users mailing list