Changeset c5831a3f in rtems


Ignore:
Timestamp:
Apr 9, 2014, 1:07:54 PM (5 years ago)
Author:
Sebastian Huber <sebastian.huber@…>
Branches:
4.11, master
Children:
509040f0
Parents:
27270b0d
git-author:
Sebastian Huber <sebastian.huber@…> (04/09/14 13:07:54)
git-committer:
Sebastian Huber <sebastian.huber@…> (04/15/14 08:41:44)
Message:

score: Add clustered/partitioned scheduling

Clustered/partitioned scheduling helps to control the worst-case
latencies in the system. The goal is to reduce the amount of shared
state in the system and thus prevention of lock contention. Modern
multi-processor systems tend to have several layers of data and
instruction caches. With clustered/partitioned scheduling it is
possible to honour the cache topology of a system and thus avoid
expensive cache synchronization traffic.

We have clustered scheduling in case the set of processors of a system
is partitioned into non-empty pairwise-disjoint subsets. These subsets
are called clusters. Clusters with a cardinality of one are partitions.
Each cluster is owned by exactly one scheduler instance.

Files:
24 added
25 edited

Legend:

Unmodified
Added
Removed
  • c/src/lib/libbsp/i386/shared/smp/smp-imps.c

    r27270b0d rc5831a3f  
    5858#include <bsp/irq.h>
    5959#include <rtems/score/smpimpl.h>
     60#include <rtems/score/schedulerimpl.h>
    6061
    6162/*
     
    387388    case IMPS_BCT_PROCESSOR:
    388389      if ( imps_num_cpus < rtems_configuration_get_maximum_processors() ) {
    389         add_processor((imps_processor *)start);
     390        const Scheduler_Assignment *assignment =
     391          _Scheduler_Get_assignment((uint32_t) imps_num_cpus);
     392
     393        if (_Scheduler_Should_start_processor(assignment)) {
     394          add_processor((imps_processor *)start);
     395        }
    390396      } else
    391397        imps_num_cpus++;
  • cpukit/posix/src/pthreadcreate.c

    r27270b0d rc5831a3f  
    6161  bool                                status;
    6262  Thread_Control                     *the_thread;
     63  Thread_Control                     *executing;
    6364  POSIX_API_Control                  *api;
    6465  int                                 schedpolicy = SCHED_RR;
     
    8990    rtems_set_errno_and_return_minus_one( ENOSYS );
    9091  #endif
     92
     93  executing = _Thread_Get_executing();
    9194
    9295  /*
     
    100103  switch ( the_attr->inheritsched ) {
    101104    case PTHREAD_INHERIT_SCHED:
    102       api = _Thread_Get_executing()->API_Extensions[ THREAD_API_POSIX ];
     105      api = executing->API_Extensions[ THREAD_API_POSIX ];
    103106      schedpolicy = api->schedpolicy;
    104107      schedparam  = api->schedparam;
     
    177180    &_POSIX_Threads_Information,
    178181    the_thread,
     182    _Scheduler_Get( executing ),
    179183    the_attr->stackaddr,
    180184    _POSIX_Threads_Ensure_minimum_stack(the_attr->stacksize),
     
    195199#if defined(RTEMS_SMP) && __RTEMS_HAVE_SYS_CPUSET_H__
    196200   status = _Scheduler_Set_affinity(
    197      _Scheduler_Get( the_thread ),
    198201     the_thread,
    199202     the_attr->affinitysetsize,
  • cpukit/posix/src/pthreadsetaffinitynp.c

    r27270b0d rc5831a3f  
    4949    case OBJECTS_LOCAL:
    5050      ok = _Scheduler_Set_affinity(
    51         _Scheduler_Get( the_thread ),
    5251        the_thread,
    5352        cpusetsize,
  • cpukit/rtems/src/clocktick.c

    r27270b0d rc5831a3f  
    3535  _Watchdog_Tickle_ticks();
    3636
    37   _Scheduler_Tick( _Scheduler_Get( NULL ) );
     37  _Scheduler_Tick();
    3838
    3939#if defined( RTEMS_SMP )
  • cpukit/rtems/src/taskcreate.c

    r27270b0d rc5831a3f  
    2424#include <rtems/rtems/support.h>
    2525#include <rtems/score/apimutex.h>
     26#include <rtems/score/schedulerimpl.h>
    2627#include <rtems/score/sysstate.h>
    2728#include <rtems/score/threadimpl.h>
     
    141142    &_RTEMS_tasks_Information,
    142143    the_thread,
     144    _Scheduler_Get_by_CPU_index( _SMP_Get_current_processor() ),
    143145    NULL,
    144146    stack_size,
  • cpukit/rtems/src/tasksetaffinity.c

    r27270b0d rc5831a3f  
    4444    case OBJECTS_LOCAL:
    4545      ok = _Scheduler_Set_affinity(
    46         _Scheduler_Get( the_thread ),
    4746        the_thread,
    4847        cpusetsize,
  • cpukit/sapi/include/confdefs.h

    r27270b0d rc5831a3f  
    821821    const size_t _Scheduler_Count =
    822822      RTEMS_ARRAY_SIZE( _Scheduler_Table );
     823
     824    const Scheduler_Assignment _Scheduler_Assignments[] = {
     825      #if defined(CONFIGURE_SMP_SCHEDULER_ASSIGNMENTS)
     826        CONFIGURE_SMP_SCHEDULER_ASSIGNMENTS
     827      #else
     828        #define CONFIGURE_SMP_SCHEDULER_ASSIGN_OPT \
     829          RTEMS_SCHEDULER_ASSIGN( \
     830            0, \
     831            RTEMS_SCHEDULER_ASSIGN_PROCESSOR_OPTIONAL \
     832          )
     833        CONFIGURE_SMP_SCHEDULER_ASSIGN_OPT
     834        #if CONFIGURE_SMP_MAXIMUM_PROCESSORS >= 2
     835          , CONFIGURE_SMP_SCHEDULER_ASSIGN_OPT
     836        #endif
     837        #if CONFIGURE_SMP_MAXIMUM_PROCESSORS >= 3
     838          , CONFIGURE_SMP_SCHEDULER_ASSIGN_OPT
     839        #endif
     840        #if CONFIGURE_SMP_MAXIMUM_PROCESSORS >= 4
     841          , CONFIGURE_SMP_SCHEDULER_ASSIGN_OPT
     842        #endif
     843        #if CONFIGURE_SMP_MAXIMUM_PROCESSORS >= 5
     844          , CONFIGURE_SMP_SCHEDULER_ASSIGN_OPT
     845        #endif
     846        #if CONFIGURE_SMP_MAXIMUM_PROCESSORS >= 6
     847          , CONFIGURE_SMP_SCHEDULER_ASSIGN_OPT
     848        #endif
     849        #if CONFIGURE_SMP_MAXIMUM_PROCESSORS >= 7
     850          , CONFIGURE_SMP_SCHEDULER_ASSIGN_OPT
     851        #endif
     852        #if CONFIGURE_SMP_MAXIMUM_PROCESSORS >= 8
     853          , CONFIGURE_SMP_SCHEDULER_ASSIGN_OPT
     854        #endif
     855        #if CONFIGURE_SMP_MAXIMUM_PROCESSORS >= 9
     856          , CONFIGURE_SMP_SCHEDULER_ASSIGN_OPT
     857        #endif
     858        #if CONFIGURE_SMP_MAXIMUM_PROCESSORS >= 10
     859          , CONFIGURE_SMP_SCHEDULER_ASSIGN_OPT
     860        #endif
     861        #if CONFIGURE_SMP_MAXIMUM_PROCESSORS >= 11
     862          , CONFIGURE_SMP_SCHEDULER_ASSIGN_OPT
     863        #endif
     864        #if CONFIGURE_SMP_MAXIMUM_PROCESSORS >= 12
     865          , CONFIGURE_SMP_SCHEDULER_ASSIGN_OPT
     866        #endif
     867        #if CONFIGURE_SMP_MAXIMUM_PROCESSORS >= 13
     868          , CONFIGURE_SMP_SCHEDULER_ASSIGN_OPT
     869        #endif
     870        #if CONFIGURE_SMP_MAXIMUM_PROCESSORS >= 14
     871          , CONFIGURE_SMP_SCHEDULER_ASSIGN_OPT
     872        #endif
     873        #if CONFIGURE_SMP_MAXIMUM_PROCESSORS >= 15
     874          , CONFIGURE_SMP_SCHEDULER_ASSIGN_OPT
     875        #endif
     876        #if CONFIGURE_SMP_MAXIMUM_PROCESSORS >= 16
     877          , CONFIGURE_SMP_SCHEDULER_ASSIGN_OPT
     878        #endif
     879        #if CONFIGURE_SMP_MAXIMUM_PROCESSORS >= 17
     880          , CONFIGURE_SMP_SCHEDULER_ASSIGN_OPT
     881        #endif
     882        #if CONFIGURE_SMP_MAXIMUM_PROCESSORS >= 18
     883          , CONFIGURE_SMP_SCHEDULER_ASSIGN_OPT
     884        #endif
     885        #if CONFIGURE_SMP_MAXIMUM_PROCESSORS >= 19
     886          , CONFIGURE_SMP_SCHEDULER_ASSIGN_OPT
     887        #endif
     888        #if CONFIGURE_SMP_MAXIMUM_PROCESSORS >= 20
     889          , CONFIGURE_SMP_SCHEDULER_ASSIGN_OPT
     890        #endif
     891        #if CONFIGURE_SMP_MAXIMUM_PROCESSORS >= 21
     892          , CONFIGURE_SMP_SCHEDULER_ASSIGN_OPT
     893        #endif
     894        #if CONFIGURE_SMP_MAXIMUM_PROCESSORS >= 22
     895          , CONFIGURE_SMP_SCHEDULER_ASSIGN_OPT
     896        #endif
     897        #if CONFIGURE_SMP_MAXIMUM_PROCESSORS >= 23
     898          , CONFIGURE_SMP_SCHEDULER_ASSIGN_OPT
     899        #endif
     900        #if CONFIGURE_SMP_MAXIMUM_PROCESSORS >= 24
     901          , CONFIGURE_SMP_SCHEDULER_ASSIGN_OPT
     902        #endif
     903        #if CONFIGURE_SMP_MAXIMUM_PROCESSORS >= 25
     904          , CONFIGURE_SMP_SCHEDULER_ASSIGN_OPT
     905        #endif
     906        #if CONFIGURE_SMP_MAXIMUM_PROCESSORS >= 26
     907          , CONFIGURE_SMP_SCHEDULER_ASSIGN_OPT
     908        #endif
     909        #if CONFIGURE_SMP_MAXIMUM_PROCESSORS >= 27
     910          , CONFIGURE_SMP_SCHEDULER_ASSIGN_OPT
     911        #endif
     912        #if CONFIGURE_SMP_MAXIMUM_PROCESSORS >= 28
     913          , CONFIGURE_SMP_SCHEDULER_ASSIGN_OPT
     914        #endif
     915        #if CONFIGURE_SMP_MAXIMUM_PROCESSORS >= 29
     916          , CONFIGURE_SMP_SCHEDULER_ASSIGN_OPT
     917        #endif
     918        #if CONFIGURE_SMP_MAXIMUM_PROCESSORS >= 30
     919          , CONFIGURE_SMP_SCHEDULER_ASSIGN_OPT
     920        #endif
     921        #if CONFIGURE_SMP_MAXIMUM_PROCESSORS >= 31
     922          , CONFIGURE_SMP_SCHEDULER_ASSIGN_OPT
     923        #endif
     924        #if CONFIGURE_SMP_MAXIMUM_PROCESSORS >= 32
     925          , CONFIGURE_SMP_SCHEDULER_ASSIGN_OPT
     926        #endif
     927        #undef CONFIGURE_SMP_SCHEDULER_ASSIGN_OPT
     928      #endif
     929    };
     930
     931    RTEMS_STATIC_ASSERT(
     932      CONFIGURE_SMP_MAXIMUM_PROCESSORS
     933        == RTEMS_ARRAY_SIZE( _Scheduler_Assignments ),
     934      _Scheduler_Assignments
     935    );
    823936  #endif
    824937
  • cpukit/sapi/include/rtems/scheduler.h

    r27270b0d rc5831a3f  
    2626#define RTEMS_SCHEDULER_CONTEXT_NAME( name ) \
    2727  _Configuration_Scheduler_ ## name
     28
     29#if defined(RTEMS_SMP)
     30  /* This object doesn't exist and indicates a configuration error */
     31  extern const Scheduler_Control RTEMS_SCHEDULER_INVALID_INDEX;
     32
     33  #define RTEMS_SCHEDULER_ASSIGN_DEFAULT \
     34    SCHEDULER_ASSIGN_DEFAULT
     35
     36  #define RTEMS_SCHEDULER_ASSIGN_PROCESSOR_OPTIONAL \
     37    SCHEDULER_ASSIGN_PROCESSOR_OPTIONAL
     38
     39  #define RTEMS_SCHEDULER_ASSIGN_PROCESSOR_MANDATORY \
     40    SCHEDULER_ASSIGN_PROCESSOR_MANDATORY
     41
     42  #define RTEMS_SCHEDULER_ASSIGN( index, attr ) \
     43    { \
     44      ( index ) < RTEMS_ARRAY_SIZE( _Scheduler_Table ) ? \
     45        &_Scheduler_Table[ ( index ) ] : &RTEMS_SCHEDULER_INVALID_INDEX, \
     46      ( attr ) \
     47    }
     48
     49  #define RTEMS_SCHEDULER_ASSIGN_NO_SCHEDULER { NULL, 0 }
     50#endif
    2851
    2952/*
  • cpukit/score/include/rtems/score/percpu.h

    r27270b0d rc5831a3f  
    317317     */
    318318    Per_CPU_State state;
     319
     320    /**
     321     * @brief Indicates if the processor has been successfully started via
     322     * _CPU_SMP_Start_processor().
     323     */
     324    bool started;
    319325  #endif
    320326
     
    461467
    462468  return ( uint32_t ) ( per_cpu_envelope - &_Per_CPU_Information[ 0 ] );
     469}
     470
     471static inline bool _Per_CPU_Is_processor_started(
     472  const Per_CPU_Control *per_cpu
     473)
     474{
     475#if defined( RTEMS_SMP )
     476  return per_cpu->started;
     477#else
     478  (void) per_cpu;
     479
     480  return true;
     481#endif
    463482}
    464483
  • cpukit/score/include/rtems/score/scheduler.h

    r27270b0d rc5831a3f  
    103103
    104104  /** perform scheduler update actions required at each clock tick */
    105   void ( *tick )( const Scheduler_Control * );
     105  void ( *tick )( const Scheduler_Control *, Thread_Control * );
    106106
    107107  /**
     
    150150 */
    151151typedef struct {
    152   /* No fields yet */
     152#if defined(RTEMS_SMP)
     153  /**
     154   * @brief Count of processors owned by this scheduler instance.
     155   */
     156  uint32_t processor_count;
     157#endif
    153158} Scheduler_Context;
    154159
     
    199204#endif
    200205
     206#if defined(RTEMS_SMP)
     207  /**
     208   * @brief The scheduler assignment default attributes.
     209   */
     210  #define SCHEDULER_ASSIGN_DEFAULT UINT32_C(0x0)
     211
     212  /**
     213   * @brief The presence of this processor is optional.
     214   */
     215  #define SCHEDULER_ASSIGN_PROCESSOR_OPTIONAL SCHEDULER_ASSIGN_DEFAULT
     216
     217  /**
     218   * @brief The presence of this processor is mandatory.
     219   */
     220  #define SCHEDULER_ASSIGN_PROCESSOR_MANDATORY UINT32_C(0x1)
     221
     222  /**
     223   * @brief Scheduler assignment.
     224   */
     225  typedef struct {
     226    /**
     227     * @brief The scheduler for this processor.
     228     */
     229    const Scheduler_Control *scheduler;
     230
     231    /**
     232     * @brief The scheduler assignment attributes.
     233     *
     234     * Use @ref SCHEDULER_ASSIGN_DEFAULT to select default attributes.
     235     *
     236     * The presence of a processor can be
     237     * - @ref SCHEDULER_ASSIGN_PROCESSOR_OPTIONAL, or
     238     * - @ref SCHEDULER_ASSIGN_PROCESSOR_MANDATORY.
     239     */
     240    uint32_t attributes;
     241  } Scheduler_Assignment;
     242
     243  /**
     244   * @brief The scheduler assignments.
     245   *
     246   * The length of this array must be equal to the maximum processors.
     247   *
     248   * Application provided via <rtems/confdefs.h>.
     249   *
     250   * @see _Scheduler_Table and rtems_configuration_get_maximum_processors().
     251   */
     252  extern const Scheduler_Assignment _Scheduler_Assignments[];
     253#endif
     254
    201255/**
    202256 * @brief Returns an arbitrary non-NULL value.
     
    254308 *
    255309 * @param[in] scheduler The scheduler.
    256  */
    257 void _Scheduler_default_Tick( const Scheduler_Control *scheduler );
     310 * @param[in] execution An executing thread.
     311 */
     312void _Scheduler_default_Tick(
     313  const Scheduler_Control *scheduler,
     314  Thread_Control          *executing
     315);
    258316
    259317/**
  • cpukit/score/include/rtems/score/schedulerimpl.h

    r27270b0d rc5831a3f  
    2222#include <rtems/score/scheduler.h>
    2323#include <rtems/score/cpusetimpl.h>
     24#include <rtems/score/smpimpl.h>
    2425#include <rtems/score/threadimpl.h>
    2526
     
    4142 */
    4243void _Scheduler_Handler_initialization( void );
     44
     45RTEMS_INLINE_ROUTINE const Scheduler_Control *_Scheduler_Get_by_CPU_index(
     46  uint32_t cpu_index
     47)
     48{
     49#if defined(RTEMS_SMP)
     50  return _Scheduler_Assignments[ cpu_index ].scheduler;
     51#else
     52  (void) cpu_index;
     53
     54  return &_Scheduler_Table[ 0 ];
     55#endif
     56}
     57
     58RTEMS_INLINE_ROUTINE const Scheduler_Control *_Scheduler_Get_by_CPU(
     59  const Per_CPU_Control *cpu
     60)
     61{
     62  uint32_t cpu_index = _Per_CPU_Get_index( cpu );
     63
     64  return _Scheduler_Get_by_CPU_index( cpu_index );
     65}
    4366
    4467/**
     
    235258 * time-slicing management.
    236259 */
    237 RTEMS_INLINE_ROUTINE void _Scheduler_Tick(
    238   const Scheduler_Control *scheduler
    239 )
    240 {
    241   ( *scheduler->Operations.tick )( scheduler );
     260RTEMS_INLINE_ROUTINE void _Scheduler_Tick( void )
     261{
     262  uint32_t cpu_count = _SMP_Get_processor_count();
     263  uint32_t cpu_index;
     264
     265  for ( cpu_index = 0 ; cpu_index < cpu_count ; ++cpu_index ) {
     266    const Per_CPU_Control *cpu = _Per_CPU_Get_by_index( cpu_index );
     267    const Scheduler_Control *scheduler = _Scheduler_Get_by_CPU( cpu );
     268
     269    if ( scheduler != NULL ) {
     270      ( *scheduler->Operations.tick )( scheduler, cpu->executing );
     271    }
     272  }
    242273}
    243274
     
    259290}
    260291
     292#if defined(RTEMS_SMP)
     293RTEMS_INLINE_ROUTINE const Scheduler_Assignment *_Scheduler_Get_assignment(
     294  uint32_t cpu_index
     295)
     296{
     297  return &_Scheduler_Assignments[ cpu_index ];
     298}
     299
     300RTEMS_INLINE_ROUTINE bool _Scheduler_Is_mandatory_processor(
     301  const Scheduler_Assignment *assignment
     302)
     303{
     304  return (assignment->attributes & SCHEDULER_ASSIGN_PROCESSOR_MANDATORY) != 0;
     305}
     306
     307RTEMS_INLINE_ROUTINE bool _Scheduler_Should_start_processor(
     308  const Scheduler_Assignment *assignment
     309)
     310{
     311  return assignment->scheduler != NULL;
     312}
     313#endif /* defined(RTEMS_SMP) */
     314
     315RTEMS_INLINE_ROUTINE bool _Scheduler_Has_processor_ownership(
     316  const Scheduler_Control *scheduler,
     317  uint32_t cpu_index
     318)
     319{
     320#if defined(RTEMS_SMP)
     321  const Scheduler_Assignment *assignment =
     322    _Scheduler_Get_assignment( cpu_index );
     323
     324  return assignment->scheduler == scheduler;
     325#else
     326  (void) scheduler;
     327  (void) cpu_index;
     328
     329  return true;
     330#endif
     331}
     332
    261333#if defined(__RTEMS_HAVE_SYS_CPUSET_H__)
    262334
     
    270342  uint32_t cpu_index;
    271343
    272   (void) scheduler;
    273 
    274344  CPU_ZERO_S( cpusetsize, cpuset );
    275345
    276346  for ( cpu_index = 0 ; cpu_index < cpu_count ; ++cpu_index ) {
     347#if defined(RTEMS_SMP)
     348    if ( _Scheduler_Has_processor_ownership( scheduler, cpu_index ) ) {
     349      CPU_SET_S( (int) cpu_index, cpusetsize, cpuset );
     350    }
     351#else
     352    (void) scheduler;
     353
    277354    CPU_SET_S( (int) cpu_index, cpusetsize, cpuset );
     355#endif
    278356  }
    279357}
     
    299377  cpu_set_t               *cpuset
    300378);
     379
     380RTEMS_INLINE_ROUTINE const Scheduler_Control *_Scheduler_Get(
     381  Thread_Control *the_thread
     382)
     383{
     384#if defined(RTEMS_SMP)
     385  return the_thread->scheduler;
     386#else
     387  (void) the_thread;
     388
     389  return &_Scheduler_Table[ 0 ];
     390#endif
     391}
     392
     393RTEMS_INLINE_ROUTINE bool _Scheduler_Set(
     394  const Scheduler_Control *scheduler,
     395  Thread_Control          *the_thread
     396)
     397{
     398  bool ok;
     399
     400  if ( _States_Is_dormant( the_thread->current_state ) ) {
     401#if defined(RTEMS_SMP)
     402    _Scheduler_Free( _Scheduler_Get( the_thread ), the_thread );
     403    the_thread->scheduler = scheduler;
     404    _Scheduler_Allocate( scheduler, the_thread );
     405    _Scheduler_Update( scheduler, the_thread );
     406#else
     407    (void) scheduler;
     408#endif
     409
     410    ok = true;
     411  } else {
     412    ok = false;
     413  }
     414
     415  return ok;
     416}
    301417
    302418RTEMS_INLINE_ROUTINE bool _Scheduler_default_Set_affinity_body(
     
    312428  bool     ok = true;
    313429
    314   (void) scheduler;
    315   (void) the_thread;
    316 
    317430  for ( cpu_index = 0 ; cpu_index < cpu_count ; ++cpu_index ) {
     431#if defined(RTEMS_SMP)
     432    const Scheduler_Control *scheduler_of_cpu =
     433      _Scheduler_Get_by_CPU_index( cpu_index );
     434
     435    ok = ok
     436      && ( ( CPU_ISSET_S( (int) cpu_index, cpusetsize, cpuset )
     437          && scheduler == scheduler_of_cpu )
     438        || ( !CPU_ISSET_S( (int) cpu_index, cpusetsize, cpuset )
     439          && scheduler != scheduler_of_cpu ) );
     440#else
     441    (void) scheduler;
     442
    318443    ok = ok && CPU_ISSET_S( (int) cpu_index, cpusetsize, cpuset );
     444#endif
    319445  }
    320446
     
    323449  }
    324450
     451  if ( ok ) {
     452    ok = _Scheduler_Set( scheduler, the_thread );
     453  }
     454
    325455  return ok;
    326456}
    327457
    328458bool _Scheduler_Set_affinity(
    329   const Scheduler_Control *scheduler,
    330459  Thread_Control          *the_thread,
    331460  size_t                   cpusetsize,
     
    443572}
    444573
    445 RTEMS_INLINE_ROUTINE const Scheduler_Control *_Scheduler_Get(
    446   Thread_Control *the_thread
    447 )
    448 {
    449   (void) the_thread;
    450 
    451   return &_Scheduler_Table[ 0 ];
    452 }
    453 
    454 RTEMS_INLINE_ROUTINE bool _Scheduler_Set(
    455   const Scheduler_Control *scheduler,
    456   Thread_Control          *the_thread
    457 )
    458 {
    459   bool ok;
    460 
    461   (void) scheduler;
    462 
    463   if ( _States_Is_dormant( the_thread->current_state ) ) {
    464     ok = true;
    465   } else {
    466     ok = false;
    467   }
    468 
    469   return ok;
    470 }
    471 
    472574RTEMS_INLINE_ROUTINE Objects_Id _Scheduler_Build_id( uint32_t scheduler_index )
    473575{
  • cpukit/score/include/rtems/score/smpimpl.h

    r27270b0d rc5831a3f  
    5050  SMP_FATAL_SHUTDOWN,
    5151  SMP_FATAL_SHUTDOWN_EARLY,
     52  SMP_FATAL_BOOT_PROCESSOR_NOT_ASSIGNED_TO_SCHEDULER,
     53  SMP_FATAL_MANDATORY_PROCESSOR_NOT_PRESENT,
     54  SMP_FATAL_MULTITASKING_START_ON_UNASSIGNED_PROCESSOR,
     55  SMP_FATAL_SCHEDULER_WITHOUT_PROCESSORS,
    5256  SMP_FATAL_START_OF_MANDATORY_PROCESSOR_FAILED
    5357} SMP_Fatal_code;
     58
     59static inline void _SMP_Fatal( SMP_Fatal_code code )
     60{
     61  _Terminate( RTEMS_FATAL_SOURCE_SMP, false, code );
     62}
    5463
    5564/**
  • cpukit/score/include/rtems/score/thread.h

    r27270b0d rc5831a3f  
    3434#include <rtems/score/watchdog.h>
    3535
    36 #ifdef RTEMS_SMP
    37 #if __RTEMS_HAVE_SYS_CPUSET_H__
    38 #include <sys/cpuset.h>
    39 #include <rtems/score/cpuset.h>
    40 #endif
    41 #endif
     36#if defined(RTEMS_SMP)
     37  #include <rtems/score/cpuset.h>
     38#endif
     39
     40struct Scheduler_Control;
    4241
    4342#ifdef __cplusplus
     
    518517   */
    519518  volatile bool                         is_executing;
     519
     520  /**
     521   * @brief The scheduler of this thread.
     522   */
     523  const struct Scheduler_Control       *scheduler;
    520524#endif
    521525
  • cpukit/score/include/rtems/score/threadimpl.h

    r27270b0d rc5831a3f  
    142142  Objects_Information                  *information,
    143143  Thread_Control                       *the_thread,
     144  const struct Scheduler_Control       *scheduler,
    144145  void                                 *stack_area,
    145146  size_t                                stack_size,
  • cpukit/score/src/percpu.c

    r27270b0d rc5831a3f  
    2323#include <rtems/score/smpimpl.h>
    2424#include <rtems/config.h>
    25 #include <rtems/fatal.h>
    2625
    2726#if defined(RTEMS_SMP)
     
    155154      && new_state != PER_CPU_STATE_SHUTDOWN
    156155  ) {
    157     rtems_fatal( RTEMS_FATAL_SOURCE_SMP, SMP_FATAL_SHUTDOWN );
     156    _SMP_Fatal( SMP_FATAL_SHUTDOWN );
    158157  }
    159158}
  • cpukit/score/src/schedulerdefaulttick.c

    r27270b0d rc5831a3f  
    2525#include <rtems/config.h>
    2626
    27 static void _Scheduler_default_Tick_for_executing(
     27void _Scheduler_default_Tick(
    2828  const Scheduler_Control *scheduler,
    2929  Thread_Control          *executing
     
    8484  }
    8585}
    86 
    87 void _Scheduler_default_Tick( const Scheduler_Control *scheduler )
    88 {
    89   uint32_t processor_count = _SMP_Get_processor_count();
    90   uint32_t processor;
    91 
    92   for ( processor = 0 ; processor < processor_count ; ++processor ) {
    93     const Per_CPU_Control *per_cpu = _Per_CPU_Get_by_index( processor );
    94 
    95     _Scheduler_default_Tick_for_executing( scheduler, per_cpu->executing );
    96   }
    97 }
  • cpukit/score/src/schedulersetaffinity.c

    r27270b0d rc5831a3f  
    2222
    2323bool _Scheduler_Set_affinity(
    24   const Scheduler_Control *scheduler,
    2524  Thread_Control          *the_thread,
    2625  size_t                   cpusetsize,
     
    3231  if ( _CPU_set_Is_large_enough( cpusetsize ) ) {
    3332#if defined(RTEMS_SMP)
    34     ok = ( *scheduler->Operations.set_affinity )(
    35       scheduler,
    36       the_thread,
    37       cpusetsize,
    38       cpuset
    39     );
     33    uint32_t cpu_count = _SMP_Get_processor_count();
     34    uint32_t cpu_index;
     35
     36    ok = false;
     37
     38    for ( cpu_index = 0 ; cpu_index < cpu_count ; ++cpu_index ) {
     39      if ( CPU_ISSET_S( (int) cpu_index, cpusetsize, cpuset ) ) {
     40        const Scheduler_Control *scheduler_of_cpu =
     41          _Scheduler_Get_by_CPU_index( cpu_index );
     42
     43        if ( scheduler_of_cpu != NULL ) {
     44          ok = ( *scheduler_of_cpu->Operations.set_affinity )(
     45            scheduler_of_cpu,
     46            the_thread,
     47            cpusetsize,
     48            cpuset
     49          );
     50        }
     51
     52        break;
     53      }
     54    }
    4055#else
    4156    ok = _Scheduler_default_Set_affinity_body(
    42       scheduler,
     57      _Scheduler_Get( the_thread ),
    4358      the_thread,
    4459      cpusetsize,
  • cpukit/score/src/smp.c

    r27270b0d rc5831a3f  
    2121#include <rtems/score/smpimpl.h>
    2222#include <rtems/score/assert.h>
     23#include <rtems/score/schedulerimpl.h>
    2324#include <rtems/score/threaddispatch.h>
    2425#include <rtems/score/threadimpl.h>
    2526#include <rtems/config.h>
    2627
     28static void _SMP_Check_scheduler_configuration( void )
     29{
     30  size_t n = _Scheduler_Count;
     31  size_t i;
     32
     33  for ( i = 0 ; i < n ; ++i ) {
     34    const Scheduler_Control *scheduler = &_Scheduler_Table[ i ];
     35
     36    if ( scheduler->context->processor_count == 0 ) {
     37      _SMP_Fatal( SMP_FATAL_SCHEDULER_WITHOUT_PROCESSORS );
     38    }
     39  }
     40}
     41
     42static void _SMP_Start_processors( uint32_t cpu_count )
     43{
     44  uint32_t cpu_self = _SMP_Get_current_processor();
     45  uint32_t cpu_index;
     46
     47
     48  for ( cpu_index = 0 ; cpu_index < cpu_count; ++cpu_index ) {
     49    const Scheduler_Assignment *assignment =
     50      _Scheduler_Get_assignment( cpu_index );
     51    Per_CPU_Control *per_cpu = _Per_CPU_Get_by_index( cpu_index );
     52    bool started;
     53
     54    if ( cpu_index != cpu_self ) {
     55      if ( _Scheduler_Should_start_processor( assignment ) ) {
     56        started = _CPU_SMP_Start_processor( cpu_index );
     57
     58        if ( !started && _Scheduler_Is_mandatory_processor( assignment ) ) {
     59          _SMP_Fatal( SMP_FATAL_START_OF_MANDATORY_PROCESSOR_FAILED );
     60        }
     61      } else {
     62        started = false;
     63      }
     64    } else {
     65      started = true;
     66
     67      if ( !_Scheduler_Should_start_processor( assignment ) ) {
     68        _SMP_Fatal( SMP_FATAL_BOOT_PROCESSOR_NOT_ASSIGNED_TO_SCHEDULER );
     69      }
     70    }
     71
     72    per_cpu->started = started;
     73
     74    if ( started ) {
     75      ++assignment->scheduler->context->processor_count;
     76    }
     77  }
     78
     79  _SMP_Check_scheduler_configuration();
     80}
     81
    2782void _SMP_Handler_initialize( void )
    2883{
    2984  uint32_t cpu_max = rtems_configuration_get_maximum_processors();
    30   uint32_t cpu_self;
    3185  uint32_t cpu_count;
    3286  uint32_t cpu_index;
     
    46100  _SMP_Processor_count = cpu_count;
    47101
    48   cpu_self = _SMP_Get_current_processor();
     102  for ( cpu_index = cpu_count ; cpu_index < cpu_max; ++cpu_index ) {
     103    const Scheduler_Assignment *assignment =
     104      _Scheduler_Get_assignment( cpu_index );
    49105
    50   for ( cpu_index = 0 ; cpu_index < cpu_count; ++cpu_index ) {
    51     if ( cpu_index != cpu_self ) {
    52       bool ok = _CPU_SMP_Start_processor( cpu_index );
    53 
    54       if ( !ok ) {
    55         _Terminate(
    56           RTEMS_FATAL_SOURCE_SMP,
    57           false,
    58           SMP_FATAL_START_OF_MANDATORY_PROCESSOR_FAILED
    59         );
    60       }
     106    if ( _Scheduler_Is_mandatory_processor( assignment ) ) {
     107      _SMP_Fatal( SMP_FATAL_MANDATORY_PROCESSOR_NOT_PRESENT );
    61108    }
    62109  }
     110
     111  _SMP_Start_processors( cpu_count );
    63112
    64113  _CPU_SMP_Finalize_initialization( cpu_count );
     
    83132{
    84133  Per_CPU_Control *self_cpu = _Per_CPU_Get();
     134
     135  if ( !_Per_CPU_Is_processor_started( self_cpu ) ) {
     136    _SMP_Fatal( SMP_FATAL_MULTITASKING_START_ON_UNASSIGNED_PROCESSOR );
     137  }
    85138
    86139  _Per_CPU_State_change( self_cpu, PER_CPU_STATE_READY_TO_START_MULTITASKING );
  • cpukit/score/src/threadcreateidle.c

    r27270b0d rc5831a3f  
    2020
    2121#include <rtems/score/threadimpl.h>
     22#include <rtems/score/schedulerimpl.h>
    2223#include <rtems/score/stackimpl.h>
    2324#include <rtems/config.h>
     
    4041    &_Thread_Internal_information,
    4142    idle,
     43    _Scheduler_Get_by_CPU( per_cpu ),
    4244    NULL,        /* allocate the stack */
    4345    _Stack_Ensure_minimum( rtems_configuration_get_idle_task_stack_size() ),
     
    7678    Per_CPU_Control *per_cpu = _Per_CPU_Get_by_index( processor );
    7779
    78     _Thread_Create_idle_for_cpu( per_cpu );
     80    if ( _Per_CPU_Is_processor_started( per_cpu ) ) {
     81      _Thread_Create_idle_for_cpu( per_cpu );
     82    }
    7983  }
    8084}
  • cpukit/score/src/threadinitialize.c

    r27270b0d rc5831a3f  
    3232  Objects_Information                  *information,
    3333  Thread_Control                       *the_thread,
     34  const Scheduler_Control              *scheduler,
    3435  void                                 *stack_area,
    3536  size_t                                stack_size,
     
    5152  size_t                   i;
    5253  bool                     scheduler_allocated = false;
    53   const Scheduler_Control *scheduler;
    5454
    5555  /*
     
    189189  the_thread->is_in_the_air           = false;
    190190  the_thread->is_executing            = false;
     191  the_thread->scheduler               = scheduler;
    191192#endif
    192193
     
    200201  the_thread->Start.initial_priority  = priority;
    201202
    202   scheduler = _Scheduler_Get( _Thread_Get_executing() );
    203203  scheduler_allocated = _Scheduler_Allocate( scheduler, the_thread );
    204204  if ( !scheduler_allocated ) {
  • cpukit/score/src/threadstart.c

    r27270b0d rc5831a3f  
    4747      _Thread_Ready( the_thread );
    4848    } else {
    49       the_thread->current_state = STATES_READY;
    50       _Scheduler_Start_idle( _Scheduler_Get( the_thread ), the_thread, cpu );
     49      const Scheduler_Control *scheduler = _Scheduler_Get_by_CPU( cpu );
     50
     51      if ( scheduler != NULL ) {
     52        the_thread->current_state = STATES_READY;
     53        _Scheduler_Start_idle( scheduler, the_thread, cpu );
     54      }
    5155    }
    5256
  • doc/user/conf.t

    r27270b0d rc5831a3f  
    35023502@subheading DESCRIPTION:
    35033503The Deterministic Priority Scheduler is the default scheduler in RTEMS
    3504 for single core applications and is designed for predictable performance
     3504for uni-processor applications and is designed for predictable performance
    35053505under the highest loads.  It can block or unblock a thread in a constant
    35063506amount of time.  This scheduler requires a variable amount of memory
     
    35733573@subheading DESCRIPTION:
    35743574The Earliest Deadline First Scheduler (EDF) is an alternative scheduler in
    3575 RTEMS for single core applications. The EDF schedules tasks with dynamic
     3575RTEMS for uni-processor applications. The EDF schedules tasks with dynamic
    35763576priorities equal to deadlines. The deadlines are declared using only
    35773577Rate Monotonic manager which handles periodic behavior.  Period is always
     
    36133613@subheading DESCRIPTION:
    36143614The Constant Bandwidth Server Scheduler (CBS) is an alternative scheduler
    3615 in RTEMS for single core applications. The CBS is a budget aware extension
     3615in RTEMS for uni-processor applications. The CBS is a budget aware extension
    36163616of EDF scheduler. The goal of this scheduler is to ensure temporal
    36173617isolation of tasks. The CBS is equipped with a set of additional rules
     
    36863686@subheading DESCRIPTION:
    36873687The Simple SMP Priority Scheduler is derived from the Simple Priority
    3688 Scheduler but is capable of scheduling threads across multiple cores.
     3688Scheduler but is capable of scheduling threads across multiple processors.
    36893689It is designed to provide the same task scheduling behaviour as the
    36903690Deterministic Priority Scheduler while distributing threads across
    3691 multiple cores.  Being based upon the Simple Priority Scheduler, it also
     3691multiple processors.  Being based upon the Simple Priority Scheduler, it also
    36923692maintains a single sorted list of all ready threads.  Thus blocking or
    36933693unblocking a thread is not a constant time operation with this scheduler.
    36943694
    3695 In addition, when allocating threads to cores, the algorithm is not
     3695In addition, when allocating threads to processors, the algorithm is not
    36963696constant time. This algorithm was not designed with efficiency as a
    36973697primary design goal.  Its primary design goal was to provide an SMP-aware
     
    37933793
    37943794@c
     3795@c === Configuring Clustered/Partitioned Schedulers ===
     3796@c
     3797@subsection Configuring Clustered/Partitioned Schedulers
     3798
     3799Clustered/partitioned scheduling helps to control the worst-case latencies in
     3800the system.  The goal is to reduce the amount of shared state in the system and
     3801thus prevention of lock contention.  Modern multi-processor systems tend to
     3802have several layers of data and instruction caches.  With clustered/partitioned
     3803scheduling it is possible to honour the cache topology of a system and thus
     3804avoid expensive cache synchronization traffic.
     3805
     3806We have clustered scheduling in case the set of processors of a system is
     3807partitioned into non-empty pairwise-disjoint subsets.  These subsets are called
     3808clusters.  Clusters with a cardinality of one are partitions.  Each cluster is
     3809owned by exactly one scheduler instance.  In order to use clustered/partitioned
     3810scheduling the application designer has to answer two questions.
     3811
     3812@enumerate
     3813@item How is the set of processors partitioned into clusters/partitions?
     3814@item Which scheduler is used for which cluster/partition?
     3815@end enumerate
     3816
     3817@subheading CONFIGURATION:
     3818
     3819The schedulers in an SMP system are statically configured on RTEMS.  Firstly
     3820the application must select which scheduling algorithms are available with the
     3821following defines
     3822
     3823@itemize @bullet
     3824@item @code{CONFIGURE_SCHEDULER_PRIORITY_SMP},
     3825@item @code{CONFIGURE_SCHEDULER_SIMPLE_SMP}, and
     3826@item @code{CONFIGURE_SCHEDULER_PRIORITY_AFFINITY_SMP}.
     3827@end itemize
     3828
     3829This is necessary to calculate the per-thread overhead introduced by the
     3830schedulers.  After these definitions the configuration file must @code{#include
     3831<rtems/scheduler.h>} to have access to scheduler specific configuration macros.
     3832Each scheduler needs a context to store state information at run-time.  To
     3833provide a context for each scheduler is the next step.  Use the following
     3834macros to create scheduler contexts
     3835
     3836@itemize @bullet
     3837@item @code{RTEMS_SCHEDULER_CONTEXT_PRIORITY_SMP(name, prio_count)},
     3838@item @code{RTEMS_SCHEDULER_CONTEXT_SIMPLE_SMP(name)}, and
     3839@item @code{RTEMS_SCHEDULER_CONTEXT_PRIORITY_AFFINITY_SMP(name, prio_count)}.
     3840@end itemize
     3841
     3842The @code{name} parameter is used as part of a designator for a global
     3843variable, so the usual C/C++ designator rules apply.  Additional parameters are
     3844scheduler specific.  The schedulers are registered in the system via the
     3845scheduler table.  To create the scheduler table define
     3846@code{CONFIGURE_SCHEDULER_CONTROLS} to a list of the following scheduler
     3847control initializers
     3848
     3849@itemize @bullet
     3850@item @code{RTEMS_SCHEDULER_CONTROL_PRIORITY_SMP(name, obj_name)},
     3851@item @code{RTEMS_SCHEDULER_CONTROL_SIMPLE_SMP(name, obj_name)}, and
     3852@item @code{RTEMS_SCHEDULER_CONTROL_PRIORITY_AFFINITY_SMP(name, obj_name)}.
     3853@end itemize
     3854
     3855The @code{name} parameter must correspond to the parameter defining the
     3856scheduler context.  The @code{obj_name} determines the scheduler object name
     3857and can be used in @code{rtems_scheduler_ident()} to get the scheduler object
     3858identifier.
     3859
     3860The last step is to define which processor uses which scheduler.
     3861For this purpose a scheduler assignment table must be defined.  The entry count
     3862of this table must be equal to the configured maximum processors
     3863(@code{CONFIGURE_SMP_MAXIMUM_PROCESSORS}).  A processor assignment to a
     3864scheduler can be optional or mandatory.  The boot processor must have a
     3865scheduler assigned.  In case the system needs more mandatory processors than
     3866available then a fatal run-time error will occur.  To specify the scheduler
     3867assignments define @code{CONFIGURE_SMP_SCHEDULER_ASSIGNMENTS} to a list of
     3868@code{RTEMS_SCHEDULER_ASSIGN(index, attr)} and
     3869@code{RTEMS_SCHEDULER_ASSIGN_NO_SCHEDULER} macros.  The @code{index} parameter
     3870must be a valid index into the scheduler table.  The @code{attr} parameter
     3871defines the scheduler assignment attributes.  By default a scheduler assignment
     3872to a processor is optional.  For the scheduler assignment attribute use one of
     3873the mutually exclusive variants
     3874
     3875@itemize @bullet
     3876@item @code{RTEMS_SCHEDULER_ASSIGN_DEFAULT},
     3877@item @code{RTEMS_SCHEDULER_ASSIGN_PROCESSOR_MANDATORY}, and
     3878@item @code{RTEMS_SCHEDULER_ASSIGN_PROCESSOR_OPTIONAL}.
     3879@end itemize
     3880
     3881@subheading ERRORS:
     3882
     3883In case one of the scheduler indices in
     3884@code{CONFIGURE_SMP_SCHEDULER_ASSIGNMENTS} is invalid a link-time error will
     3885occur with an undefined reference to @code{RTEMS_SCHEDULER_INVALID_INDEX}.
     3886
     3887Some fatal errors may occur in case of scheduler configuration inconsistencies or a lack
     3888of processors on the system.  The fatal source is
     3889@code{RTEMS_FATAL_SOURCE_SMP}.  None of the errors is internal.
     3890
     3891@itemize @bullet
     3892@item @code{SMP_FATAL_BOOT_PROCESSOR_NOT_ASSIGNED_TO_SCHEDULER} - the boot
     3893processor must have a scheduler assigned.
     3894@item @code{SMP_FATAL_MANDATORY_PROCESSOR_NOT_PRESENT} - there exists a
     3895mandatory processor beyond the range of physically or virtually available
     3896processors.  The processor demand must be reduced for this system.
     3897@item @code{SMP_FATAL_START_OF_MANDATORY_PROCESSOR_FAILED} - the start of a
     3898mandatory processor failed during system initialization.  The system may not
     3899have this processor at all or it could be a problem with a boot loader for
     3900example.
     3901the @code{CONFIGURE_SMP_SCHEDULER_ASSIGNMENTS} definition.
     3902@item @code{SMP_FATAL_SCHEDULER_WITHOUT_PROCESSORS} - it is prohibited to have
     3903a scheduler managing the empty processor set.
     3904@item @code{SMP_FATAL_MULTITASKING_START_ON_UNASSIGNED_PROCESSOR} - it is not
     3905allowed to start multitasking on a processor with no scheduler assigned.
     3906@end itemize
     3907
     3908@subheading EXAMPLE:
     3909
     3910The following example shows a scheduler configuration for a hypothetical
     3911product using two chip variants.  One variant has four processors which is used
     3912for the normal product line and another provides eight processors for the
     3913high-performance product line.  The first processor performs hard-real time
     3914control of actuators and sensors.  The second processor is not used by RTEMS at
     3915all and runs a Linux instance to provide a graphical user interface.  The
     3916additional processors are used for a worker thread pool to perform data
     3917processing operations.
     3918
     3919The processors managed by RTEMS use two Deterministic Priority scheduler
     3920instances capable of dealing with 256 priority levels.  The scheduler with
     3921index zero has the name @code{"IO  "}.  The scheduler with index one has the
     3922name @code{"WORK"}.  The scheduler assignments of the first, third and fourth
     3923processor are mandatory, so the system must have at least four processors,
     3924otherwise a fatal run-time error will occur during system startup.  The
     3925processor assignments for the fifth up to the eighth processor are optional so
     3926that the same application can be used for the normal and high-performance
     3927product lines.  The second processor has no scheduler assigned and runs Linux.
     3928A hypervisor will ensure that the two systems cannot interfere in an
     3929undesirable way.
     3930
     3931@example
     3932@group
     3933#define CONFIGURE_SMP_MAXIMUM_PROCESSORS 8
     3934
     3935#define CONFIGURE_MAXIMUM_PRIORITY 255
     3936
     3937/* Make the scheduler algorithm available */
     3938
     3939#define CONFIGURE_SCHEDULER_PRIORITY_SMP
     3940
     3941#include <rtems/scheduler.h>
     3942
     3943/* Create contexts for the two scheduler instances */
     3944
     3945RTEMS_SCHEDULER_CONTEXT_PRIORITY_SMP(io, CONFIGURE_MAXIMUM_PRIORITY + 1);
     3946
     3947RTEMS_SCHEDULER_CONTEXT_PRIORITY_SMP(work, CONFIGURE_MAXIMUM_PRIORITY + 1);
     3948
     3949/* Define the scheduler table */
     3950
     3951#define CONFIGURE_SCHEDULER_CONTROLS \
     3952  RTEMS_SCHEDULER_CONTROL_PRIORITY_SMP( \
     3953    io, \
     3954    rtems_build_name('I', 'O', ' ', ' ') \
     3955  ), \
     3956  RTEMS_SCHEDULER_CONTROL_PRIORITY_SMP( \
     3957    work, \
     3958    rtems_build_name('W', 'O', 'R', 'K') \
     3959  )
     3960
     3961/* Define the processor to scheduler assignments */
     3962
     3963#define CONFIGURE_SMP_SCHEDULER_ASSIGNMENTS \
     3964  RTEMS_SCHEDULER_ASSIGN(0, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_MANDATORY), \
     3965  RTEMS_SCHEDULER_ASSIGN_NO_SCHEDULER, \
     3966  RTEMS_SCHEDULER_ASSIGN(1, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_MANDATORY), \
     3967  RTEMS_SCHEDULER_ASSIGN(1, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_MANDATORY), \
     3968  RTEMS_SCHEDULER_ASSIGN(1, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_OPTIONAL), \
     3969  RTEMS_SCHEDULER_ASSIGN(1, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_OPTIONAL), \
     3970  RTEMS_SCHEDULER_ASSIGN(1, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_OPTIONAL), \
     3971  RTEMS_SCHEDULER_ASSIGN(1, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_OPTIONAL)
     3972@end group
     3973@end example
     3974
     3975@c
    37953976@c === SMP Specific Configuration Parameters ===
    37963977@c
     
    38053986@c === CONFIGURE_SMP_APPLICATION ===
    38063987@c
    3807 @subsection Specify Application Uses Multiple Cores (is SMP)
     3988@subsection Enable SMP Support for Applications
    38083989
    38093990@findex CONFIGURE_SMP_APPLICATION
     
    38204001
    38214002@item DEFAULT VALUE:
     4003This is not defined by default.
     4004
     4005@end table
     4006
     4007@subheading DESCRIPTION:
     4008@code{CONFIGURE_SMP_APPLICATION} must be defined to enable SMP support for the
     4009application.
     4010
     4011@subheading NOTES:
     4012This define may go away in the future in case all RTEMS components are SMP ready.
     4013
     4014@c
     4015@c === CONFIGURE_SMP_MAXIMUM_PROCESSORS ===
     4016@c
     4017@subsection Specify Maximum Processors in SMP System
     4018
     4019@findex CONFIGURE_SMP_MAXIMUM_PROCESSORS
     4020
     4021@table @b
     4022@item CONSTANT:
     4023@code{CONFIGURE_SMP_MAXIMUM_PROCESSORS}
     4024
     4025@item DATA TYPE:
     4026Unsigned integer (@code{uint32_t}).
     4027
     4028@item RANGE:
     4029Defined or undefined.
     4030
     4031@item DEFAULT VALUE:
    38224032The default value is 1, (if CONFIGURE_SMP_APPLICATION is defined).
    38234033
     
    38254035
    38264036@subheading DESCRIPTION:
    3827 @code{CONFIGURE_SMP_APPLICATION} must be defined if the application is
    3828 to make use of multiple CPU cores in an SMP target system.
    3829 
    3830 @subheading NOTES:
    3831 None.
    3832 
    3833 @c
    3834 @c === CONFIGURE_SMP_MAXIMUM_PROCESSORS ===
    3835 @c
    3836 @subsection Specify Maximum Processors in SMP System
    3837 
    3838 @findex CONFIGURE_SMP_MAXIMUM_PROCESSORS
    3839 
    3840 @table @b
    3841 @item CONSTANT:
    3842 @code{CONFIGURE_SMP_MAXIMUM_PROCESSORS}
    3843 
    3844 @item DATA TYPE:
    3845 Unsigned integer (@code{uint32_t}).
    3846 
    3847 @item RANGE:
    3848 Defined or undefined.
    3849 
    3850 @item DEFAULT VALUE:
    3851 The default value is 1, (if CONFIGURE_SMP_APPLICATION is defined).
    3852 
    3853 @end table
    3854 
    3855 @subheading DESCRIPTION:
    38564037@code{CONFIGURE_SMP_MAXIMUM_PROCESSORS} must be set to the number of
    3857 CPU cores in the SMP configuration.
    3858 
    3859 @subheading NOTES:
    3860 If there are more cores available than configured, the rest will be
     4038processors in the SMP configuration.
     4039
     4040@subheading NOTES:
     4041If there are more processors available than configured, the rest will be
    38614042ignored.
    38624043
  • testsuites/smptests/Makefile.am

    r27270b0d rc5831a3f  
    22
    33SUBDIRS =
    4 SUBDIRS += smpload01
    5 
    64if SMPTESTS
    75SUBDIRS += smp01
     
    1715SUBDIRS += smpfatal02
    1816SUBDIRS += smpfatal03
     17SUBDIRS += smpfatal04
     18SUBDIRS += smpfatal05
     19SUBDIRS += smpfatal06
     20SUBDIRS += smpfatal07
     21SUBDIRS += smpfatal08
     22SUBDIRS += smpload01
    1923SUBDIRS += smplock01
    2024SUBDIRS += smpmigration01
    2125SUBDIRS += smpscheduler01
     26SUBDIRS += smpscheduler02
    2227SUBDIRS += smpsignal01
    2328SUBDIRS += smpswitchextension01
  • testsuites/smptests/configure.ac

    r27270b0d rc5831a3f  
    5858# Explicitly list all Makefiles here
    5959AC_CONFIG_FILES([Makefile
    60 smpload01/Makefile
    6160smp01/Makefile
    6261smp02/Makefile
     
    7170smpfatal02/Makefile
    7271smpfatal03/Makefile
     72smpfatal04/Makefile
     73smpfatal05/Makefile
     74smpfatal06/Makefile
     75smpfatal07/Makefile
     76smpfatal08/Makefile
     77smpload01/Makefile
    7378smplock01/Makefile
    7479smpmigration01/Makefile
     
    7782smppsxsignal01/Makefile
    7883smpscheduler01/Makefile
     84smpscheduler02/Makefile
    7985smpsignal01/Makefile
    8086smpswitchextension01/Makefile
  • testsuites/sptests/spscheduler01/init.c

    r27270b0d rc5831a3f  
    3636#if defined(__RTEMS_HAVE_SYS_CPUSET_H__)
    3737  rtems_id self_id = rtems_task_self();
     38  rtems_id task_id;
    3839  rtems_status_code sc;
    3940  cpu_set_t cpusetone;
     
    4748  CPU_SET(0, &cpusetone);
    4849
     50  sc = rtems_task_create(
     51    rtems_build_name('T', 'A', 'S', 'K'),
     52    2,
     53    RTEMS_MINIMUM_STACK_SIZE,
     54    RTEMS_DEFAULT_MODES,
     55    RTEMS_DEFAULT_ATTRIBUTES,
     56    &task_id
     57  );
     58  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
     59
    4960  sc = rtems_task_get_affinity(RTEMS_SELF, sizeof(cpuset), NULL);
    5061  rtems_test_assert(sc == RTEMS_INVALID_ADDRESS);
     
    7182
    7283  sc = rtems_task_set_affinity(RTEMS_SELF, sizeof(cpuset), &cpuset);
    73   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
    74 
    75   sc = rtems_task_get_affinity(self_id, sizeof(cpuset), &cpuset);
     84  rtems_test_assert(sc == RTEMS_INVALID_NUMBER);
     85
     86  sc = rtems_task_set_affinity(self_id, sizeof(cpuset), &cpuset);
     87  rtems_test_assert(sc == RTEMS_INVALID_NUMBER);
     88
     89  sc = rtems_task_set_affinity(task_id, sizeof(cpuset), &cpuset);
     90  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
     91
     92  sc = rtems_task_get_affinity(task_id, sizeof(cpuset), &cpuset);
    7693  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
    7794
    7895  rtems_test_assert(CPU_EQUAL(&cpuset, &cpusetone));
    79 
    80   sc = rtems_task_set_affinity(self_id, sizeof(cpuset), &cpuset);
    81   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
    8296
    8397  cpusetbigone = CPU_ALLOC(big);
     
    90104  CPU_SET_S(0, cpusetbigsize, cpusetbigone);
    91105
    92   sc = rtems_task_get_affinity(RTEMS_SELF, cpusetbigsize, cpusetbig);
     106  sc = rtems_task_get_affinity(task_id, cpusetbigsize, cpusetbig);
    93107  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
    94108
    95109  rtems_test_assert(CPU_EQUAL_S(cpusetbigsize, cpusetbig, cpusetbigone));
    96110
    97   sc = rtems_task_set_affinity(RTEMS_SELF, cpusetbigsize, cpusetbig);
     111  sc = rtems_task_set_affinity(task_id, cpusetbigsize, cpusetbig);
     112  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
     113
     114  sc = rtems_task_delete(task_id);
    98115  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
    99116
Note: See TracChangeset for help on using the changeset viewer.