[PATCH 2/2] score: Implement forced thread migration

Sebastian Huber sebastian.huber at embedded-brains.de
Fri May 2 16:56:49 UTC 2014


On 05/02/2014 06:23 PM, Gedare Bloom wrote:
> On Fri, May 2, 2014 at 7:39 AM, Sebastian Huber
> <sebastian.huber at embedded-brains.de>  wrote:
>> >The current implementation of task migration in RTEMS has some
>> >implications with respect to the interrupt latency. It is crucial to
>> >preserve the system invariant that a task can execute on at most one
>> >processor in the system at a time. This is accomplished with a boolean
>> >indicator in the task context. The processor architecture specific
>> >low-level task context switch code will mark that a task context is no
>> >longer executing and waits that the heir context stopped execution
>> >before it restores the heir context and resumes execution of the heir
>> >task. So there is one point in time in which a processor is without a
>> >task. This is essential to avoid cyclic dependencies in case multiple
>> >tasks migrate at once. Otherwise some supervising entity is necessary to
>> >prevent life-locks. Such a global supervisor would lead to scalability
>> >problems so this approach is not used. Currently the thread dispatch is
>> >performed with interrupts disabled. So in case the heir task is
>> >currently executing on another processor then this prolongs the time of
>> >disabled interrupts since one processor has to wait for another
>> >processor to make progress.
>> >
>> >It is difficult to avoid this issue with the interrupt latency since
>> >interrupts normally store the context of the interrupted task on its
>> >stack. In case a task is marked as not executing we must not use its
>> >task stack to store such an interrupt context. We cannot use the heir
>> >stack before it stopped execution on another processor. So if we enable
>> >interrupts during this transition we have to provide an alternative task
>> >independent stack for this time frame. This issue needs further
>> >investigation.
> Thanks for the good explanation. Is the problem of using the
> non-executing task's stack that the task might get resumed on some
> other processor whlie the interrupt is running?

Yes, as soon as you set is_executing to false it may start execution on 
another processor.

> When you say "cannot
> use the heir stack" do you mean cannot use it on the "idle" processor
> because the heir is executing on some oher processor where the heir
> should be getting blocked soon?

Yes, exactly, the heir may currently execute on another processor. On 
this other processor it must have an heir thread and a thread dispatch 
must be pending.

For example lets have a look at  _Scheduler_Set() and assume that 
the_thread is the currently executing thread:

RTEMS_INLINE_ROUTINE void _Scheduler_Set(
   const Scheduler_Control *scheduler,
   Thread_Control          *the_thread
)
{
   const Scheduler_Control *current_scheduler = _Scheduler_Get( 
the_thread );

   if ( current_scheduler != scheduler ) {
     _Thread_Set_state( the_thread, STATES_MIGRATING );

    <-- here we are still executing on this processor (thread 
dispatching is disabled), but we have an heir for this processor

     _Scheduler_Free( _Scheduler_Get( the_thread ), the_thread );
     the_thread->scheduler = scheduler;
     _Scheduler_Allocate( scheduler, the_thread );
     _Scheduler_Update( scheduler, the_thread );
     _Thread_Clear_state( the_thread, STATES_MIGRATING );

    <-- here we are still executing on this processor (thread 
dispatching is still disabled) and we may be an heir on another 
processor which just received an inter-processor interrupt

   }
}

<-- high level code will eventually call _Thread_Dispatch() and we 
finish the migration

>
>> >---
>> >  c/src/lib/libbsp/sparc/shared/irq_asm.S            |   18 ++
>> >  c/src/lib/libcpu/powerpc/new-exceptions/cpu.c      |    4 +
>> >  c/src/lib/libcpu/powerpc/new-exceptions/cpu_asm.S  |   18 ++
>> >  cpukit/libmisc/cpuuse/cpuusagereport.c             |    2 +-
>> >  cpukit/rtems/include/rtems/rtems/tasks.h           |    2 -
>> >  cpukit/rtems/src/tasksetscheduler.c                |    5 +-
>> >  cpukit/score/cpu/arm/cpu.c                         |   12 +
>> >  cpukit/score/cpu/arm/cpu_asm.S                     |   18 ++
>> >  cpukit/score/cpu/arm/rtems/score/cpu.h             |   16 ++
>> >  cpukit/score/cpu/i386/cpu.c                        |   18 ++
>> >  cpukit/score/cpu/i386/cpu_asm.S                    |   29 ++-
>> >  cpukit/score/cpu/i386/rtems/score/cpu.h            |   27 ++
>> >  cpukit/score/cpu/no_cpu/rtems/score/cpu.h          |   18 ++
>> >  cpukit/score/cpu/powerpc/cpu.c                     |    4 +
>> >  cpukit/score/cpu/powerpc/rtems/score/cpu.h         |   14 +-
>> >  cpukit/score/cpu/sparc/cpu.c                       |    8 +
>> >  cpukit/score/cpu/sparc/rtems/score/cpu.h           |   13 +
>> >  cpukit/score/include/rtems/score/percpu.h          |   11 +-
>> >  cpukit/score/include/rtems/score/scheduler.h       |    2 +-
>> >  cpukit/score/include/rtems/score/schedulerimpl.h   |   24 +--
>> >  cpukit/score/include/rtems/score/schedulersmp.h    |    4 +-
>> >  .../score/include/rtems/score/schedulersmpimpl.h   |   33 ++-
>> >  cpukit/score/include/rtems/score/statesimpl.h      |    2 +
>> >  cpukit/score/include/rtems/score/thread.h          |   11 +
>> >  cpukit/score/include/rtems/score/threadimpl.h      |   35 +++-
>> >  cpukit/score/src/smp.c                             |    5 +-
>> >  cpukit/score/src/threaddispatch.c                  |   31 +--
>> >  cpukit/score/src/threadhandler.c                   |    4 +-
>> >  cpukit/score/src/threadinitialize.c                |    6 +-
>> >  cpukit/score/src/threadrestart.c                   |    2 +-
>> >  cpukit/score/src/threadstartmultitasking.c         |   18 +-
>> >  doc/user/smp.t                                     |   46 ++++
>> >  testsuites/smptests/Makefile.am                    |    1 +
>> >  testsuites/smptests/configure.ac                   |    1 +
>> >  testsuites/smptests/smpmigration02/Makefile.am     |   19 ++
>> >  testsuites/smptests/smpmigration02/init.c          |  255 ++++++++++++++++++++
>> >  .../smptests/smpmigration02/smpmigration02.doc     |   12 +
>> >  .../smptests/smpmigration02/smpmigration02.scn     |    7 +
>> >  testsuites/smptests/smpscheduler02/init.c          |    4 +-
>> >  39 files changed, 679 insertions(+), 80 deletions(-)
>> >  create mode 100644 testsuites/smptests/smpmigration02/Makefile.am
>> >  create mode 100644 testsuites/smptests/smpmigration02/init.c
>> >  create mode 100644 testsuites/smptests/smpmigration02/smpmigration02.doc
>> >  create mode 100644 testsuites/smptests/smpmigration02/smpmigration02.scn
>> >
>> >diff --git a/c/src/lib/libbsp/sparc/shared/irq_asm.S b/c/src/lib/libbsp/sparc/shared/irq_asm.S
>> >index 3a86ad5..cdaaf6d 100644
>> >--- a/c/src/lib/libbsp/sparc/shared/irq_asm.S
>> >+++ b/c/src/lib/libbsp/sparc/shared/irq_asm.S
>> >@@ -163,6 +163,21 @@ done_flushing:
>> >          nop
>> >          nop
>> >
>> >+#if defined(RTEMS_SMP)
>> >+        ! Indicate that this context is no longer executing
>> >+        stb     %g0, [%o0 + SPARC_CONTEXT_CONTROL_IS_EXECUTING_OFFSET]
>> >+
> The register usage should be documented at the declaration of
> CPU_Context_restore_heir above. Probably in the other architectures it
> should be documented as well.
>

%g0 is the zero register on SPARC and %o0 is the executing context, so I 
don't think there is something to document here.

-- 
Sebastian Huber, embedded brains GmbH

Address : Dornierstr. 4, D-82178 Puchheim, Germany
Phone   : +49 89 189 47 41-16
Fax     : +49 89 189 47 41-09
E-Mail  : sebastian.huber at embedded-brains.de
PGP     : Public key available on request.

Diese Nachricht ist keine geschäftliche Mitteilung im Sinne des EHUG.




More information about the devel mailing list