forked from Imagelibrary/rtems
score: Move priority bit map to scheduler instance
Delete global variables _Priority_Major_bit_map and _Priority_Bit_map. This makes it possible to use multiple priority scheduler instances for example with clustered/partitioned scheduling on SMP.
This commit is contained in:
@@ -676,7 +676,8 @@ const rtems_libio_helper rtems_fs_init_helper =
|
||||
*/
|
||||
#define CONFIGURE_MEMORY_FOR_SCHEDULER ( \
|
||||
_Configure_From_workspace( \
|
||||
((CONFIGURE_MAXIMUM_PRIORITY+1) * sizeof(Chain_Control)) ) \
|
||||
sizeof(Scheduler_priority_Control) + \
|
||||
((CONFIGURE_MAXIMUM_PRIORITY) * sizeof(Chain_Control)) ) \
|
||||
)
|
||||
#define CONFIGURE_MEMORY_PER_TASK_FOR_SCHEDULER ( \
|
||||
_Configure_From_workspace(sizeof(Scheduler_priority_Per_thread)) )
|
||||
@@ -695,7 +696,7 @@ const rtems_libio_helper rtems_fs_init_helper =
|
||||
*/
|
||||
#define CONFIGURE_MEMORY_FOR_SCHEDULER ( \
|
||||
_Configure_From_workspace( \
|
||||
sizeof(Scheduler_SMP_Control) + \
|
||||
sizeof(Scheduler_priority_SMP_Control) + \
|
||||
((CONFIGURE_MAXIMUM_PRIORITY) * sizeof(Chain_Control)) ) \
|
||||
)
|
||||
#define CONFIGURE_MEMORY_PER_TASK_FOR_SCHEDULER ( \
|
||||
@@ -731,7 +732,7 @@ const rtems_libio_helper rtems_fs_init_helper =
|
||||
* NOTE: This is the same as the Simple Scheduler
|
||||
*/
|
||||
#define CONFIGURE_MEMORY_FOR_SCHEDULER ( \
|
||||
_Configure_From_workspace( sizeof( Scheduler_SMP_Control ) ) \
|
||||
_Configure_From_workspace( sizeof( Scheduler_simple_SMP_Control ) ) \
|
||||
)
|
||||
#define CONFIGURE_MEMORY_PER_TASK_FOR_SCHEDULER (0)
|
||||
#endif
|
||||
|
||||
@@ -127,7 +127,6 @@ if HAS_SMP
|
||||
libscore_a_SOURCES += src/profilingsmplock.c
|
||||
libscore_a_SOURCES += src/schedulerprioritysmp.c
|
||||
libscore_a_SOURCES += src/schedulersimplesmp.c
|
||||
libscore_a_SOURCES += src/schedulersmpstartidle.c
|
||||
libscore_a_SOURCES += src/smp.c
|
||||
libscore_a_SOURCES += src/cpuset.c
|
||||
libscore_a_SOURCES += src/cpusetprintsupport.c
|
||||
@@ -191,7 +190,6 @@ libscore_a_SOURCES += src/objectallocate.c src/objectclose.c \
|
||||
|
||||
## SCHEDULER_C_FILES
|
||||
libscore_a_SOURCES += src/log2table.c
|
||||
libscore_a_SOURCES += src/prioritybitmap.c
|
||||
libscore_a_SOURCES += src/scheduler.c
|
||||
libscore_a_SOURCES += src/schedulerdefaultallocatefree.c
|
||||
libscore_a_SOURCES += src/schedulerdefaultreleasejob.c
|
||||
|
||||
@@ -37,6 +37,24 @@ extern "C" {
|
||||
*
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
/**
|
||||
* @brief Each sixteen bit entry in this word is associated with one of the
|
||||
* sixteen entries in the bit map.
|
||||
*/
|
||||
Priority_bit_map_Word major_bit_map;
|
||||
|
||||
/**
|
||||
* @brief Each bit in the bit map indicates whether or not there are threads
|
||||
* ready at a particular priority.
|
||||
*
|
||||
* The mapping of individual priority levels to particular bits is processor
|
||||
* dependent as is the value of each bit used to indicate that threads are
|
||||
* ready at that priority.
|
||||
*/
|
||||
Priority_bit_map_Word bit_map[ 16 ];
|
||||
} Priority_bit_map_Control;
|
||||
|
||||
/**
|
||||
* The following record defines the information associated with
|
||||
* each thread to manage its interaction with the priority bit maps.
|
||||
|
||||
@@ -22,6 +22,8 @@
|
||||
#include <rtems/score/prioritybitmap.h>
|
||||
#include <rtems/score/priority.h>
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
@@ -31,26 +33,6 @@ extern "C" {
|
||||
*/
|
||||
/**@{**/
|
||||
|
||||
/*
|
||||
* The Priority_bit_map_Word variables are instantiated only
|
||||
* if using the bit map handler.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Each sixteen bit entry in this array is associated with one of
|
||||
* the sixteen entries in the Priority Bit map.
|
||||
*/
|
||||
extern volatile Priority_bit_map_Word _Priority_Major_bit_map;
|
||||
|
||||
/** Each bit in the Priority Bitmap indicates whether or not there are
|
||||
* threads ready at a particular priority. The mapping of
|
||||
* individual priority levels to particular bits is processor
|
||||
* dependent as is the value of each bit used to indicate that
|
||||
* threads are ready at that priority.
|
||||
*/
|
||||
extern Priority_bit_map_Word
|
||||
_Priority_Bit_map[16] CPU_STRUCTURE_ALIGNMENT;
|
||||
|
||||
#if ( CPU_USE_GENERIC_BITFIELD_DATA == TRUE )
|
||||
|
||||
/**
|
||||
@@ -188,74 +170,67 @@ RTEMS_INLINE_ROUTINE uint32_t _Priority_Bits_index (
|
||||
|
||||
#endif
|
||||
|
||||
RTEMS_INLINE_ROUTINE void _Priority_bit_map_Initialize(
|
||||
Priority_bit_map_Control *bit_map
|
||||
)
|
||||
{
|
||||
memset( bit_map, 0, sizeof( *bit_map ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Priority Queue implemented by bit map
|
||||
*/
|
||||
|
||||
/**
|
||||
* This is the minor bit map.
|
||||
*/
|
||||
extern Priority_bit_map_Word _Priority_Bit_map[16] CPU_STRUCTURE_ALIGNMENT;
|
||||
|
||||
/**
|
||||
* This routine uses the_priority_map to update the priority
|
||||
* bit maps to indicate that a thread has been readied.
|
||||
*/
|
||||
|
||||
RTEMS_INLINE_ROUTINE void _Priority_bit_map_Add (
|
||||
Priority_bit_map_Information *the_priority_map
|
||||
Priority_bit_map_Control *bit_map,
|
||||
Priority_bit_map_Information *bit_map_info
|
||||
)
|
||||
{
|
||||
*the_priority_map->minor |= the_priority_map->ready_minor;
|
||||
_Priority_Major_bit_map |= the_priority_map->ready_major;
|
||||
*bit_map_info->minor |= bit_map_info->ready_minor;
|
||||
bit_map->major_bit_map |= bit_map_info->ready_major;
|
||||
}
|
||||
|
||||
/**
|
||||
* This routine uses the_priority_map to update the priority
|
||||
* bit maps to indicate that a thread has been removed from the
|
||||
* ready state.
|
||||
*/
|
||||
|
||||
RTEMS_INLINE_ROUTINE void _Priority_bit_map_Remove (
|
||||
Priority_bit_map_Information *the_priority_map
|
||||
Priority_bit_map_Control *bit_map,
|
||||
Priority_bit_map_Information *bit_map_info
|
||||
)
|
||||
{
|
||||
*the_priority_map->minor &= the_priority_map->block_minor;
|
||||
if ( *the_priority_map->minor == 0 )
|
||||
_Priority_Major_bit_map &= the_priority_map->block_major;
|
||||
*bit_map_info->minor &= bit_map_info->block_minor;
|
||||
if ( *bit_map_info->minor == 0 )
|
||||
bit_map->major_bit_map &= bit_map_info->block_major;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function returns the priority of the highest priority
|
||||
* ready thread.
|
||||
*/
|
||||
|
||||
RTEMS_INLINE_ROUTINE Priority_Control _Priority_bit_map_Get_highest( void )
|
||||
RTEMS_INLINE_ROUTINE Priority_Control _Priority_bit_map_Get_highest(
|
||||
const Priority_bit_map_Control *bit_map
|
||||
)
|
||||
{
|
||||
Priority_bit_map_Word minor;
|
||||
Priority_bit_map_Word major;
|
||||
|
||||
_Bitfield_Find_first_bit( _Priority_Major_bit_map, major );
|
||||
_Bitfield_Find_first_bit( _Priority_Bit_map[major], minor );
|
||||
/* Avoid problems with some inline ASM statements */
|
||||
Priority_bit_map_Word tmp;
|
||||
|
||||
tmp = bit_map->major_bit_map;
|
||||
_Bitfield_Find_first_bit( tmp, major );
|
||||
|
||||
tmp = bit_map->bit_map[ major ];
|
||||
_Bitfield_Find_first_bit( tmp, minor );
|
||||
|
||||
return (_Priority_Bits_index( major ) << 4) +
|
||||
_Priority_Bits_index( minor );
|
||||
}
|
||||
|
||||
RTEMS_INLINE_ROUTINE bool _Priority_bit_map_Is_empty( void )
|
||||
RTEMS_INLINE_ROUTINE bool _Priority_bit_map_Is_empty(
|
||||
const Priority_bit_map_Control *bit_map
|
||||
)
|
||||
{
|
||||
return _Priority_Major_bit_map == 0;
|
||||
return bit_map->major_bit_map == 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* This routine initializes the_priority_map so that it
|
||||
* contains the information necessary to manage a thread
|
||||
* at new_priority.
|
||||
*/
|
||||
|
||||
RTEMS_INLINE_ROUTINE void _Priority_bit_map_Initialize_information(
|
||||
Priority_bit_map_Information *the_priority_map,
|
||||
Priority_Control new_priority
|
||||
Priority_bit_map_Control *bit_map,
|
||||
Priority_bit_map_Information *bit_map_info,
|
||||
Priority_Control new_priority
|
||||
)
|
||||
{
|
||||
Priority_bit_map_Word major;
|
||||
@@ -265,18 +240,17 @@ RTEMS_INLINE_ROUTINE void _Priority_bit_map_Initialize_information(
|
||||
major = _Priority_Major( new_priority );
|
||||
minor = _Priority_Minor( new_priority );
|
||||
|
||||
the_priority_map->minor =
|
||||
&_Priority_Bit_map[ _Priority_Bits_index(major) ];
|
||||
bit_map_info->minor = &bit_map->bit_map[ _Priority_Bits_index( major ) ];
|
||||
|
||||
mask = _Priority_Mask( major );
|
||||
the_priority_map->ready_major = mask;
|
||||
bit_map_info->ready_major = mask;
|
||||
/* Add _Priority_Mask_invert to non-generic bitfield then change this code. */
|
||||
the_priority_map->block_major = (Priority_bit_map_Word)(~((uint32_t)mask));
|
||||
bit_map_info->block_major = (Priority_bit_map_Word)(~((uint32_t)mask));
|
||||
|
||||
mask = _Priority_Mask( minor );
|
||||
the_priority_map->ready_minor = mask;
|
||||
bit_map_info->ready_minor = mask;
|
||||
/* Add _Priority_Mask_invert to non-generic bitfield then change this code. */
|
||||
the_priority_map->block_minor = (Priority_bit_map_Word)(~((uint32_t)mask));
|
||||
bit_map_info->block_minor = (Priority_bit_map_Word)(~((uint32_t)mask));
|
||||
}
|
||||
|
||||
/** @} */
|
||||
|
||||
@@ -56,6 +56,18 @@ extern "C" {
|
||||
_Scheduler_default_Start_idle /* start idle entry point */ \
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
/**
|
||||
* @brief Bit map to indicate non-empty ready queues.
|
||||
*/
|
||||
Priority_bit_map_Control Bit_map;
|
||||
|
||||
/**
|
||||
* @brief One ready queue per priority level.
|
||||
*/
|
||||
Chain_Control Ready[ 1 ];
|
||||
} Scheduler_priority_Control;
|
||||
|
||||
/**
|
||||
* Per-thread data related to the _Scheduler_PRIORITY scheduling policy.
|
||||
*/
|
||||
|
||||
@@ -35,16 +35,16 @@ extern "C" {
|
||||
*/
|
||||
/**@{**/
|
||||
|
||||
RTEMS_INLINE_ROUTINE Chain_Control *
|
||||
_Scheduler_priority_Get_ready_queues( void )
|
||||
RTEMS_INLINE_ROUTINE Scheduler_priority_Control *
|
||||
_Scheduler_priority_Instance( void )
|
||||
{
|
||||
return ( Chain_Control * ) _Scheduler.information;
|
||||
return _Scheduler.information;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Ready queue initialization.
|
||||
*
|
||||
* This routine initializes @a the_ready_queue for priority-based scheduling.
|
||||
* This routine initializes @a ready_queues for priority-based scheduling.
|
||||
*/
|
||||
RTEMS_INLINE_ROUTINE void _Scheduler_priority_Ready_queue_initialize(
|
||||
Chain_Control *ready_queues
|
||||
@@ -68,10 +68,12 @@ _Scheduler_priority_Get_scheduler_info( Thread_Control *thread )
|
||||
*
|
||||
* This routine puts @a the_thread on to the priority-based ready queue.
|
||||
*
|
||||
* @param[in] the_thread is a pointer to the thread
|
||||
* @param[in] the_thread The thread to enqueue.
|
||||
* @param[in] bit_map The priority bit map of the scheduler instance.
|
||||
*/
|
||||
RTEMS_INLINE_ROUTINE void _Scheduler_priority_Ready_queue_enqueue(
|
||||
Thread_Control *the_thread
|
||||
Thread_Control *the_thread,
|
||||
Priority_bit_map_Control *bit_map
|
||||
)
|
||||
{
|
||||
Scheduler_priority_Per_thread *sched_info_of_thread =
|
||||
@@ -79,7 +81,7 @@ RTEMS_INLINE_ROUTINE void _Scheduler_priority_Ready_queue_enqueue(
|
||||
Chain_Control *ready_chain = sched_info_of_thread->ready_chain;
|
||||
|
||||
_Chain_Append_unprotected( ready_chain, &the_thread->Object.Node );
|
||||
_Priority_bit_map_Add( &sched_info_of_thread->Priority_map );
|
||||
_Priority_bit_map_Add( bit_map, &sched_info_of_thread->Priority_map );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -89,10 +91,12 @@ RTEMS_INLINE_ROUTINE void _Scheduler_priority_Ready_queue_enqueue(
|
||||
* For priority-based ready queues, the thread will be the first thread
|
||||
* at its priority level.
|
||||
*
|
||||
* @param[in] the_thread is a pointer to the thread.
|
||||
* @param[in] the_thread The thread to enqueue.
|
||||
* @param[in] bit_map The priority bit map of the scheduler instance.
|
||||
*/
|
||||
RTEMS_INLINE_ROUTINE void _Scheduler_priority_Ready_queue_enqueue_first(
|
||||
Thread_Control *the_thread
|
||||
Thread_Control *the_thread,
|
||||
Priority_bit_map_Control *bit_map
|
||||
)
|
||||
{
|
||||
Scheduler_priority_Per_thread *sched_info_of_thread =
|
||||
@@ -100,7 +104,7 @@ RTEMS_INLINE_ROUTINE void _Scheduler_priority_Ready_queue_enqueue_first(
|
||||
Chain_Control *ready_chain = sched_info_of_thread->ready_chain;
|
||||
|
||||
_Chain_Prepend_unprotected( ready_chain, &the_thread->Object.Node );
|
||||
_Priority_bit_map_Add( &sched_info_of_thread->Priority_map );
|
||||
_Priority_bit_map_Add( bit_map, &sched_info_of_thread->Priority_map );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -109,10 +113,12 @@ RTEMS_INLINE_ROUTINE void _Scheduler_priority_Ready_queue_enqueue_first(
|
||||
* This routine removes a specific thread from the specified
|
||||
* priority-based ready queue.
|
||||
*
|
||||
* @param[in] the_thread is a pointer to the thread.
|
||||
* @param[in] the_thread The thread to extract.
|
||||
* @param[in] bit_map The priority bit map of the scheduler instance.
|
||||
*/
|
||||
RTEMS_INLINE_ROUTINE void _Scheduler_priority_Ready_queue_extract(
|
||||
Thread_Control *the_thread
|
||||
Thread_Control *the_thread,
|
||||
Priority_bit_map_Control *bit_map
|
||||
)
|
||||
{
|
||||
Scheduler_priority_Per_thread *sched_info_of_thread =
|
||||
@@ -121,28 +127,39 @@ RTEMS_INLINE_ROUTINE void _Scheduler_priority_Ready_queue_extract(
|
||||
|
||||
if ( _Chain_Has_only_one_node( ready_chain ) ) {
|
||||
_Chain_Initialize_empty( ready_chain );
|
||||
_Priority_bit_map_Remove( &sched_info_of_thread->Priority_map );
|
||||
_Priority_bit_map_Remove( bit_map, &sched_info_of_thread->Priority_map );
|
||||
} else {
|
||||
_Chain_Extract_unprotected( &the_thread->Object.Node );
|
||||
}
|
||||
}
|
||||
|
||||
RTEMS_INLINE_ROUTINE void _Scheduler_priority_Extract_body(
|
||||
Thread_Control *the_thread
|
||||
)
|
||||
{
|
||||
Scheduler_priority_Control *scheduler = _Scheduler_priority_Instance();
|
||||
|
||||
_Scheduler_priority_Ready_queue_extract( the_thread, &scheduler->Bit_map );
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Return a pointer to the first thread.
|
||||
*
|
||||
* This routines returns a pointer to the first thread on @a the_ready_queue.
|
||||
* This routines returns a pointer to the first thread on @a ready_queues.
|
||||
*
|
||||
* @param[in] the_ready_queue - pointer to thread queue
|
||||
* @param[in] bit_map The priority bit map of the scheduler instance.
|
||||
* @param[in] ready_queues The ready queues of the scheduler instance.
|
||||
*
|
||||
* @return This method returns the first thread or NULL
|
||||
*/
|
||||
RTEMS_INLINE_ROUTINE Thread_Control *_Scheduler_priority_Ready_queue_first(
|
||||
Chain_Control *the_ready_queue
|
||||
Priority_bit_map_Control *bit_map,
|
||||
Chain_Control *ready_queues
|
||||
)
|
||||
{
|
||||
Priority_Control index = _Priority_bit_map_Get_highest();
|
||||
Priority_Control index = _Priority_bit_map_Get_highest( bit_map );
|
||||
|
||||
return (Thread_Control *) _Chain_First( &the_ready_queue[ index ] );
|
||||
return (Thread_Control *) _Chain_First( &ready_queues[ index ] );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -178,8 +195,11 @@ RTEMS_INLINE_ROUTINE void _Scheduler_priority_Schedule_body(
|
||||
bool force_dispatch
|
||||
)
|
||||
{
|
||||
Chain_Control *ready_queues = _Scheduler_priority_Get_ready_queues();
|
||||
Thread_Control *heir = _Scheduler_priority_Ready_queue_first( ready_queues );
|
||||
Scheduler_priority_Control *scheduler = _Scheduler_priority_Instance();
|
||||
Thread_Control *heir = _Scheduler_priority_Ready_queue_first(
|
||||
&scheduler->Bit_map,
|
||||
&scheduler->Ready[ 0 ]
|
||||
);
|
||||
|
||||
( void ) thread;
|
||||
|
||||
@@ -187,8 +207,9 @@ RTEMS_INLINE_ROUTINE void _Scheduler_priority_Schedule_body(
|
||||
}
|
||||
|
||||
RTEMS_INLINE_ROUTINE void _Scheduler_priority_Update_body(
|
||||
Thread_Control *thread,
|
||||
Chain_Control *ready_queues
|
||||
Thread_Control *thread,
|
||||
Priority_bit_map_Control *bit_map,
|
||||
Chain_Control *ready_queues
|
||||
)
|
||||
{
|
||||
Scheduler_priority_Per_thread *sched_info_of_thread =
|
||||
@@ -198,6 +219,7 @@ RTEMS_INLINE_ROUTINE void _Scheduler_priority_Update_body(
|
||||
&ready_queues[ thread->current_priority ];
|
||||
|
||||
_Priority_bit_map_Initialize_information(
|
||||
bit_map,
|
||||
&sched_info_of_thread->Priority_map,
|
||||
thread->current_priority
|
||||
);
|
||||
|
||||
@@ -66,7 +66,7 @@ extern "C" {
|
||||
_Scheduler_priority_Priority_compare, \
|
||||
_Scheduler_default_Release_job, \
|
||||
_Scheduler_default_Tick, \
|
||||
_Scheduler_SMP_Start_idle \
|
||||
_Scheduler_priority_SMP_Start_idle \
|
||||
}
|
||||
|
||||
void _Scheduler_priority_SMP_Initialize( void );
|
||||
@@ -85,6 +85,11 @@ void _Scheduler_priority_SMP_Extract( Thread_Control *thread );
|
||||
|
||||
void _Scheduler_priority_SMP_Yield( Thread_Control *thread );
|
||||
|
||||
void _Scheduler_priority_SMP_Start_idle(
|
||||
Thread_Control *thread,
|
||||
Per_CPU_Control *cpu
|
||||
);
|
||||
|
||||
/** @} */
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
@@ -68,7 +68,7 @@ extern "C" {
|
||||
_Scheduler_priority_Priority_compare, \
|
||||
_Scheduler_default_Release_job, \
|
||||
_Scheduler_default_Tick, \
|
||||
_Scheduler_SMP_Start_idle \
|
||||
_Scheduler_simple_smp_Start_idle \
|
||||
}
|
||||
|
||||
void _Scheduler_simple_smp_Initialize( void );
|
||||
@@ -85,6 +85,11 @@ void _Scheduler_simple_smp_Yield( Thread_Control *thread );
|
||||
|
||||
void _Scheduler_simple_smp_Schedule( Thread_Control *thread );
|
||||
|
||||
void _Scheduler_simple_smp_Start_idle(
|
||||
Thread_Control *thread,
|
||||
Per_CPU_Control *cpu
|
||||
);
|
||||
|
||||
/** @} */
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 2013 embedded brains GmbH. All rights reserved.
|
||||
* Copyright (c) 2013-2014 embedded brains GmbH. All rights reserved.
|
||||
*
|
||||
* embedded brains GmbH
|
||||
* Dornierstr. 4
|
||||
@@ -25,6 +25,7 @@
|
||||
|
||||
#include <rtems/score/chain.h>
|
||||
#include <rtems/score/percpu.h>
|
||||
#include <rtems/score/prioritybitmap.h>
|
||||
#include <rtems/score/thread.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
@@ -40,14 +41,19 @@ extern "C" {
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
Chain_Control scheduled;
|
||||
Chain_Control ready[ 1 ];
|
||||
Chain_Control Scheduled;
|
||||
} Scheduler_SMP_Control;
|
||||
|
||||
void _Scheduler_SMP_Start_idle(
|
||||
Thread_Control *thread,
|
||||
Per_CPU_Control *cpu
|
||||
);
|
||||
typedef struct {
|
||||
Scheduler_SMP_Control Base;
|
||||
Chain_Control Ready;
|
||||
} Scheduler_simple_SMP_Control;
|
||||
|
||||
typedef struct {
|
||||
Scheduler_SMP_Control Base;
|
||||
Priority_bit_map_Control Bit_map;
|
||||
Chain_Control Ready[ 1 ];
|
||||
} Scheduler_priority_SMP_Control;
|
||||
|
||||
/** @} */
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 2013 embedded brains GmbH. All rights reserved.
|
||||
* Copyright (c) 2013-2014 embedded brains GmbH. All rights reserved.
|
||||
*
|
||||
* embedded brains GmbH
|
||||
* Dornierstr. 4
|
||||
@@ -57,9 +57,11 @@ typedef void ( *Scheduler_SMP_Move )(
|
||||
Thread_Control *thread_to_move
|
||||
);
|
||||
|
||||
static inline Scheduler_SMP_Control *_Scheduler_SMP_Instance( void )
|
||||
static inline void _Scheduler_SMP_Initialize(
|
||||
Scheduler_SMP_Control *self
|
||||
)
|
||||
{
|
||||
return _Scheduler.information;
|
||||
_Chain_Initialize_empty( &self->Scheduled );
|
||||
}
|
||||
|
||||
static inline void _Scheduler_SMP_Allocate_processor(
|
||||
@@ -109,7 +111,7 @@ static inline Thread_Control *_Scheduler_SMP_Get_lowest_scheduled(
|
||||
)
|
||||
{
|
||||
Thread_Control *lowest_ready = NULL;
|
||||
Chain_Control *scheduled = &self->scheduled;
|
||||
Chain_Control *scheduled = &self->Scheduled;
|
||||
|
||||
if ( !_Chain_Is_empty( scheduled ) ) {
|
||||
lowest_ready = (Thread_Control *) _Chain_Last( scheduled );
|
||||
@@ -244,7 +246,7 @@ static inline void _Scheduler_SMP_Insert_scheduled_lifo(
|
||||
)
|
||||
{
|
||||
_Chain_Insert_ordered_unprotected(
|
||||
&self->scheduled,
|
||||
&self->Scheduled,
|
||||
&thread->Object.Node,
|
||||
_Scheduler_simple_Insert_priority_lifo_order
|
||||
);
|
||||
@@ -256,12 +258,23 @@ static inline void _Scheduler_SMP_Insert_scheduled_fifo(
|
||||
)
|
||||
{
|
||||
_Chain_Insert_ordered_unprotected(
|
||||
&self->scheduled,
|
||||
&self->Scheduled,
|
||||
&thread->Object.Node,
|
||||
_Scheduler_simple_Insert_priority_fifo_order
|
||||
);
|
||||
}
|
||||
|
||||
static inline void _Scheduler_SMP_Start_idle(
|
||||
Scheduler_SMP_Control *self,
|
||||
Thread_Control *thread,
|
||||
Per_CPU_Control *cpu
|
||||
)
|
||||
{
|
||||
thread->is_scheduled = true;
|
||||
_Thread_Set_CPU( thread, cpu );
|
||||
_Chain_Append_unprotected( &self->Scheduled, &thread->Object.Node );
|
||||
}
|
||||
|
||||
/** @} */
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
@@ -1,27 +0,0 @@
|
||||
/*
|
||||
* @file
|
||||
*
|
||||
* @brief Priority Bit Map Implementation
|
||||
*
|
||||
* @ingroup ScorePriorityBitmap
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2010 Gedare Bloom.
|
||||
* Copyright (C) 2011 On-Line Applications Research Corporation (OAR).
|
||||
*
|
||||
* The license and distribution terms for this file may be
|
||||
* found in the file LICENSE in this distribution or at
|
||||
* http://www.rtems.org/license/LICENSE.
|
||||
*/
|
||||
|
||||
#if HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <rtems/score/prioritybitmapimpl.h>
|
||||
|
||||
Priority_bit_map_Word _Priority_Bit_map[16] CPU_STRUCTURE_ALIGNMENT;
|
||||
|
||||
/* Instantiate any global variables needed by the priority scheduler */
|
||||
volatile Priority_bit_map_Word _Priority_Major_bit_map;
|
||||
@@ -23,12 +23,12 @@
|
||||
|
||||
void _Scheduler_priority_Initialize(void)
|
||||
{
|
||||
/* allocate ready queue structures */
|
||||
Chain_Control *ready_queues = _Workspace_Allocate_or_fatal_error(
|
||||
((size_t) PRIORITY_MAXIMUM + 1) * sizeof(Chain_Control)
|
||||
Scheduler_priority_Control *self = _Workspace_Allocate_or_fatal_error(
|
||||
sizeof( *self ) + PRIORITY_MAXIMUM * sizeof( Chain_Control )
|
||||
);
|
||||
|
||||
_Scheduler_priority_Ready_queue_initialize( ready_queues );
|
||||
_Priority_bit_map_Initialize( &self->Bit_map );
|
||||
_Scheduler_priority_Ready_queue_initialize( &self->Ready[ 0 ] );
|
||||
|
||||
_Scheduler.information = ready_queues;
|
||||
_Scheduler.information = self;
|
||||
}
|
||||
|
||||
@@ -22,12 +22,10 @@
|
||||
|
||||
#include <rtems/score/schedulerpriorityimpl.h>
|
||||
|
||||
void _Scheduler_priority_Block(
|
||||
Thread_Control *the_thread
|
||||
)
|
||||
void _Scheduler_priority_Block( Thread_Control *the_thread )
|
||||
{
|
||||
_Scheduler_Generic_block(
|
||||
_Scheduler_priority_Ready_queue_extract,
|
||||
_Scheduler_priority_Extract_body,
|
||||
_Scheduler_priority_Schedule_body,
|
||||
the_thread
|
||||
);
|
||||
|
||||
@@ -24,5 +24,7 @@ void _Scheduler_priority_Enqueue(
|
||||
Thread_Control *the_thread
|
||||
)
|
||||
{
|
||||
_Scheduler_priority_Ready_queue_enqueue( the_thread );
|
||||
Scheduler_priority_Control *scheduler = _Scheduler_priority_Instance();
|
||||
|
||||
_Scheduler_priority_Ready_queue_enqueue( the_thread, &scheduler->Bit_map );
|
||||
}
|
||||
|
||||
@@ -24,6 +24,11 @@ void _Scheduler_priority_Enqueue_first(
|
||||
Thread_Control *the_thread
|
||||
)
|
||||
{
|
||||
_Scheduler_priority_Ready_queue_enqueue_first( the_thread );
|
||||
Scheduler_priority_Control *scheduler = _Scheduler_priority_Instance();
|
||||
|
||||
_Scheduler_priority_Ready_queue_enqueue_first(
|
||||
the_thread,
|
||||
&scheduler->Bit_map
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -21,9 +21,7 @@
|
||||
|
||||
#include <rtems/score/schedulerpriorityimpl.h>
|
||||
|
||||
void _Scheduler_priority_Extract(
|
||||
Thread_Control *the_thread
|
||||
)
|
||||
void _Scheduler_priority_Extract( Thread_Control *the_thread )
|
||||
{
|
||||
_Scheduler_priority_Ready_queue_extract( the_thread );
|
||||
_Scheduler_priority_Extract_body( the_thread );
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 2013 embedded brains GmbH. All rights reserved.
|
||||
* Copyright (c) 2013-2014 embedded brains GmbH. All rights reserved.
|
||||
*
|
||||
* embedded brains GmbH
|
||||
* Dornierstr. 4
|
||||
@@ -29,100 +29,141 @@
|
||||
#include <rtems/score/schedulersmpimpl.h>
|
||||
#include <rtems/score/wkspace.h>
|
||||
|
||||
static Scheduler_priority_SMP_Control *_Scheduler_priority_SMP_Instance( void )
|
||||
{
|
||||
return _Scheduler.information;
|
||||
}
|
||||
|
||||
static Scheduler_priority_SMP_Control *
|
||||
_Scheduler_priority_SMP_Self_from_SMP_base( Scheduler_SMP_Control *base )
|
||||
{
|
||||
return (Scheduler_priority_SMP_Control *)
|
||||
( (char *) base
|
||||
- offsetof( Scheduler_priority_SMP_Control, Base ) );
|
||||
}
|
||||
|
||||
void _Scheduler_priority_SMP_Initialize( void )
|
||||
{
|
||||
Scheduler_SMP_Control *self = _Workspace_Allocate_or_fatal_error(
|
||||
Scheduler_priority_SMP_Control *self = _Workspace_Allocate_or_fatal_error(
|
||||
sizeof( *self ) + PRIORITY_MAXIMUM * sizeof( Chain_Control )
|
||||
);
|
||||
|
||||
_Chain_Initialize_empty( &self->scheduled );
|
||||
_Scheduler_priority_Ready_queue_initialize( &self->ready[ 0 ] );
|
||||
_Scheduler_SMP_Initialize( &self->Base );
|
||||
_Priority_bit_map_Initialize( &self->Bit_map );
|
||||
_Scheduler_priority_Ready_queue_initialize( &self->Ready[ 0 ] );
|
||||
|
||||
_Scheduler.information = self;
|
||||
}
|
||||
|
||||
void _Scheduler_priority_SMP_Update( Thread_Control *thread )
|
||||
{
|
||||
Scheduler_SMP_Control *self = _Scheduler_SMP_Instance();
|
||||
Scheduler_priority_SMP_Control *self = _Scheduler_priority_SMP_Instance();
|
||||
|
||||
_Scheduler_priority_Update_body( thread, &self->ready[ 0 ] );
|
||||
_Scheduler_priority_Update_body(
|
||||
thread,
|
||||
&self->Bit_map,
|
||||
&self->Ready[ 0 ]
|
||||
);
|
||||
}
|
||||
|
||||
static Thread_Control *_Scheduler_priority_SMP_Get_highest_ready(
|
||||
Scheduler_SMP_Control *self
|
||||
Scheduler_SMP_Control *base
|
||||
)
|
||||
{
|
||||
Scheduler_priority_SMP_Control *self =
|
||||
_Scheduler_priority_SMP_Self_from_SMP_base( base );
|
||||
Thread_Control *highest_ready = NULL;
|
||||
|
||||
if ( !_Priority_bit_map_Is_empty() ) {
|
||||
highest_ready = _Scheduler_priority_Ready_queue_first( &self->ready[ 0 ] );
|
||||
if ( !_Priority_bit_map_Is_empty( &self->Bit_map ) ) {
|
||||
highest_ready = _Scheduler_priority_Ready_queue_first(
|
||||
&self->Bit_map,
|
||||
&self->Ready[ 0 ]
|
||||
);
|
||||
}
|
||||
|
||||
return highest_ready;
|
||||
}
|
||||
|
||||
static void _Scheduler_priority_SMP_Move_from_scheduled_to_ready(
|
||||
Scheduler_SMP_Control *self,
|
||||
Scheduler_SMP_Control *base,
|
||||
Thread_Control *scheduled_to_ready
|
||||
)
|
||||
{
|
||||
Scheduler_priority_SMP_Control *self =
|
||||
_Scheduler_priority_SMP_Self_from_SMP_base( base );
|
||||
|
||||
_Chain_Extract_unprotected( &scheduled_to_ready->Object.Node );
|
||||
_Scheduler_priority_Ready_queue_enqueue_first( scheduled_to_ready );
|
||||
_Scheduler_priority_Ready_queue_enqueue_first(
|
||||
scheduled_to_ready,
|
||||
&self->Bit_map
|
||||
);
|
||||
}
|
||||
|
||||
static void _Scheduler_priority_SMP_Move_from_ready_to_scheduled(
|
||||
Scheduler_SMP_Control *self,
|
||||
Scheduler_SMP_Control *base,
|
||||
Thread_Control *ready_to_scheduled
|
||||
)
|
||||
{
|
||||
_Scheduler_priority_Ready_queue_extract( ready_to_scheduled );
|
||||
Scheduler_priority_SMP_Control *self =
|
||||
_Scheduler_priority_SMP_Self_from_SMP_base( base );
|
||||
|
||||
_Scheduler_priority_Ready_queue_extract(
|
||||
ready_to_scheduled,
|
||||
&self->Bit_map
|
||||
);
|
||||
_Scheduler_simple_Insert_priority_fifo(
|
||||
&self->scheduled,
|
||||
&self->Base.Scheduled,
|
||||
ready_to_scheduled
|
||||
);
|
||||
}
|
||||
|
||||
static void _Scheduler_priority_SMP_Insert_ready_lifo(
|
||||
Scheduler_SMP_Control *self,
|
||||
Scheduler_SMP_Control *base,
|
||||
Thread_Control *thread
|
||||
)
|
||||
{
|
||||
_Scheduler_priority_Ready_queue_enqueue( thread );
|
||||
Scheduler_priority_SMP_Control *self =
|
||||
_Scheduler_priority_SMP_Self_from_SMP_base( base );
|
||||
|
||||
_Scheduler_priority_Ready_queue_enqueue( thread, &self->Bit_map );
|
||||
}
|
||||
|
||||
static void _Scheduler_priority_SMP_Insert_ready_fifo(
|
||||
Scheduler_SMP_Control *self,
|
||||
Scheduler_SMP_Control *base,
|
||||
Thread_Control *thread
|
||||
)
|
||||
{
|
||||
_Scheduler_priority_Ready_queue_enqueue_first( thread );
|
||||
Scheduler_priority_SMP_Control *self =
|
||||
_Scheduler_priority_SMP_Self_from_SMP_base( base );
|
||||
|
||||
_Scheduler_priority_Ready_queue_enqueue_first( thread, &self->Bit_map );
|
||||
}
|
||||
|
||||
static void _Scheduler_priority_SMP_Do_extract(
|
||||
Scheduler_SMP_Control *self,
|
||||
Scheduler_SMP_Control *base,
|
||||
Thread_Control *thread
|
||||
)
|
||||
{
|
||||
Scheduler_priority_SMP_Control *self =
|
||||
_Scheduler_priority_SMP_Self_from_SMP_base( base );
|
||||
bool is_scheduled = thread->is_scheduled;
|
||||
|
||||
( void ) self;
|
||||
|
||||
thread->is_in_the_air = is_scheduled;
|
||||
thread->is_scheduled = false;
|
||||
|
||||
if ( is_scheduled ) {
|
||||
_Chain_Extract_unprotected( &thread->Object.Node );
|
||||
} else {
|
||||
_Scheduler_priority_Ready_queue_extract( thread );
|
||||
_Scheduler_priority_Ready_queue_extract( thread, &self->Bit_map );
|
||||
}
|
||||
}
|
||||
|
||||
void _Scheduler_priority_SMP_Block( Thread_Control *thread )
|
||||
{
|
||||
Scheduler_SMP_Control *self = _Scheduler_SMP_Instance();
|
||||
Scheduler_priority_SMP_Control *self = _Scheduler_priority_SMP_Instance();
|
||||
|
||||
_Scheduler_SMP_Block(
|
||||
self,
|
||||
&self->Base,
|
||||
thread,
|
||||
_Scheduler_priority_SMP_Do_extract,
|
||||
_Scheduler_priority_SMP_Get_highest_ready,
|
||||
@@ -152,10 +193,10 @@ static void _Scheduler_priority_SMP_Enqueue_ordered(
|
||||
|
||||
void _Scheduler_priority_SMP_Enqueue_lifo( Thread_Control *thread )
|
||||
{
|
||||
Scheduler_SMP_Control *self = _Scheduler_SMP_Instance();
|
||||
Scheduler_priority_SMP_Control *self = _Scheduler_priority_SMP_Instance();
|
||||
|
||||
_Scheduler_priority_SMP_Enqueue_ordered(
|
||||
self,
|
||||
&self->Base,
|
||||
thread,
|
||||
_Scheduler_simple_Insert_priority_lifo_order,
|
||||
_Scheduler_priority_SMP_Insert_ready_lifo,
|
||||
@@ -165,10 +206,10 @@ void _Scheduler_priority_SMP_Enqueue_lifo( Thread_Control *thread )
|
||||
|
||||
void _Scheduler_priority_SMP_Enqueue_fifo( Thread_Control *thread )
|
||||
{
|
||||
Scheduler_SMP_Control *self = _Scheduler_SMP_Instance();
|
||||
Scheduler_priority_SMP_Control *self = _Scheduler_priority_SMP_Instance();
|
||||
|
||||
_Scheduler_priority_SMP_Enqueue_ordered(
|
||||
self,
|
||||
&self->Base,
|
||||
thread,
|
||||
_Scheduler_simple_Insert_priority_fifo_order,
|
||||
_Scheduler_priority_SMP_Insert_ready_fifo,
|
||||
@@ -178,10 +219,10 @@ void _Scheduler_priority_SMP_Enqueue_fifo( Thread_Control *thread )
|
||||
|
||||
void _Scheduler_priority_SMP_Extract( Thread_Control *thread )
|
||||
{
|
||||
Scheduler_SMP_Control *self = _Scheduler_SMP_Instance();
|
||||
Scheduler_priority_SMP_Control *self = _Scheduler_priority_SMP_Instance();
|
||||
|
||||
_Scheduler_SMP_Extract(
|
||||
self,
|
||||
&self->Base,
|
||||
thread,
|
||||
_Scheduler_priority_SMP_Do_extract
|
||||
);
|
||||
@@ -201,12 +242,22 @@ void _Scheduler_priority_SMP_Yield( Thread_Control *thread )
|
||||
|
||||
void _Scheduler_priority_SMP_Schedule( Thread_Control *thread )
|
||||
{
|
||||
Scheduler_SMP_Control *self = _Scheduler_SMP_Instance();
|
||||
Scheduler_priority_SMP_Control *self = _Scheduler_priority_SMP_Instance();
|
||||
|
||||
_Scheduler_SMP_Schedule(
|
||||
self,
|
||||
&self->Base,
|
||||
thread,
|
||||
_Scheduler_priority_SMP_Get_highest_ready,
|
||||
_Scheduler_priority_SMP_Move_from_ready_to_scheduled
|
||||
);
|
||||
}
|
||||
|
||||
void _Scheduler_priority_SMP_Start_idle(
|
||||
Thread_Control *thread,
|
||||
Per_CPU_Control *cpu
|
||||
)
|
||||
{
|
||||
Scheduler_priority_SMP_Control *self = _Scheduler_priority_SMP_Instance();
|
||||
|
||||
_Scheduler_SMP_Start_idle( &self->Base, thread, cpu );
|
||||
}
|
||||
|
||||
@@ -26,7 +26,9 @@ void _Scheduler_priority_Unblock (
|
||||
Thread_Control *the_thread
|
||||
)
|
||||
{
|
||||
_Scheduler_priority_Ready_queue_enqueue(the_thread);
|
||||
Scheduler_priority_Control *scheduler = _Scheduler_priority_Instance();
|
||||
|
||||
_Scheduler_priority_Ready_queue_enqueue( the_thread, &scheduler->Bit_map );
|
||||
|
||||
/* TODO: flash critical section? */
|
||||
|
||||
|
||||
@@ -25,7 +25,11 @@ void _Scheduler_priority_Update(
|
||||
Thread_Control *the_thread
|
||||
)
|
||||
{
|
||||
Chain_Control *ready_queues = _Scheduler_priority_Get_ready_queues();
|
||||
Scheduler_priority_Control *scheduler = _Scheduler_priority_Instance();
|
||||
|
||||
_Scheduler_priority_Update_body( the_thread, ready_queues );
|
||||
_Scheduler_priority_Update_body(
|
||||
the_thread,
|
||||
&scheduler->Bit_map,
|
||||
&scheduler->Ready[ 0 ]
|
||||
);
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 2013 embedded brains GmbH.
|
||||
* Copyright (c) 2013-2014 embedded brains GmbH.
|
||||
*
|
||||
* The license and distribution terms for this file may be
|
||||
* found in the file LICENSE in this distribution or at
|
||||
@@ -22,23 +22,37 @@
|
||||
#include <rtems/score/schedulersmpimpl.h>
|
||||
#include <rtems/score/wkspace.h>
|
||||
|
||||
static Scheduler_simple_SMP_Control *_Scheduler_simple_SMP_Instance( void )
|
||||
{
|
||||
return _Scheduler.information;
|
||||
}
|
||||
|
||||
static Scheduler_simple_SMP_Control *
|
||||
_Scheduler_simple_SMP_Self_from_SMP_base( Scheduler_SMP_Control *base )
|
||||
{
|
||||
return (Scheduler_simple_SMP_Control *)
|
||||
( (char *) base - offsetof( Scheduler_simple_SMP_Control, Base ) );
|
||||
}
|
||||
|
||||
void _Scheduler_simple_smp_Initialize( void )
|
||||
{
|
||||
Scheduler_SMP_Control *self =
|
||||
Scheduler_simple_SMP_Control *self =
|
||||
_Workspace_Allocate_or_fatal_error( sizeof( *self ) );
|
||||
|
||||
_Chain_Initialize_empty( &self->ready[ 0 ] );
|
||||
_Chain_Initialize_empty( &self->scheduled );
|
||||
_Scheduler_SMP_Initialize( &self->Base );
|
||||
_Chain_Initialize_empty( &self->Ready );
|
||||
|
||||
_Scheduler.information = self;
|
||||
}
|
||||
|
||||
static Thread_Control *_Scheduler_simple_smp_Get_highest_ready(
|
||||
Scheduler_SMP_Control *self
|
||||
Scheduler_SMP_Control *base
|
||||
)
|
||||
{
|
||||
Scheduler_simple_SMP_Control *self =
|
||||
_Scheduler_simple_SMP_Self_from_SMP_base( base );
|
||||
Thread_Control *highest_ready = NULL;
|
||||
Chain_Control *ready = &self->ready[ 0 ];
|
||||
Chain_Control *ready = &self->Ready;
|
||||
|
||||
if ( !_Chain_Is_empty( ready ) ) {
|
||||
highest_ready = (Thread_Control *) _Chain_First( ready );
|
||||
@@ -48,59 +62,68 @@ static Thread_Control *_Scheduler_simple_smp_Get_highest_ready(
|
||||
}
|
||||
|
||||
static void _Scheduler_simple_smp_Move_from_scheduled_to_ready(
|
||||
Scheduler_SMP_Control *self,
|
||||
Scheduler_SMP_Control *base,
|
||||
Thread_Control *scheduled_to_ready
|
||||
)
|
||||
{
|
||||
Scheduler_simple_SMP_Control *self =
|
||||
_Scheduler_simple_SMP_Self_from_SMP_base( base );
|
||||
|
||||
_Chain_Extract_unprotected( &scheduled_to_ready->Object.Node );
|
||||
_Scheduler_simple_Insert_priority_lifo(
|
||||
&self->ready[ 0 ],
|
||||
&self->Ready,
|
||||
scheduled_to_ready
|
||||
);
|
||||
}
|
||||
|
||||
static void _Scheduler_simple_smp_Move_from_ready_to_scheduled(
|
||||
Scheduler_SMP_Control *self,
|
||||
Scheduler_SMP_Control *base,
|
||||
Thread_Control *ready_to_scheduled
|
||||
)
|
||||
{
|
||||
_Chain_Extract_unprotected( &ready_to_scheduled->Object.Node );
|
||||
_Scheduler_simple_Insert_priority_fifo(
|
||||
&self->scheduled,
|
||||
&base->Scheduled,
|
||||
ready_to_scheduled
|
||||
);
|
||||
}
|
||||
|
||||
static void _Scheduler_simple_smp_Insert_ready_lifo(
|
||||
Scheduler_SMP_Control *self,
|
||||
Scheduler_SMP_Control *base,
|
||||
Thread_Control *thread
|
||||
)
|
||||
{
|
||||
Scheduler_simple_SMP_Control *self =
|
||||
_Scheduler_simple_SMP_Self_from_SMP_base( base );
|
||||
|
||||
_Chain_Insert_ordered_unprotected(
|
||||
&self->ready[ 0 ],
|
||||
&self->Ready,
|
||||
&thread->Object.Node,
|
||||
_Scheduler_simple_Insert_priority_lifo_order
|
||||
);
|
||||
}
|
||||
|
||||
static void _Scheduler_simple_smp_Insert_ready_fifo(
|
||||
Scheduler_SMP_Control *self,
|
||||
Scheduler_SMP_Control *base,
|
||||
Thread_Control *thread
|
||||
)
|
||||
{
|
||||
Scheduler_simple_SMP_Control *self =
|
||||
_Scheduler_simple_SMP_Self_from_SMP_base( base );
|
||||
|
||||
_Chain_Insert_ordered_unprotected(
|
||||
&self->ready[ 0 ],
|
||||
&self->Ready,
|
||||
&thread->Object.Node,
|
||||
_Scheduler_simple_Insert_priority_fifo_order
|
||||
);
|
||||
}
|
||||
|
||||
static void _Scheduler_simple_smp_Do_extract(
|
||||
Scheduler_SMP_Control *self,
|
||||
Scheduler_SMP_Control *base,
|
||||
Thread_Control *thread
|
||||
)
|
||||
{
|
||||
( void ) self;
|
||||
(void) base;
|
||||
|
||||
thread->is_in_the_air = thread->is_scheduled;
|
||||
thread->is_scheduled = false;
|
||||
@@ -110,10 +133,10 @@ static void _Scheduler_simple_smp_Do_extract(
|
||||
|
||||
void _Scheduler_simple_smp_Block( Thread_Control *thread )
|
||||
{
|
||||
Scheduler_SMP_Control *self = _Scheduler_SMP_Instance();
|
||||
Scheduler_simple_SMP_Control *self = _Scheduler_simple_SMP_Instance();
|
||||
|
||||
_Scheduler_SMP_Block(
|
||||
self,
|
||||
&self->Base,
|
||||
thread,
|
||||
_Scheduler_simple_smp_Do_extract,
|
||||
_Scheduler_simple_smp_Get_highest_ready,
|
||||
@@ -122,7 +145,7 @@ void _Scheduler_simple_smp_Block( Thread_Control *thread )
|
||||
}
|
||||
|
||||
static void _Scheduler_simple_smp_Enqueue_ordered(
|
||||
Scheduler_SMP_Control *self,
|
||||
Scheduler_SMP_Control *base,
|
||||
Thread_Control *thread,
|
||||
Chain_Node_order order,
|
||||
Scheduler_SMP_Insert insert_ready,
|
||||
@@ -130,7 +153,7 @@ static void _Scheduler_simple_smp_Enqueue_ordered(
|
||||
)
|
||||
{
|
||||
_Scheduler_SMP_Enqueue_ordered(
|
||||
self,
|
||||
base,
|
||||
thread,
|
||||
order,
|
||||
_Scheduler_simple_smp_Get_highest_ready,
|
||||
@@ -143,10 +166,10 @@ static void _Scheduler_simple_smp_Enqueue_ordered(
|
||||
|
||||
void _Scheduler_simple_smp_Enqueue_priority_lifo( Thread_Control *thread )
|
||||
{
|
||||
Scheduler_SMP_Control *self = _Scheduler_SMP_Instance();
|
||||
Scheduler_simple_SMP_Control *self = _Scheduler_simple_SMP_Instance();
|
||||
|
||||
_Scheduler_simple_smp_Enqueue_ordered(
|
||||
self,
|
||||
&self->Base,
|
||||
thread,
|
||||
_Scheduler_simple_Insert_priority_lifo_order,
|
||||
_Scheduler_simple_smp_Insert_ready_lifo,
|
||||
@@ -156,10 +179,10 @@ void _Scheduler_simple_smp_Enqueue_priority_lifo( Thread_Control *thread )
|
||||
|
||||
void _Scheduler_simple_smp_Enqueue_priority_fifo( Thread_Control *thread )
|
||||
{
|
||||
Scheduler_SMP_Control *self = _Scheduler_SMP_Instance();
|
||||
Scheduler_simple_SMP_Control *self = _Scheduler_simple_SMP_Instance();
|
||||
|
||||
_Scheduler_simple_smp_Enqueue_ordered(
|
||||
self,
|
||||
&self->Base,
|
||||
thread,
|
||||
_Scheduler_simple_Insert_priority_fifo_order,
|
||||
_Scheduler_simple_smp_Insert_ready_fifo,
|
||||
@@ -169,10 +192,10 @@ void _Scheduler_simple_smp_Enqueue_priority_fifo( Thread_Control *thread )
|
||||
|
||||
void _Scheduler_simple_smp_Extract( Thread_Control *thread )
|
||||
{
|
||||
Scheduler_SMP_Control *self = _Scheduler_SMP_Instance();
|
||||
Scheduler_simple_SMP_Control *self = _Scheduler_simple_SMP_Instance();
|
||||
|
||||
_Scheduler_SMP_Extract(
|
||||
self,
|
||||
&self->Base,
|
||||
thread,
|
||||
_Scheduler_simple_smp_Do_extract
|
||||
);
|
||||
@@ -192,12 +215,22 @@ void _Scheduler_simple_smp_Yield( Thread_Control *thread )
|
||||
|
||||
void _Scheduler_simple_smp_Schedule( Thread_Control *thread )
|
||||
{
|
||||
Scheduler_SMP_Control *self = _Scheduler_SMP_Instance();
|
||||
Scheduler_simple_SMP_Control *self = _Scheduler_simple_SMP_Instance();
|
||||
|
||||
_Scheduler_SMP_Schedule(
|
||||
self,
|
||||
&self->Base,
|
||||
thread,
|
||||
_Scheduler_simple_smp_Get_highest_ready,
|
||||
_Scheduler_simple_smp_Move_from_ready_to_scheduled
|
||||
);
|
||||
}
|
||||
|
||||
void _Scheduler_simple_smp_Start_idle(
|
||||
Thread_Control *thread,
|
||||
Per_CPU_Control *cpu
|
||||
)
|
||||
{
|
||||
Scheduler_simple_SMP_Control *self = _Scheduler_simple_SMP_Instance();
|
||||
|
||||
_Scheduler_SMP_Start_idle( &self->Base, thread, cpu );
|
||||
}
|
||||
|
||||
@@ -1,40 +0,0 @@
|
||||
/**
|
||||
* @file
|
||||
*
|
||||
* @brief SMP Scheduler Start Idle Operation
|
||||
*
|
||||
* @ingroup ScoreSchedulerSMP
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 2013 embedded brains GmbH. All rights reserved.
|
||||
*
|
||||
* embedded brains GmbH
|
||||
* Dornierstr. 4
|
||||
* 82178 Puchheim
|
||||
* Germany
|
||||
* <rtems@embedded-brains.de>
|
||||
*
|
||||
* The license and distribution terms for this file may be
|
||||
* found in the file LICENSE in this distribution or at
|
||||
* http://www.rtems.org/license/LICENSE.
|
||||
*/
|
||||
|
||||
#if HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <rtems/score/schedulersmpimpl.h>
|
||||
#include <rtems/score/chainimpl.h>
|
||||
|
||||
void _Scheduler_SMP_Start_idle(
|
||||
Thread_Control *thread,
|
||||
Per_CPU_Control *cpu
|
||||
)
|
||||
{
|
||||
Scheduler_SMP_Control *self = _Scheduler_SMP_Instance();
|
||||
|
||||
thread->is_scheduled = true;
|
||||
_Thread_Set_CPU( thread, cpu );
|
||||
_Chain_Append_unprotected( &self->scheduled, &thread->Object.Node );
|
||||
}
|
||||
@@ -85,9 +85,7 @@ void print_formula(void);
|
||||
#include <rtems/score/schedulerpriority.h>
|
||||
|
||||
/* Priority scheduling uninitialized (globals) consumption */
|
||||
#define SCHEDULER_OVHD ((sizeof _Scheduler) + \
|
||||
(sizeof _Priority_Major_bit_map) + \
|
||||
(sizeof _Priority_Bit_map))
|
||||
#define SCHEDULER_OVHD (sizeof _Scheduler)
|
||||
|
||||
/* Priority scheduling per-thread consumption. Gets
|
||||
* included in the PER_TASK consumption.
|
||||
@@ -100,7 +98,8 @@ void print_formula(void);
|
||||
* including _Scheduler in SCHEDULER_OVHD.
|
||||
*/
|
||||
#define SCHEDULER_WKSP_SIZE \
|
||||
((RTEMS_MAXIMUM_PRIORITY + 1) * sizeof(Chain_Control ))
|
||||
(sizeof(Scheduler_priority_Control) + \
|
||||
RTEMS_MAXIMUM_PRIORITY * sizeof(Chain_Control ))
|
||||
/****** END OF MEMORY USAGE OF DEFAULT PRIORITY SCHEDULER ******/
|
||||
|
||||
#define PER_TASK \
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
#include <tmacros.h>
|
||||
#include <timesys.h>
|
||||
|
||||
#include <rtems/score/schedulerpriorityimpl.h>
|
||||
#include <rtems/rtems/semimpl.h>
|
||||
|
||||
#if defined( RTEMS_SMP ) && defined( RTEMS_DEBUG )
|
||||
@@ -370,7 +371,7 @@ rtems_task Middle_task(
|
||||
rtems_task_argument argument
|
||||
)
|
||||
{
|
||||
Chain_Control *ready_queues;
|
||||
Scheduler_priority_Control *scheduler = _Scheduler_priority_Instance();
|
||||
|
||||
thread_dispatch_no_fp_time = benchmark_timer_read();
|
||||
|
||||
@@ -378,9 +379,8 @@ rtems_task Middle_task(
|
||||
|
||||
Middle_tcb = _Thread_Get_executing();
|
||||
|
||||
ready_queues = (Chain_Control *) _Scheduler.information;
|
||||
set_thread_executing(
|
||||
(Thread_Control *) _Chain_First(&ready_queues[LOW_PRIORITY])
|
||||
(Thread_Control *) _Chain_First(&scheduler->Ready[LOW_PRIORITY])
|
||||
);
|
||||
|
||||
/* do not force context switch */
|
||||
@@ -403,10 +403,8 @@ rtems_task Low_task(
|
||||
rtems_task_argument argument
|
||||
)
|
||||
{
|
||||
Thread_Control *executing;
|
||||
Chain_Control *ready_queues;
|
||||
|
||||
ready_queues = (Chain_Control *) _Scheduler.information;
|
||||
Scheduler_priority_Control *scheduler = _Scheduler_priority_Instance();
|
||||
Thread_Control *executing;
|
||||
|
||||
context_switch_no_fp_time = benchmark_timer_read();
|
||||
|
||||
@@ -424,7 +422,7 @@ rtems_task Low_task(
|
||||
context_switch_another_task_time = benchmark_timer_read();
|
||||
|
||||
set_thread_executing(
|
||||
(Thread_Control *) _Chain_First(&ready_queues[FP1_PRIORITY])
|
||||
(Thread_Control *) _Chain_First(&scheduler->Ready[FP1_PRIORITY])
|
||||
);
|
||||
|
||||
/* do not force context switch */
|
||||
@@ -447,17 +445,16 @@ rtems_task Floating_point_task_1(
|
||||
rtems_task_argument argument
|
||||
)
|
||||
{
|
||||
Chain_Control *ready_queues;
|
||||
Thread_Control *executing;
|
||||
Scheduler_priority_Control *scheduler = _Scheduler_priority_Instance();
|
||||
Thread_Control *executing;
|
||||
FP_DECLARE;
|
||||
|
||||
context_switch_restore_1st_fp_time = benchmark_timer_read();
|
||||
|
||||
executing = _Thread_Get_executing();
|
||||
|
||||
ready_queues = (Chain_Control *) _Scheduler.information;
|
||||
set_thread_executing(
|
||||
(Thread_Control *) _Chain_First(&ready_queues[FP2_PRIORITY])
|
||||
(Thread_Control *) _Chain_First(&scheduler->Ready[FP2_PRIORITY])
|
||||
);
|
||||
|
||||
/* do not force context switch */
|
||||
@@ -483,9 +480,8 @@ rtems_task Floating_point_task_1(
|
||||
|
||||
executing = _Thread_Get_executing();
|
||||
|
||||
ready_queues = (Chain_Control *) _Scheduler.information;
|
||||
set_thread_executing(
|
||||
(Thread_Control *) _Chain_First(&ready_queues[FP2_PRIORITY])
|
||||
(Thread_Control *) _Chain_First(&scheduler->Ready[FP2_PRIORITY])
|
||||
);
|
||||
|
||||
benchmark_timer_initialize();
|
||||
@@ -504,17 +500,16 @@ rtems_task Floating_point_task_2(
|
||||
rtems_task_argument argument
|
||||
)
|
||||
{
|
||||
Chain_Control *ready_queues;
|
||||
Thread_Control *executing;
|
||||
Scheduler_priority_Control *scheduler = _Scheduler_priority_Instance();
|
||||
Thread_Control *executing;
|
||||
FP_DECLARE;
|
||||
|
||||
context_switch_save_restore_idle_time = benchmark_timer_read();
|
||||
|
||||
executing = _Thread_Get_executing();
|
||||
|
||||
ready_queues = (Chain_Control *) _Scheduler.information;
|
||||
set_thread_executing(
|
||||
(Thread_Control *) _Chain_First(&ready_queues[FP1_PRIORITY])
|
||||
(Thread_Control *) _Chain_First(&scheduler->Ready[FP1_PRIORITY])
|
||||
);
|
||||
|
||||
FP_LOAD( 1.0 );
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
#define CONFIGURE_INIT
|
||||
#include "system.h"
|
||||
|
||||
#include <rtems/score/schedulerpriorityimpl.h>
|
||||
#include <bsp.h>
|
||||
|
||||
#define _RTEMS_TMTEST27
|
||||
@@ -101,10 +102,10 @@ rtems_task Task_1(
|
||||
rtems_task_argument argument
|
||||
)
|
||||
{
|
||||
Scheduler_priority_Control *scheduler = _Scheduler_priority_Instance();
|
||||
#if defined(RTEMS_SMP)
|
||||
rtems_interrupt_level level;
|
||||
#endif
|
||||
Chain_Control *ready_queues;
|
||||
|
||||
Install_tm27_vector( Isr_handler );
|
||||
|
||||
@@ -185,9 +186,8 @@ rtems_task Task_1(
|
||||
_ISR_Disable_without_giant(level);
|
||||
#endif
|
||||
|
||||
ready_queues = (Chain_Control *) _Scheduler.information;
|
||||
_Thread_Executing =
|
||||
(Thread_Control *) _Chain_First(&ready_queues[LOW_PRIORITY]);
|
||||
(Thread_Control *) _Chain_First(&scheduler->Ready[LOW_PRIORITY]);
|
||||
|
||||
_Thread_Dispatch_necessary = 1;
|
||||
|
||||
@@ -219,10 +219,10 @@ rtems_task Task_2(
|
||||
rtems_task_argument argument
|
||||
)
|
||||
{
|
||||
Scheduler_priority_Control *scheduler = _Scheduler_priority_Instance();
|
||||
#if defined(RTEMS_SMP)
|
||||
rtems_interrupt_level level;
|
||||
#endif
|
||||
Chain_Control *ready_queues;
|
||||
|
||||
#if (MUST_WAIT_FOR_INTERRUPT == 1)
|
||||
while ( Interrupt_occurred == 0 );
|
||||
@@ -255,9 +255,8 @@ rtems_task Task_2(
|
||||
rtems_interrupt_disable(level);
|
||||
#endif
|
||||
|
||||
ready_queues = (Chain_Control *) _Scheduler.information;
|
||||
_Thread_Executing =
|
||||
(Thread_Control *) _Chain_First(&ready_queues[LOW_PRIORITY]);
|
||||
(Thread_Control *) _Chain_First(&scheduler->Ready[LOW_PRIORITY]);
|
||||
|
||||
_Thread_Dispatch_necessary = 1;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user