Ticket #1808: per_core_scheduler_updated.patch

File per_core_scheduler_updated.patch, 33.9 KB (added by Marta Rybczynska, on 05/31/11 at 06:13:57)

Updated version

  • cpukit/sapi/include/confdefs.h

    diff --git a/cpukit/sapi/include/confdefs.h b/cpukit/sapi/include/confdefs.h
    index 6aa6406..e3f407e 100644
    a b rtems_fs_init_functions_t rtems_fs_init_helper = 
    573573 *  CONFIGURE_SCHEDULER_PRIORITY   - Deterministic Priority Scheduler
    574574 *  CONFIGURE_SCHEDULER_SIMPLE     - Light-weight Priority Scheduler
    575575 *  CONFIGURE_SCHEDULER_SIMPLE_SMP - Simple SMP Priority Scheduler
     576 *  CONFIGURE_SCHEDULER_PERCORE_SMP - PerCore SMP Scheduler
    576577 *
    577578 * If no configuration is specified by the application, then
    578579 * CONFIGURE_SCHEDULER_PRIORITY is assumed to be the default.
    rtems_fs_init_functions_t rtems_fs_init_helper = 
    592593
    593594#if !defined(RTEMS_SMP)
    594595  #undef CONFIGURE_SCHEDULER_SIMPLE_SMP
     596  #undef CONFIGURE_SCHEDULER_PERCORE_SMP
    595597#endif
    596598
    597599/* If no scheduler is specified, the priority scheduler is default. */
    rtems_fs_init_functions_t rtems_fs_init_helper = 
    640642  #define CONFIGURE_MEMORY_PER_TASK_FOR_SCHEDULER (0)
    641643#endif
    642644
     645/*
     646 * If the PerCore SMP Scheduler is selected, then configure for it.
     647 */
     648#if defined(CONFIGURE_SCHEDULER_PERCORE_SMP)
     649  #include <rtems/score/schedulerpercoresmp.h>
     650  #define CONFIGURE_SCHEDULER_ENTRY_POINTS SCHEDULER_PERCORE_SMP_ENTRY_POINTS
     651
     652  /**
     653   * define the memory used by the SMP simple scheduler
     654   */
     655  #define CONFIGURE_MEMORY_FOR_SCHEDULER ( \
     656    CONFIGURE_SMP_MAXIMUM_PROCESSORS * _Configure_From_workspace( sizeof(Scheduler_PerCore_SMP_Information) ) \
     657      )
     658  #define CONFIGURE_MEMORY_PER_TASK_FOR_SCHEDULER (0)
     659#endif
     660
    643661/*
    644662 * If the Simple SMP Priority Scheduler is selected, then configure for it.
    645663 */
    rtems_fs_init_functions_t rtems_fs_init_helper = 
    663681          CONFIGURE_SCHEDULER_USER_ENTRY_POINTS
    664682#endif
    665683
     684
    666685/*
    667686 * Set up the scheduler entry points table.  The scheduling code uses
    668687 * this code to know which scheduler is configured by the user.
  • cpukit/score/Makefile.am

    diff --git a/cpukit/score/Makefile.am b/cpukit/score/Makefile.am
    index 9138178..4f81d47 100644
    a b endif 
    7878
    7979if HAS_SMP
    8080include_rtems_score_HEADERS += include/rtems/score/schedulersimplesmp.h
     81include_rtems_score_HEADERS += include/rtems/score/schedulerpercoresmp.h
    8182endif
    8283
    8384## inline
    libscore_a_SOURCES += src/schedulersimple.c \ 
    218219    src/schedulersimpleunblock.c \
    219220    src/schedulersimpleyield.c
    220221
     222if HAS_SMP
     223## SCHEDULERPERCORESMP_C_FILES
     224libscore_a_SOURCES += src/schedulerpercoresmp.c \
     225    src/schedulerpercoresmpblock.c \
     226    src/schedulerpercoresmpenqueue.c \
     227    src/schedulerpercoresmpenqueuefirst.c \
     228    src/schedulerpercoresmpextract.c \
     229    src/schedulerpercoresmpreadyqueueenqueue.c \
     230    src/schedulerpercoresmpreadyqueueenqueuefirst.c \
     231    src/schedulerpercoresmpschedule.c \
     232    src/schedulerpercoresmpunblock.c \
     233    src/schedulerpercoresmpyield.c
     234endif
     235
    221236## PROTECTED_HEAP_C_FILES
    222237libscore_a_SOURCES += src/pheapallocate.c \
    223238    src/pheapextend.c src/pheapfree.c src/pheapgetsize.c \
  • cpukit/score/include/rtems/score/percpu.h

    diff --git a/cpukit/score/include/rtems/score/percpu.h b/cpukit/score/include/rtems/score/percpu.h
    index 0e11680..5edd965 100644
    a b typedef struct { 
    143143
    144144  /** This is set to true when this CPU needs to run the dispatcher. */
    145145  volatile bool dispatch_necessary;
     146 
     147  /** Scheduler-specific information */
     148  void *scheduler_information;
    146149
    147150  /** This is the time of the last context switch on this CPU. */
    148151  Timestamp_Control time_of_last_context_switch;
     152 
     153 
    149154} Per_CPU_Control;
    150155#endif
    151156
  • new file cpukit/score/include/rtems/score/schedulerpercoresmp.h

    diff --git a/cpukit/score/include/rtems/score/schedulerpercoresmp.h b/cpukit/score/include/rtems/score/schedulerpercoresmp.h
    new file mode 100644
    index 0000000..34ebd9d
    - +  
     1/**
     2 *  @file  rtems/score/schedulerpercoresmp.h
     3 *
     4 *  This include file contains all the constants and structures associated
     5 *  with the manipulation of threads on a SMP-aware simple-priority-based ready queue.
     6 *
     7 *
     8 *  Copyright (C) 2011 On-Line Applications Research Corporation (OAR).
     9 *  Copyright (C) 2011 Kalray
     10 *
     11 *  The license and distribution terms for this file may be
     12 *  found in the file LICENSE in this distribution or at
     13 *  http://www.rtems.com/license/LICENSE.
     14 *
     15 *  $Id$
     16 */
     17
     18#ifndef _RTEMS_SCORE_SCHEDULERPERCORESMP_H
     19#define _RTEMS_SCORE_SCHEDULERPERCORESMP_H
     20
     21#if defined(RTEMS_SMP)
     22
     23/**
     24 *  @addtogroup ScoreScheduler
     25 *
     26 */
     27/**@{*/
     28
     29#ifdef __cplusplus
     30extern "C" {
     31#endif
     32
     33#include <rtems/score/scheduler.h>
     34
     35/**
     36 *  Entry points for PerCore SMP Scheduler
     37 */
     38#define SCHEDULER_PERCORE_SMP_ENTRY_POINTS \
     39  { \
     40    _Scheduler_PerCore_SMP_Initialize,    /* initialize entry point */ \
     41    _Scheduler_PerCore_SMP_Schedule,      /* schedule entry point */ \
     42    _Scheduler_PerCore_SMP_Yield,         /* yield entry point */ \
     43    _Scheduler_PerCore_SMP_Block,         /* block entry point */ \
     44    _Scheduler_PerCore_SMP_Unblock,       /* unblock entry point */ \
     45    _Scheduler_PerCore_SMP_Allocate,      /* allocate entry point */ \
     46    _Scheduler_PerCore_SMP_Free,          /* free entry point */ \
     47    _Scheduler_PerCore_SMP_Update,        /* update entry point */ \
     48    _Scheduler_PerCore_SMP_Enqueue,       /* enqueue entry point */ \
     49    _Scheduler_PerCore_SMP_Enqueue_first, /* enqueue_first entry point */ \
     50    _Scheduler_PerCore_SMP_Extract        /* extract entry point */ \
     51  }
     52 
     53/**
     54 * This is the scheduler-specific per-core information.
     55 */
     56typedef struct {
     57    /** This element is used to lock this structure */
     58    SMP_lock_spinlock_simple_Control lock;
     59   
     60    /** Ready queue */
     61    Chain_Control rq;
     62} Scheduler_PerCore_SMP_Information;
     63
     64/**
     65 * This routine initializes the simple scheduler.
     66 */
     67void _Scheduler_PerCore_SMP_Initialize( void );
     68
     69/**
     70 *  This routine sets the heir thread to be the next ready thread
     71 *  on the ready queue by getting the first node in the scheduler
     72 *  information. Protecting wrapper of
     73 *  _Scheduler_PerCore_SMP_Schedule_unprotected.
     74 */
     75void _Scheduler_PerCore_SMP_Schedule( void );
     76
     77/**
     78 *  This routine sets the heir thread to be the next ready thread
     79 *  on the ready queue by getting the first node in the scheduler
     80 *  information. This version is for internal use only.
     81 */
     82void _Scheduler_PerCore_SMP_Schedule_unprotected(void);
     83
     84/**
     85 *  This routine is invoked when a thread wishes to voluntarily
     86 *  transfer control of the processor to another thread in the queue.
     87 *  It will remove the running THREAD from the scheduler.informaiton
     88 *  (where the ready queue is stored) and place it immediately at the
     89 *  between the last entry of its priority and the next priority thread. 
     90 *  Reset timeslice and yield the processor functions both use this routine,
     91 *  therefore if reset is true and this is the only thread on the queue then
     92 *  the timeslice counter is reset.  The heir THREAD will be updated if the
     93 *  running is also the currently the heir.
     94*/
     95void _Scheduler_PerCore_SMP_Yield( void );
     96
     97/**
     98 *  This routine removes @a the_thread from the scheduling decision,
     99 *  that is, removes it from the ready queue.  It performs
     100 *  any necessary scheduling operations including the selection of
     101 *  a new heir thread.
     102 *
     103 *  @param[in] the_thread is the thread that is to be blocked
     104 */
     105void _Scheduler_PerCore_SMP_Block(
     106  Thread_Control *the_thread
     107);
     108
     109/**
     110 *  This routine adds @a the_thread to the scheduling decision,
     111 *  that is, adds it to the ready queue and
     112 *  updates any appropriate scheduling variables, for example the heir thread.
     113 *
     114 *  @param[in] the_thread is the thread that is to be unblocked
     115 */
     116void _Scheduler_PerCore_SMP_Unblock(
     117  Thread_Control *the_thread
     118);
     119
     120/**
     121 *  This routine removes a specific thread from the specified
     122 *  simple-based ready queue.
     123 *
     124 *  @param[in] the_thread is the thread to be blocked
     125 */
     126void _Scheduler_PerCore_SMP_Extract(
     127  Thread_Control *the_thread
     128);
     129
     130/**
     131 *  This routine puts @a the_thread on to the ready queue.
     132 *
     133 *  @param[in] the_thread is the thread to be blocked
     134 */
     135void _Scheduler_PerCore_SMP_Enqueue(
     136  Thread_Control *the_thread
     137);
     138
     139/**
     140 *  This routine puts @a the_thread to the head of the ready queue.
     141 *  The thread will be the first thread at its priority level.
     142 *
     143 *  @param[in] the_thread is the thread to be blocked
     144 */
     145void _Scheduler_PerCore_SMP_Enqueue_first(
     146  Thread_Control *the_thread
     147);
     148
     149/**
     150 *  This routine is a place holder for any memeory allocation needed
     151 *  by the scheduler.  For the simple scheduler the routine is an empty
     152 *  place holder.
     153 *
     154 *  @param[in] the_thread is the thread the scheduler is allocating
     155 *             management memory for
     156 *
     157 *  @return this routine returns -1 since this is just an empty placeholder
     158 *  and the return value may be defined differently by each scheduler.
     159 */
     160void *_Scheduler_PerCore_SMP_Allocate(
     161  Thread_Control *the_thread
     162);
     163
     164/**
     165 * This routine does nothing, and is used as a stub for Schedule update
     166 *
     167 * The overhead of a function call will still be imposed.
     168 *
     169 *  @param[in] the_thread is the thread to be blocked
     170 */
     171void _Scheduler_PerCore_SMP_Update(
     172  Thread_Control *the_thread
     173);
     174
     175/**
     176 * This routine does nothing, and is used as a stub for Schedule free
     177 *
     178 * The overhead of a function call will still be imposed.
     179 *
     180 *  @param[in] the_thread is the thread to be blocked
     181 */
     182void _Scheduler_PerCore_SMP_Free(
     183  Thread_Control *the_thread
     184);
     185
     186/**
     187 *  _Scheduler_simple_Ready_queue_Enqueue
     188 *
     189 *  This routine puts @a the_thread on the ready queue
     190 *  at the end of its priority group.
     191 * 
     192 *  @param[in] the_thread - pointer to a thread control block
     193 */
     194void _Scheduler_PerCore_SMP_Ready_queue_Enqueue(
     195  Thread_Control    *the_thread
     196);
     197
     198/**
     199 *  _Scheduler_simple_Ready_queue_Enqueue_first
     200 *
     201 *  This routine puts @a the_thread on to the ready queue
     202 *  at the beginning of its priority group.
     203 * 
     204 *  @param[in] the_thread - pointer to a thread control block
     205 */
     206void _Scheduler_PerCore_SMP_Ready_queue_Enqueue_first(
     207  Thread_Control    *the_thread
     208);
     209
     210#ifndef __RTEMS_APPLICATION__
     211#include <rtems/score/schedulerpercoresmp.inl>
     212#endif
     213
     214#ifdef __cplusplus
     215}
     216#endif
     217
     218#endif /* RTEMS_SMP */
     219
     220/**@}*/
     221
     222#endif
     223/* end of include file */
  • cpukit/score/include/rtems/score/smp.h

    diff --git a/cpukit/score/include/rtems/score/smp.h b/cpukit/score/include/rtems/score/smp.h
    index 727a139..f3eb454 100644
    a b extern "C" { 
    6363 */
    6464#define RTEMS_BSP_SMP_FIRST_TASK                0x08
    6565
     66/**
     67 *  This defines the bit which indicates the interprocessor interrupt
     68 *  has been requested so that RTEMS will run the scheduler on this CPU
     69 *  because the currently executing thread may need to be switched out.
     70 */
     71#define RTEMS_BSP_SMP_SCHEDULE_NECESSARY  0x10
     72
    6673#ifndef ASM
    6774/**
    6875 *  @brief Number of CPUs in SMP System
  • new file cpukit/score/inline/rtems/score/schedulerpercoresmp.inl

    diff --git a/cpukit/score/inline/rtems/score/schedulerpercoresmp.inl b/cpukit/score/inline/rtems/score/schedulerpercoresmp.inl
    new file mode 100644
    index 0000000..f1cd536
    - +  
     1/**
     2 *  @file  rtems/score/schedulerpercoresmp.inl
     3 *
     4 *  This inline file contains all of the inlined routines associated with
     5 *  the manipulation of the per-core SMP-aware scheduler structures.
     6 */
     7
     8/*
     9 *  Copyright (C) 2011 On-Line Applications Research Corporation (OAR).
     10 *  Copyright (C) 2011 Kalray
     11 *
     12 *  The license and distribution terms for this file may be
     13 *  found in the file LICENSE in this distribution or at
     14 *  http://www.rtems.com/license/LICENSE.
     15 *
     16 *  $Id: schedulersimple.inl,v 1.1 2011/03/16 16:32:21 joel Exp $
     17 */
     18
     19#ifndef _RTEMS_SCORE_SCHEDULERPERCORESMP_H
     20# error "Never use <rtems/score/schedulerpercoresmp.inl> directly; include <rtems/score/schedulerpercoresmp.h> instead."
     21#endif
     22
     23#ifndef RTEMS_SMP
     24# error "SMP Scheduler include when SMP is not enabled"
     25#endif
     26
     27#ifndef _RTEMS_SCORE_SCHEDULERPERCORESMP_INL
     28#define _RTEMS_SCORE_SCHEDULERPERCORESMP_INL
     29
     30#include <rtems/score/thread.h>
     31
     32/**
     33 *  @addtogroup ScoreScheduler
     34 * @{
     35 */
     36
     37/**
     38 *  This routine puts @a the_thread on to the ready queue.
     39 *
     40 *  @param[in] the_ready_queue is a pointer to the ready queue head
     41 *  @param[in] the_thread is the thread to be blocked
     42 */
     43RTEMS_INLINE_ROUTINE void _Scheduler_PerCore_SMP_Ready_queue_Requeue(
     44  Scheduler_Control *the_ready_queue,
     45  Thread_Control    *the_thread
     46)
     47{
     48  /* extract */
     49  _Chain_Extract_unprotected( &the_thread->Object.Node );
     50
     51  /* enqueue */
     52  _Scheduler_PerCore_SMP_Ready_queue_Enqueue( the_thread );
     53}
     54
     55/**@}*/
     56
     57#endif
     58/* end of include file */
  • cpukit/score/preinstall.am

    diff --git a/cpukit/score/preinstall.am b/cpukit/score/preinstall.am
    index f302118..443a621 100644
    a b $(PROJECT_INCLUDE)/rtems/score/schedulersimple.h: include/rtems/score/schedulers 
    131131        $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/schedulersimple.h
    132132PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/schedulersimple.h
    133133
     134$(PROJECT_INCLUDE)/rtems/score/schedulerpercoresmp.h: include/rtems/score/schedulerpercoresmp.h $(PROJECT_INCLUDE)/rtems/score/$(dirstamp)
     135        $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/schedulerpercoresmp.h
     136PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/schedulerpercoresmp.h
     137
    134138$(PROJECT_INCLUDE)/rtems/score/stack.h: include/rtems/score/stack.h $(PROJECT_INCLUDE)/rtems/score/$(dirstamp)
    135139        $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/stack.h
    136140PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/stack.h
    $(PROJECT_INCLUDE)/rtems/score/schedulersimple.inl: inline/rtems/score/scheduler 
    295299        $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/schedulersimple.inl
    296300PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/schedulersimple.inl
    297301
     302$(PROJECT_INCLUDE)/rtems/score/schedulerpercoresmp.inl: inline/rtems/score/schedulerpercoresmp.inl $(PROJECT_INCLUDE)/rtems/score/$(dirstamp)
     303        $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/schedulerpercoresmp.inl
     304PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/schedulerpercoresmp.inl
     305
    298306$(PROJECT_INCLUDE)/rtems/score/stack.inl: inline/rtems/score/stack.inl $(PROJECT_INCLUDE)/rtems/score/$(dirstamp)
    299307        $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/stack.inl
    300308PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/stack.inl
  • new file cpukit/score/src/schedulerpercoresmp.c

    diff --git a/cpukit/score/src/schedulerpercoresmp.c b/cpukit/score/src/schedulerpercoresmp.c
    new file mode 100644
    index 0000000..8e0be6b
    - +  
     1/*
     2 *  Scheduler PerCoreSMP Handler / Initialize
     3 *  Scheduler PerCoreSMP Handler / Allocate (Empty Routine)
     4 *  Scheduler PerCoreSMP Handler / Update (Empty Routine)
     5 *  Scheduler PerCoreSMP Handler / Free (Empty Routine)
     6 *
     7 *  COPYRIGHT (c) 2011.
     8 *  On-Line Applications Research Corporation (OAR).
     9 *  COPYRIGHT (c) 2011.
     10 *  Kalray.
     11 *
     12 *  The license and distribution terms for this file may be
     13 *  found in the file LICENSE in this distribution or at
     14 *  http://www.rtems.com/license/LICENSE.
     15 *
     16 *  $Id$
     17 */
     18
     19#if HAVE_CONFIG_H
     20#include "config.h"
     21#endif
     22
     23#if defined(RTEMS_SMP)
     24
     25#include <rtems/system.h>
     26#include <rtems/config.h>
     27#include <rtems/score/chain.h>
     28#include <rtems/score/scheduler.h>
     29#include <rtems/score/schedulerpercoresmp.h>
     30#include <rtems/score/thread.h>
     31#include <rtems/score/smp.h>
     32#include <rtems/score/wkspace.h>
     33
     34/**
     35 * This routine does nothing, and is used as a stub for Schedule allocate
     36 *
     37 * Note: returns a non-zero value, or else thread initialize thinks the
     38 * allocation failed.
     39 *
     40 * The overhead of a function call will still be imposed.
     41 */
     42void * _Scheduler_PerCore_SMP_Allocate(
     43  Thread_Control *the_thread
     44)
     45{
     46  return (void*)-1; /* maybe pick an appropriate poison value */
     47}
     48
     49
     50/**
     51 * This routine does nothing, and is used as a stub for Schedule update
     52 *
     53 * The overhead of a function call will still be imposed.
     54 */
     55void _Scheduler_PerCore_SMP_Update(
     56  Thread_Control *the_thread
     57)
     58{
     59}
     60
     61/**
     62 * This routine does nothing, and is used as a stub for Schedule free
     63 *
     64 * The overhead of a function call will still be imposed.
     65 */
     66void _Scheduler_PerCore_SMP_Free(
     67  Thread_Control *the_thread
     68)
     69{
     70}
     71
     72/**
     73 * This routine initializes the simple scheduler.
     74 *
     75 * \note We assume nobody will get in our way here.
     76 */
     77void _Scheduler_PerCore_SMP_Initialize ( void )
     78{
     79  Scheduler_PerCore_SMP_Information *info;
     80  int i;
     81
     82  /*
     83   * Initialize All Ready Queues
     84   */
     85  for (i = 0; i < _SMP_Processor_count; i++) {
     86    /* allocate ready queue structures */
     87    info = _Workspace_Allocate_or_fatal_error( sizeof(Scheduler_PerCore_SMP_Information) );
     88    _Per_CPU_Information[i].scheduler_information = info;
     89
     90    /* initialize the lock */
     91    _SMP_lock_spinlock_simple_Initialize( &(info->lock) );
     92 
     93    /* initialize ready queue structure */
     94    _Chain_Initialize_empty( &(info->rq) );
     95  }
     96}
     97
     98#endif /* RTEMS_SMP */
  • new file cpukit/score/src/schedulerpercoresmpblock.c

    diff --git a/cpukit/score/src/schedulerpercoresmpblock.c b/cpukit/score/src/schedulerpercoresmpblock.c
    new file mode 100644
    index 0000000..f605328
    - +  
     1/*
     2 *  Scheduler PerCore SMP Handler / Block
     3 *
     4 *  COPYRIGHT (c) 2011.
     5 *  On-Line Applications Research Corporation (OAR).
     6 *  COPYRIGHT (c) 2011.
     7 *  Kalray.
     8 *
     9 *  The license and distribution terms for this file may be
     10 *  found in found in the file LICENSE in this distribution or at
     11 *  http://www.rtems.com/license/LICENSE.
     12 *
     13 *  $Id$
     14 */
     15
     16#if HAVE_CONFIG_H
     17#include "config.h"
     18#endif
     19
     20#if defined(RTEMS_SMP)
     21
     22#include <rtems/system.h>
     23#include <rtems/score/context.h>
     24#include <rtems/score/interr.h>
     25#include <rtems/score/isr.h>
     26#include <rtems/score/object.h>
     27#include <rtems/score/priority.h>
     28#include <rtems/score/scheduler.h>
     29#include <rtems/score/thread.h>
     30#include <rtems/score/smp.h>
     31#include <rtems/score/schedulerpercoresmp.h>
     32
     33void _Scheduler_PerCore_SMP_Block(
     34  Thread_Control   *the_thread
     35)
     36{
     37  ISR_Level       level;
     38  int core = the_thread->core;
     39  Scheduler_PerCore_SMP_Information *info;
     40
     41  info = _Per_CPU_Information[core].scheduler_information;
     42 
     43  level = _SMP_lock_spinlock_simple_Obtain( &(info->lock) );
     44 
     45  _Scheduler_PerCore_SMP_Extract(the_thread);
     46
     47  /* We can run schedule directly only if the thread is
     48  on our CPU. Otherwise, we need to notify. */
     49  if ( _Thread_Is_heir_SMP( the_thread, core ) ) {
     50    if ( the_thread->core == bsp_smp_processor_id() ) {
     51       _Scheduler_PerCore_SMP_Schedule_unprotected();
     52    } else {
     53       rtems_smp_send_message( core, RTEMS_BSP_SMP_SCHEDULE_NECESSARY );   
     54    }
     55  }
     56
     57  if ( _Thread_Is_executing_SMP( the_thread, core ) )
     58  {
     59    if ( core == bsp_smp_processor_id() ) {
     60      _Per_CPU_Information[core].dispatch_necessary = true;
     61    } else {
     62      rtems_smp_send_message( core, RTEMS_BSP_SMP_CONTEXT_SWITCH_NECESSARY );
     63    }
     64  }
     65 
     66  _SMP_lock_spinlock_simple_Release( &(info->lock), level );
     67}
     68
     69#endif
  • new file cpukit/score/src/schedulerpercoresmpenqueue.c

    diff --git a/cpukit/score/src/schedulerpercoresmpenqueue.c b/cpukit/score/src/schedulerpercoresmpenqueue.c
    new file mode 100644
    index 0000000..6023181
    - +  
     1/*
     2 *  Schedule PerCore SMP Handler / Enqueue
     3 *
     4 *  COPYRIGHT (c) 2011.
     5 *  On-Line Applications Research Corporation (OAR).
     6 *  COPYRIGHT (c) 2011.
     7 *  Kalray.
     8 *
     9 *  The license and distribution terms for this file may be
     10 *  found in the file LICENSE in this distribution or at
     11 *  http://www.rtems.com/license/LICENSE.
     12 *
     13 *  $Id$
     14 */
     15
     16#if HAVE_CONFIG_H
     17#include "config.h"
     18#endif
     19
     20#if defined(RTEMS_SMP)
     21
     22#include <rtems/system.h>
     23#include <rtems/score/chain.h>
     24#include <rtems/score/isr.h>
     25#include <rtems/score/thread.h>
     26#include <rtems/score/schedulerpercoresmp.h>
     27
     28void _Scheduler_PerCore_SMP_Enqueue(
     29  Thread_Control            *the_thread
     30)
     31{
     32  Scheduler_PerCore_SMP_Information *info;
     33  int core;
     34  ISR_Level level;
     35
     36  core = the_thread->core;
     37  info =  _Per_CPU_Information[core].scheduler_information;
     38 
     39  level = _SMP_lock_spinlock_simple_Obtain( &(info->lock) );
     40  _Scheduler_PerCore_SMP_Ready_queue_Enqueue( the_thread );
     41  _SMP_lock_spinlock_simple_Release( &(info->lock), level );
     42}
     43
     44#endif
  • new file cpukit/score/src/schedulerpercoresmpenqueuefirst.c

    diff --git a/cpukit/score/src/schedulerpercoresmpenqueuefirst.c b/cpukit/score/src/schedulerpercoresmpenqueuefirst.c
    new file mode 100644
    index 0000000..d6e077e
    - +  
     1/*
     2 *  Schedule PerCore SMP Handler / Enqueue First
     3 *
     4 *  COPYRIGHT (c) 2011.
     5 *  On-Line Applications Research Corporation (OAR).
     6 *  COPYRIGHT (c) 2011.
     7 *  Kalray.
     8 *
     9 *  The license and distribution terms for this file may be
     10 *  found in the file LICENSE in this distribution or at
     11 *  http://www.rtems.com/license/LICENSE.
     12 *
     13 *  $Id$
     14 */
     15
     16#if HAVE_CONFIG_H
     17#include "config.h"
     18#endif
     19
     20#if defined(RTEMS_SMP)
     21
     22#include <rtems/system.h>
     23#include <rtems/score/chain.h>
     24#include <rtems/score/thread.h>
     25#include <rtems/score/schedulerpercoresmp.h>
     26
     27void _Scheduler_PerCore_SMP_Enqueue_first(
     28  Thread_Control            *the_thread
     29)
     30{
     31  Scheduler_PerCore_SMP_Information *info;
     32  int core;
     33  ISR_Level level;
     34
     35  core = the_thread->core;
     36  info =  _Per_CPU_Information[core].scheduler_information;
     37 
     38  level = _SMP_lock_spinlock_simple_Obtain( &(info->lock) );
     39  _Scheduler_PerCore_SMP_Ready_queue_Enqueue_first( the_thread );
     40  _SMP_lock_spinlock_simple_Release( &(info->lock), level );
     41}
     42
     43#endif
  • new file cpukit/score/src/schedulerpercoresmpextract.c

    diff --git a/cpukit/score/src/schedulerpercoresmpextract.c b/cpukit/score/src/schedulerpercoresmpextract.c
    new file mode 100644
    index 0000000..e407c35
    - +  
     1/*
     2 *  Schedule PerCore SMP Handler / Extract
     3 *
     4 *  COPYRIGHT (c) 2011.
     5 *  On-Line Applications Research Corporation (OAR).
     6 *  COPYRIGHT (c) 2011.
     7 *  Kalray.
     8 *
     9 *  The license and distribution terms for this file may be
     10 *  found in the file LICENSE in this distribution or at
     11 *  http://www.rtems.com/license/LICENSE.
     12 *
     13 *  $Id$
     14 */
     15
     16#if HAVE_CONFIG_H
     17#include "config.h"
     18#endif
     19
     20#if defined(RTEMS_SMP)
     21
     22#include <rtems/system.h>
     23#include <rtems/score/chain.h>
     24#include <rtems/score/interr.h>
     25#include <rtems/score/thread.h>
     26#include <rtems/score/schedulerpercoresmp.h>
     27
     28//#define LOCAL_DEBUG
     29
     30#ifdef LOCAL_DEBUG
     31#define D(format,...) printk( format, __VA_ARGS__)
     32#else
     33#define D(format,...)
     34#endif
     35
     36#ifdef LOCAL_DEBUG
     37static inline _Scheduler_PerCore_SMP_Show_chain(Chain_Control *ready, int core)
     38{
     39  Chain_Node *the_node = _Chain_First( ready );
     40  D( "SCHED core %d showing list %p\n -- \n", core, ready );
     41  for ( ; !_Chain_Is_tail( ready, the_node ) ; the_node = the_node->next ) {
     42    D( "SCHED element %p\n", the_node );
     43  }
     44  D( "--\nSCHED list end %d -- \n", core );
     45}
     46#else
     47static inline _Scheduler_PerCore_SMP_Show_chain(Chain_Control *ready, int core)
     48{
     49}
     50#endif
     51
     52/* This function is called internally. We assume that it is always
     53   in the critical section. */
     54
     55void _Scheduler_PerCore_SMP_Extract(
     56  Thread_Control    *the_thread
     57)
     58{
     59  Scheduler_PerCore_SMP_Information *info;
     60  int core;
     61  ISR_Level level;
     62  Chain_Control *ready;
     63
     64  core = the_thread->core;
     65  info =  _Per_CPU_Information[core].scheduler_information;
     66  ready    = &(info->rq);
     67 
     68  D( "SCHED core %d extracting %p\n", core, the_thread );
     69 
     70  _Chain_Extract_unprotected( &the_thread->Object.Node );
     71  _Scheduler_PerCore_SMP_Show_chain(ready, core);
     72}
     73
     74#endif
  • new file cpukit/score/src/schedulerpercoresmpreadyqueueenqueue.c

    diff --git a/cpukit/score/src/schedulerpercoresmpreadyqueueenqueue.c b/cpukit/score/src/schedulerpercoresmpreadyqueueenqueue.c
    new file mode 100644
    index 0000000..c198d14
    - +  
     1/*
     2 *  Schedule PerCoreSMP Handler / Ready Queue Enqueue
     3 *
     4 *  COPYRIGHT (c) 2011.
     5 *  On-Line Applications Research Corporation (OAR).
     6 *  COPYRIGHT (c) 2011.
     7 *  Kalray.
     8 *
     9 *  The license and distribution terms for this file may be
     10 *  found in the file LICENSE in this distribution or at
     11 *  http://www.rtems.com/license/LICENSE.
     12 *
     13 *  $Id$
     14 */
     15
     16#if HAVE_CONFIG_H
     17#include "config.h"
     18#endif
     19
     20#if defined(RTEMS_SMP)
     21
     22#include <rtems/system.h>
     23#include <rtems/score/chain.h>
     24#include <rtems/score/interr.h>
     25#include <rtems/score/isr.h>
     26#include <rtems/score/thread.h>
     27#include <rtems/score/schedulerpercoresmp.h>
     28
     29//#define LOCAL_DEBUG
     30
     31#ifdef LOCAL_DEBUG
     32#define D(format,...) printk( format, __VA_ARGS__)
     33#else
     34#define D(format,...)
     35#endif
     36
     37#ifdef LOCAL_DEBUG
     38static inline _Scheduler_PerCore_SMP_Show_chain(Chain_Control *ready, int core)
     39{
     40  Chain_Node *the_node = _Chain_First( ready );
     41  D( "SCHED core %d showing list %p\n -- \n", core, ready );
     42  for ( ; !_Chain_Is_tail( ready, the_node ) ; the_node = the_node->next ) {
     43    D( "SCHED element %p\n", the_node );
     44  }
     45  D( "--\nSCHED list end %d -- \n", core );
     46}
     47#else
     48static inline _Scheduler_PerCore_SMP_Show_chain(Chain_Control *ready, int core)
     49{
     50}
     51#endif
     52
     53void _Scheduler_PerCore_SMP_Ready_queue_Enqueue(
     54  Thread_Control    *the_thread
     55)
     56{
     57  Chain_Control    *ready;
     58  Chain_Node       *the_node;
     59  Thread_Control   *current;
     60  Scheduler_PerCore_SMP_Information *info;
     61  int core;
     62
     63  core = the_thread->core;
     64 
     65  info =  _Per_CPU_Information[core].scheduler_information;
     66  ready    = &(info->rq);
     67  the_node = _Chain_First( ready );
     68  current  = (Thread_Control *)the_node;
     69
     70  for ( ; !_Chain_Is_tail( ready, the_node ) ; the_node = the_node->next ) {
     71    current = (Thread_Control *) the_node;
     72
     73    /* break when AT END OR PAST our priority */
     74    if ( the_thread->current_priority < current->current_priority ) {
     75      current = (Thread_Control *)current->Object.Node.previous;
     76      break;
     77    }
     78  }
     79
     80  if (_Chain_Is_tail( ready, the_node))
     81  {
     82    /* Insert just after the head. Possibly we're inserting IDLE now */
     83    D( "SCHED core %d inserting head %p\n", core, the_thread );
     84    _Chain_Insert_unprotected( _Chain_Head(ready), &the_thread->Object.Node );
     85  }
     86  else
     87  {
     88    /* enqueue */
     89    D( "SCHED core %d inserting middle %p\n", core, the_thread );
     90    _Chain_Insert_unprotected( (Chain_Node *)current, &the_thread->Object.Node );
     91  }
     92  _Scheduler_PerCore_SMP_Show_chain(ready, core);
     93}
     94
     95#endif
  • new file cpukit/score/src/schedulerpercoresmpreadyqueueenqueuefirst.c

    diff --git a/cpukit/score/src/schedulerpercoresmpreadyqueueenqueuefirst.c b/cpukit/score/src/schedulerpercoresmpreadyqueueenqueuefirst.c
    new file mode 100644
    index 0000000..4ff7fc7
    - +  
     1/*
     2 *  Schedule PerCoreSMP Handler / Ready Queue Enqueue First
     3 *
     4 *  COPYRIGHT (c) 2011.
     5 *  On-Line Applications Research Corporation (OAR).
     6 *  COPYRIGHT (c) 2011.
     7 *  Kalray.
     8 *
     9 *  The license and distribution terms for this file may be
     10 *  found in the file LICENSE in this distribution or at
     11 *  http://www.rtems.com/license/LICENSE.
     12 *
     13 *  $Id$
     14 */
     15
     16#if HAVE_CONFIG_H
     17#include "config.h"
     18#endif
     19
     20#if defined(RTEMS_SMP)
     21
     22#include <rtems/system.h>
     23#include <rtems/score/chain.h>
     24#include <rtems/score/interr.h>
     25#include <rtems/score/thread.h>
     26#include <rtems/score/schedulerpercoresmp.h>
     27
     28void _Scheduler_PerCore_SMP_Ready_queue_Enqueue_first(
     29  Thread_Control    *the_thread
     30)
     31{
     32  Chain_Control    *ready;
     33  Chain_Node       *the_node;
     34  Thread_Control   *current;
     35  Scheduler_PerCore_SMP_Information *info;
     36  int core;
     37 
     38  core = the_thread->core;
     39 
     40  info =  _Per_CPU_Information[core].scheduler_information;
     41  ready    = &(info->rq);
     42  the_node = _Chain_First( ready );
     43  current  = (Thread_Control *)the_node;
     44
     45  /*
     46   * Do NOT need to check for end of chain because there is always
     47   * at least one task on the ready chain -- the IDLE task.  It can
     48   * never block, should never attempt to obtain a semaphore or mutex,
     49   * and thus will always be there.
     50   */
     51  for ( the_node = _Chain_First(ready) ; ; the_node = the_node->next ) {
     52    current = (Thread_Control *) the_node;
     53
     54    /* break when AT HEAD OF (or PAST) our priority */
     55    if ( the_thread->current_priority <= current->current_priority ) {
     56      current = (Thread_Control *)current->Object.Node.previous;
     57      break;
     58    }
     59  }
     60
     61  /* enqueue */
     62  _Chain_Insert_unprotected( (Chain_Node *)current, &the_thread->Object.Node );
     63}
     64
     65#endif
  • new file cpukit/score/src/schedulerpercoresmpschedule.c

    diff --git a/cpukit/score/src/schedulerpercoresmpschedule.c b/cpukit/score/src/schedulerpercoresmpschedule.c
    new file mode 100644
    index 0000000..0a3ce74
    - +  
     1/*
     2 *  Scheduler PerCore SMP Handler / Schedule
     3 *
     4 *  COPYRIGHT (c) 2011.
     5 *  On-Line Applications Research Corporation (OAR).
     6 *  COPYRIGHT (c) 2011.
     7 *  Kalray.
     8 *
     9 *  The license and distribution terms for this file may be
     10 *  found in found in the file LICENSE in this distribution or at
     11 *  http://www.rtems.com/license/LICENSE.
     12 *
     13 *  $Id$
     14 */
     15
     16#if HAVE_CONFIG_H
     17#include "config.h"
     18#endif
     19
     20#if defined(RTEMS_SMP)
     21
     22#include <rtems/system.h>
     23#include <rtems/score/context.h>
     24#include <rtems/score/interr.h>
     25#include <rtems/score/isr.h>
     26#include <rtems/score/object.h>
     27#include <rtems/score/priority.h>
     28#include <rtems/score/percpu.h>
     29#include <rtems/score/scheduler.h>
     30#include <rtems/score/thread.h>
     31#include <rtems/score/schedulerpercoresmp.h>
     32
     33void _Scheduler_PerCore_SMP_Schedule_unprotected(void)
     34{
     35  Scheduler_PerCore_SMP_Information *info;
     36  info = _Per_CPU_Information[bsp_smp_processor_id()].scheduler_information;
     37  _Per_CPU_Information[bsp_smp_processor_id()].heir = (Thread_Control *) _Chain_First( &(info->rq) );
     38}
     39
     40void _Scheduler_PerCore_SMP_Schedule(void)
     41{
     42  ISR_Level level;
     43  Scheduler_PerCore_SMP_Information *info;
     44  info = _Per_CPU_Information[bsp_smp_processor_id()].scheduler_information;
     45 
     46  level = _SMP_lock_spinlock_simple_Obtain( &(info->lock) );
     47  _Scheduler_PerCore_SMP_Schedule_unprotected();
     48  _SMP_lock_spinlock_simple_Release( &(info->lock), level );
     49}
     50
     51#endif
  • new file cpukit/score/src/schedulerpercoresmpunblock.c

    diff --git a/cpukit/score/src/schedulerpercoresmpunblock.c b/cpukit/score/src/schedulerpercoresmpunblock.c
    new file mode 100644
    index 0000000..93c5cc7
    - +  
     1/*
     2 *  Scheduler PerCore SMP Handler / Unblock
     3 *
     4 *  COPYRIGHT (c) 2011.
     5 *  On-Line Applications Research Corporation (OAR).
     6 *  COPYRIGHT (c) 2011.
     7 *  Kalray.
     8 *
     9 *  The license and distribution terms for this file may be
     10 *  found in found in the file LICENSE in this distribution or at
     11 *  http://www.rtems.com/license/LICENSE.
     12 *
     13 *  $Id$
     14 */
     15
     16#if HAVE_CONFIG_H
     17#include "config.h"
     18#endif
     19
     20#if defined(RTEMS_SMP)
     21
     22#include <rtems/system.h>
     23#include <rtems/score/interr.h>
     24#include <rtems/score/isr.h>
     25#include <rtems/score/schedulerpercoresmp.h>
     26#include <rtems/score/thread.h>
     27#include <rtems/score/smp.h>
     28
     29void _Scheduler_PerCore_SMP_Unblock(
     30  Thread_Control    *the_thread
     31)
     32{
     33  int core;
     34  ISR_Level       level;
     35  Scheduler_PerCore_SMP_Information *info;
     36
     37  core = the_thread->core;
     38  info = _Per_CPU_Information[core].scheduler_information;
     39 
     40  level = _SMP_lock_spinlock_simple_Obtain( &(info->lock) );
     41 
     42  _Scheduler_PerCore_SMP_Ready_queue_Enqueue(the_thread);
     43
     44  /*
     45   *  If the thread that was unblocked is more important than the heir,
     46   *  then we have a new heir.  This may or may not result in a
     47   *  context switch.
     48   *
     49   *  Normal case:
     50   *    If the current thread is preemptible, then we need to do
     51   *    a context switch.
     52   *  Pseudo-ISR case:
     53   *    Even if the thread isn't preemptible, if the new heir is
     54   *    a pseudo-ISR system task, we need to do a context switch.
     55   */
     56  if ( the_thread->current_priority <  _Per_CPU_Information[core].heir->current_priority ) {
     57    _Per_CPU_Information[core].heir = the_thread;
     58    if (  _Per_CPU_Information[core].executing->is_preemptible ||
     59        the_thread->current_priority == 0 ) {
     60       if (core == bsp_smp_processor_id())
     61         _Per_CPU_Information[core].dispatch_necessary = true;
     62       else
     63         rtems_smp_send_message( core, RTEMS_BSP_SMP_CONTEXT_SWITCH_NECESSARY );
     64    }
     65  }
     66  _SMP_lock_spinlock_simple_Release( &(info->lock), level );
     67}
     68
     69#endif
  • new file cpukit/score/src/schedulerpercoresmpyield.c

    diff --git a/cpukit/score/src/schedulerpercoresmpyield.c b/cpukit/score/src/schedulerpercoresmpyield.c
    new file mode 100644
    index 0000000..0d03c2c
    - +  
     1/*
     2 *  Scheduler PerCore SMP Handler / Yield
     3 *
     4 *  COPYRIGHT (c) 2011.
     5 *  On-Line Applications Research Corporation (OAR).
     6 *  COPYRIGHT (c) 2011.
     7 *  Kalray
     8 *
     9 *  The license and distribution terms for this file may be
     10 *  found in found in the file LICENSE in this distribution or at
     11 *  http://www.rtems.com/license/LICENSE.
     12 *
     13 *  $Id: schedulersimpleyield.c,v 1.1 2011/03/16 16:32:22 joel Exp $
     14 */
     15
     16#if HAVE_CONFIG_H
     17#include "config.h"
     18#endif
     19
     20#if defined(RTEMS_SMP)
     21
     22#include <rtems/system.h>
     23#include <rtems/score/isr.h>
     24#include <rtems/score/scheduler.h>
     25#include <rtems/score/thread.h>
     26#include <rtems/score/schedulerpercoresmp.h>
     27
     28void _Scheduler_PerCore_SMP_Yield( void )
     29{
     30  ISR_Level       level;
     31  Thread_Control *executing;
     32  Scheduler_PerCore_SMP_Information *info;
     33
     34  info = _Per_CPU_Information[bsp_smp_processor_id()].scheduler_information;
     35  level = _SMP_lock_spinlock_simple_Obtain( &(info->lock) );
     36 
     37  executing = _Per_CPU_Information[bsp_smp_processor_id()].executing;
     38 
     39  _Scheduler_PerCore_SMP_Ready_queue_Requeue(&_Scheduler, executing);
     40
     41  _Scheduler_PerCore_SMP_Schedule_unprotected();
     42 
     43  /* This is only on local core, so we do not send messages */
     44  if ( !_Thread_Is_heir( executing ) )
     45    _Per_CPU_Information[bsp_smp_processor_id()].dispatch_necessary = true;
     46
     47  _SMP_lock_spinlock_simple_Release ( &(info->lock), level );
     48}
     49
     50#endif