[PATCH 3/3] score: Task get/set affinity

Sebastian Huber sebastian.huber at embedded-brains.de
Thu Apr 10 08:42:34 UTC 2014


On 2014-04-10 04:27, Chris Johns wrote:
>>> The short circuit logic for non-smp should be in the api level code
>>> and the
>>> score should have NO code for affinity.
>>
>> Since the affinity support is used by the Classic and POSIX API it must
>> stay in the score.
>
> Conditionally removed on uniprocessor builds ?
>
>>
>>>
>>> Otherwise you impact the minimum profile and this is 100% unacceptable.
>>
>> There is no overhead in the non-SMP configurations if you don't use the
>> task set/get affinity functions.  The scheduler get/set affinity
>> operations are only available in SMP configurations.
>>
>
> Could you please elaborate ? If I do not use the functions the score includes
> no extra code related to this API, ie the scope is limited to the API layer ?

Lets look at rtems_task_get_affinity() for example.  This function makes sense 
on a uni-processor system since this can be viewed as an SMP system with only 
one processor.  The implementation is like this:

rtems_status_code rtems_task_get_affinity(
   rtems_id             id,
   size_t               cpusetsize,
   cpu_set_t           *cpuset
)
{
   Thread_Control        *the_thread;
   Objects_Locations      location;
   bool                   ok;

   if ( !cpuset )
     return RTEMS_INVALID_ADDRESS;

   the_thread = _Thread_Get( id, &location );

   switch ( location ) {

     case OBJECTS_LOCAL:
       ok = _Scheduler_Get_affinity(
         _Scheduler_Get( the_thread ),
         the_thread,
         cpusetsize,
         cpuset
       );
       _Objects_Put( &the_thread->Object );
       return ok ? RTEMS_SUCCESSFUL : RTEMS_INVALID_NUMBER;

#if defined(RTEMS_MULTIPROCESSING)
     case OBJECTS_REMOTE:
#endif

     case OBJECTS_ERROR:
       break;
   }

   return RTEMS_INVALID_ID;
}

This leads to _Scheduler_Get_affinity():

bool _Scheduler_Get_affinity(
   const Scheduler_Control *scheduler,
   Thread_Control          *the_thread,
   size_t                   cpusetsize,
   cpu_set_t               *cpuset
)
{
   bool ok;

   if ( _CPU_set_Is_large_enough( cpusetsize ) ) {
#if defined(RTEMS_SMP)
     ok = ( *scheduler->Operations.get_affinity )(
       scheduler,
       the_thread,
       cpusetsize,
       cpuset
     );
#else
     ok = _Scheduler_default_Get_affinity_body(
       scheduler,
       the_thread,
       cpusetsize,
       cpuset
     );
#endif
   } else {
     ok = false;
   }

   return ok;
}

On non-SMP this leads to _Scheduler_default_Get_affinity_body().  Please note 
that we have no get/set affinity operation!

RTEMS_INLINE_ROUTINE bool _Scheduler_default_Get_affinity_body(
   const Scheduler_Control *scheduler,
   Thread_Control          *the_thread,
   size_t                   cpusetsize,
   cpu_set_t               *cpuset
)
{
   uint32_t cpu_count = _SMP_Get_processor_count();
   uint32_t cpu_index;

   (void) scheduler;
   (void) the_thread;

   CPU_ZERO_S( cpusetsize, cpuset );

   for ( cpu_index = 0 ; cpu_index < cpu_count ; ++cpu_index ) {
     CPU_SET_S( (int) cpu_index, cpusetsize, cpuset );
   }

   return true;
}

On non-SMP _SMP_Get_processor_count() is a compile-time constant of one.

So if you use rtems_task_get_affinity() on non-SMP you have of course the 
overhead for this function to return a cpuset with all bits except bit 0 set to 
zero.  You have no overhead in the rest of the system, e.g. not set/get 
affinity operations in the scheduler, global variables, structure variables, etc.

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