Ejemplo n.º 1
0
void _Thread_Dispatch( void )
{
  ISR_Level        level;
  Per_CPU_Control *cpu_self;

  _ISR_Disable_without_giant( level );

  cpu_self = _Per_CPU_Get();

  if ( cpu_self->dispatch_necessary ) {
    _Profiling_Thread_dispatch_disable( cpu_self, 0 );
    cpu_self->thread_dispatch_disable_level = 1;
    _Thread_Do_dispatch( cpu_self, level );
  } else {
    _ISR_Enable_without_giant( level );
  }
}
Ejemplo n.º 2
0
void ppc_exc_wrapup(BSP_Exception_frame *frame)
{
  Per_CPU_Control *cpu_self;

  cpu_self = _Per_CPU_Get();

  if (cpu_self->isr_dispatch_disable) {
    return;
  }

  while (cpu_self->dispatch_necessary) {
    rtems_interrupt_level level;

    cpu_self->isr_dispatch_disable = 1;
    cpu_self->thread_dispatch_disable_level = 1;
    _Thread_Do_dispatch(cpu_self, frame->EXC_SRR1);
    rtems_interrupt_local_disable(level);
    (void) level;
    cpu_self = _Per_CPU_Get();
  }

  cpu_self->isr_dispatch_disable = 0;
}
Ejemplo n.º 3
0
void _Thread_Handler( void )
{
    Thread_Control  *executing;
    ISR_Level        level;
    Per_CPU_Control *cpu_self;

    /*
     * Some CPUs need to tinker with the call frame or registers when the
     * thread actually begins to execute for the first time.  This is a
     * hook point where the port gets a shot at doing whatever it requires.
     */
    _Context_Initialization_at_thread_begin();
    executing = _Thread_Executing;

    /*
     * have to put level into a register for those cpu's that use
     * inline asm here
     */
    level = executing->Start.isr_level;
    _ISR_Set_level( level );

    /*
     * Initialize the floating point context because we do not come
     * through _Thread_Dispatch on our first invocation. So the normal
     * code path for performing the FP context switch is not hit.
     */
    _Thread_Restore_fp( executing );

    /*
     * Do not use the level of the thread control block, since it has a
     * different format.
     */
    _ISR_Local_disable( level );

    /*
     *  At this point, the dispatch disable level BETTER be 1.
     */
    cpu_self = _Per_CPU_Get();
    _Assert( cpu_self->thread_dispatch_disable_level == 1 );

    /*
     * Make sure we lose no thread dispatch necessary update and execute the
     * post-switch actions.  As a side-effect change the thread dispatch level
     * from one to zero.  Do not use _Thread_Enable_dispatch() since there is no
     * valid thread dispatch necessary indicator in this context.
     */
    _Thread_Do_dispatch( cpu_self, level );

    /*
     * Invoke the thread begin extensions in the context of the thread entry
     * function with thread dispatching enabled.  This enables use of dynamic
     * memory allocation, creation of POSIX keys and use of C++ thread local
     * storage.  Blocking synchronization primitives are allowed also.
     */
    _User_extensions_Thread_begin( executing );

    /*
     *  RTEMS supports multiple APIs and each API can define a different
     *  thread/task prototype. The following code supports invoking the
     *  user thread entry point using the prototype expected.
     */
    ( *executing->Start.Entry.adaptor )( executing );

    /*
     *  In the call above, the return code from the user thread body which return
     *  something was placed in return_argument.  This assumed that if it
     *  returned anything (which is not supporting in all APIs), then it would be
     *  able to fit in a (void *).
     */

    _User_extensions_Thread_exitted( executing );

    _Internal_error( INTERNAL_ERROR_THREAD_EXITTED );
}