From 77ff5599e0d8e6d91190a379be21a332f83252b0 Mon Sep 17 00:00:00 2001 From: Sebastian Huber Date: Fri, 10 Jun 2016 08:48:54 +0200 Subject: score: Introduce map priority scheduler operation Introduce map/unmap priority scheduler operations to map thread priority values from/to the user domain to/from the scheduler domain. Use the map priority operation to validate the thread priority. The EDF schedulers use this new operation to distinguish between normal priorities and priorities obtain through a job release. Update #2173. Update #2556. --- cpukit/libmisc/monitor/mon-sema.c | 6 +- cpukit/posix/include/rtems/posix/priorityimpl.h | 7 +-- cpukit/posix/src/mutexgetprioceiling.c | 12 ++-- cpukit/posix/src/mutexinit.c | 9 +-- cpukit/posix/src/mutexsetprioceiling.c | 39 ++++++------ cpukit/posix/src/psxpriorityisvalid.c | 13 +++- cpukit/posix/src/pthreadcreate.c | 3 +- cpukit/rtems/include/rtems/rtems/tasksimpl.h | 7 ++- cpukit/rtems/src/semcreate.c | 2 + cpukit/rtems/src/semsetpriority.c | 69 ++++++++++++++-------- cpukit/score/Makefile.am | 1 + cpukit/score/include/rtems/score/coremutex.h | 9 +++ cpukit/score/include/rtems/score/coremuteximpl.h | 42 +++++++++++++ cpukit/score/include/rtems/score/mrspimpl.h | 46 ++++++++++----- cpukit/score/include/rtems/score/scheduler.h | 27 +++++++++ cpukit/score/include/rtems/score/schedulercbs.h | 2 + cpukit/score/include/rtems/score/scheduleredf.h | 12 ++++ cpukit/score/include/rtems/score/schedulerimpl.h | 37 ++++++++++++ .../score/include/rtems/score/schedulerpriority.h | 2 + .../rtems/score/schedulerpriorityaffinitysmp.h | 2 + .../include/rtems/score/schedulerprioritysmp.h | 2 + cpukit/score/include/rtems/score/schedulersimple.h | 2 + .../score/include/rtems/score/schedulersimplesmp.h | 2 + .../score/include/rtems/score/schedulerstrongapa.h | 2 + cpukit/score/include/rtems/score/status.h | 3 + cpukit/score/src/schedulerdefaultmappriority.c | 21 +++++++ cpukit/score/src/scheduleredfchangepriority.c | 16 +++++ cpukit/score/src/threadcreateidle.c | 4 +- 28 files changed, 317 insertions(+), 82 deletions(-) create mode 100644 cpukit/score/src/schedulerdefaultmappriority.c (limited to 'cpukit') diff --git a/cpukit/libmisc/monitor/mon-sema.c b/cpukit/libmisc/monitor/mon-sema.c index 272391f01e..7334611465 100644 --- a/cpukit/libmisc/monitor/mon-sema.c +++ b/cpukit/libmisc/monitor/mon-sema.c @@ -61,8 +61,10 @@ rtems_monitor_sema_canonical( switch ( rtems_sema->variant ) { case SEMAPHORE_VARIANT_MUTEX_PRIORITY_CEILING: - canonical_sema->priority_ceiling = - rtems_sema->Core_control.Mutex.priority_ceiling; + canonical_sema->priority_ceiling = _Scheduler_Unmap_priority( + _CORE_ceiling_mutex_Get_scheduler( &rtems_sema->Core_control.Mutex ), + _CORE_ceiling_mutex_Get_priority( &rtems_sema->Core_control.Mutex ) + ); /* Fall through */ case SEMAPHORE_VARIANT_MUTEX_INHERIT_PRIORITY: case SEMAPHORE_VARIANT_MUTEX_NO_PROTOCOL: diff --git a/cpukit/posix/include/rtems/posix/priorityimpl.h b/cpukit/posix/include/rtems/posix/priorityimpl.h index ae2e763fba..b986d64cd5 100644 --- a/cpukit/posix/include/rtems/posix/priorityimpl.h +++ b/cpukit/posix/include/rtems/posix/priorityimpl.h @@ -88,13 +88,10 @@ Priority_Control _POSIX_Priority_To_core( * * @return The corresponding POSIX API priority. */ -RTEMS_INLINE_ROUTINE int _POSIX_Priority_From_core( +int _POSIX_Priority_From_core( const Scheduler_Control *scheduler, Priority_Control priority -) -{ - return (int) ( scheduler->maximum_priority - priority ); -} +); /** @} */ diff --git a/cpukit/posix/src/mutexgetprioceiling.c b/cpukit/posix/src/mutexgetprioceiling.c index eda02cba83..dfff98f9b7 100644 --- a/cpukit/posix/src/mutexgetprioceiling.c +++ b/cpukit/posix/src/mutexgetprioceiling.c @@ -45,10 +45,14 @@ int pthread_mutex_getprioceiling( _POSIX_Mutex_Acquire_critical( the_mutex, &queue_context ); - *prioceiling = _POSIX_Priority_From_core( - &_Scheduler_Table[ 0 ], - the_mutex->Mutex.priority_ceiling - ); + if ( the_mutex->protocol == POSIX_MUTEX_PRIORITY_CEILING ) { + *prioceiling = _POSIX_Priority_From_core( + _CORE_ceiling_mutex_Get_scheduler( &the_mutex->Mutex ), + _CORE_ceiling_mutex_Get_priority( &the_mutex->Mutex ) + ); + } else { + *prioceiling = 0; + } _POSIX_Mutex_Release( the_mutex, &queue_context ); diff --git a/cpukit/posix/src/mutexinit.c b/cpukit/posix/src/mutexinit.c index 2cda90ea05..0dacc3fa03 100644 --- a/cpukit/posix/src/mutexinit.c +++ b/cpukit/posix/src/mutexinit.c @@ -135,19 +135,14 @@ int pthread_mutex_init( switch ( protocol ) { case POSIX_MUTEX_PRIORITY_CEILING: - _CORE_ceiling_mutex_Initialize( - &the_mutex->Mutex, - priority - ); + _CORE_ceiling_mutex_Initialize( &the_mutex->Mutex, scheduler, priority ); break; default: _Assert( the_mutex->protocol == POSIX_MUTEX_NO_PROTOCOL || the_mutex->protocol == POSIX_MUTEX_PRIORITY_INHERIT ); - _CORE_recursive_mutex_Initialize( - &the_mutex->Mutex.Recursive - ); + _CORE_recursive_mutex_Initialize( &the_mutex->Mutex.Recursive ); break; } diff --git a/cpukit/posix/src/mutexsetprioceiling.c b/cpukit/posix/src/mutexsetprioceiling.c index 478aafa6e0..31e54c5fc3 100644 --- a/cpukit/posix/src/mutexsetprioceiling.c +++ b/cpukit/posix/src/mutexsetprioceiling.c @@ -31,15 +31,13 @@ int pthread_mutex_setprioceiling( int *old_ceiling ) { - POSIX_Mutex_Control *the_mutex; - const Scheduler_Control *scheduler; - bool valid; - Priority_Control priority; - int error; - int unlock_error; + POSIX_Mutex_Control *the_mutex; + int error; + int unlock_error; - if ( !old_ceiling ) + if ( old_ceiling == NULL ) { return EINVAL; + } /* * Must acquire the mutex before we can change it's ceiling. @@ -54,19 +52,26 @@ int pthread_mutex_setprioceiling( the_mutex = _POSIX_Mutex_Get_no_protection( mutex ); _Assert( the_mutex != NULL ); - scheduler = &_Scheduler_Table[ 0 ]; + if ( the_mutex->protocol == POSIX_MUTEX_PRIORITY_CEILING ) { + const Scheduler_Control *scheduler; + bool valid; + Priority_Control new_priority; + Priority_Control old_priority; - *old_ceiling = _POSIX_Priority_From_core( - scheduler, - the_mutex->Mutex.priority_ceiling - ); + scheduler = _CORE_ceiling_mutex_Get_scheduler( &the_mutex->Mutex ); + old_priority = _CORE_ceiling_mutex_Get_priority( &the_mutex->Mutex ); + *old_ceiling = _POSIX_Priority_From_core( scheduler, old_priority ); - priority = _POSIX_Priority_To_core( scheduler, prioceiling, &valid ); - if ( valid ) { - the_mutex->Mutex.priority_ceiling = priority; - error = 0; + new_priority = _POSIX_Priority_To_core( scheduler, prioceiling, &valid ); + if ( valid ) { + _CORE_ceiling_mutex_Set_priority( &the_mutex->Mutex, new_priority ); + error = 0; + } else { + error = EINVAL; + } } else { - error = EINVAL; + *old_ceiling = 0; + error = 0; } unlock_error = pthread_mutex_unlock( mutex ); diff --git a/cpukit/posix/src/psxpriorityisvalid.c b/cpukit/posix/src/psxpriorityisvalid.c index 22c4ac0b87..7c2300b4d6 100644 --- a/cpukit/posix/src/psxpriorityisvalid.c +++ b/cpukit/posix/src/psxpriorityisvalid.c @@ -19,6 +19,7 @@ #endif #include +#include int _POSIX_Priority_Get_maximum( const Scheduler_Control *scheduler ) { @@ -44,5 +45,15 @@ Priority_Control _POSIX_Priority_To_core( *valid = ( posix_priority >= POSIX_SCHEDULER_MINIMUM_PRIORITY && core_posix_priority < scheduler->maximum_priority ); - return core_priority; + return _Scheduler_Map_priority( scheduler, core_priority ); +} + +int _POSIX_Priority_From_core( + const Scheduler_Control *scheduler, + Priority_Control core_priority +) +{ + core_priority = _Scheduler_Unmap_priority( scheduler, core_priority ); + + return (int) ( scheduler->maximum_priority - core_priority ); } diff --git a/cpukit/posix/src/pthreadcreate.c b/cpukit/posix/src/pthreadcreate.c index b266a4cd7f..54b6a71040 100644 --- a/cpukit/posix/src/pthreadcreate.c +++ b/cpukit/posix/src/pthreadcreate.c @@ -103,6 +103,7 @@ int pthread_create( #endif executing = _Thread_Get_executing(); + scheduler = _Scheduler_Get_own( executing ); /* * P1003.1c/Draft 10, p. 121. @@ -197,7 +198,7 @@ int pthread_create( status = _Thread_Initialize( &_POSIX_Threads_Information, the_thread, - _Scheduler_Get( executing ), + scheduler, the_attr->stackaddr, _POSIX_Threads_Ensure_minimum_stack(the_attr->stacksize), is_fp, diff --git a/cpukit/rtems/include/rtems/rtems/tasksimpl.h b/cpukit/rtems/include/rtems/rtems/tasksimpl.h index c7f8952bcf..b0432351f3 100644 --- a/cpukit/rtems/include/rtems/rtems/tasksimpl.h +++ b/cpukit/rtems/include/rtems/rtems/tasksimpl.h @@ -19,7 +19,7 @@ #include #include -#include +#include #include #ifdef __cplusplus @@ -96,7 +96,7 @@ RTEMS_INLINE_ROUTINE Priority_Control _RTEMS_Priority_To_core( { *valid = ( priority <= scheduler->maximum_priority ); - return (Priority_Control) priority; + return _Scheduler_Map_priority( scheduler, (Priority_Control) priority ); } /** @@ -113,7 +113,8 @@ RTEMS_INLINE_ROUTINE rtems_task_priority _RTEMS_Priority_From_core( Priority_Control priority ) { - return (rtems_task_priority) priority; + return (rtems_task_priority) + _Scheduler_Unmap_priority( scheduler, priority ); } /**@}*/ diff --git a/cpukit/rtems/src/semcreate.c b/cpukit/rtems/src/semcreate.c index f03475ee33..7d49542203 100644 --- a/cpukit/rtems/src/semcreate.c +++ b/cpukit/rtems/src/semcreate.c @@ -163,6 +163,7 @@ rtems_status_code rtems_semaphore_create( if ( valid ) { _CORE_ceiling_mutex_Initialize( &the_semaphore->Core_control.Mutex, + scheduler, priority ); @@ -200,6 +201,7 @@ rtems_status_code rtems_semaphore_create( if ( valid ) { status = _MRSP_Initialize( &the_semaphore->Core_control.MRSP, + scheduler, priority, executing, count == 0 diff --git a/cpukit/rtems/src/semsetpriority.c b/cpukit/rtems/src/semsetpriority.c index 37d7a207ca..5c331bb292 100644 --- a/cpukit/rtems/src/semsetpriority.c +++ b/cpukit/rtems/src/semsetpriority.c @@ -20,6 +20,20 @@ #include #include +static rtems_status_code _Semaphore_Is_scheduler_valid( + const CORE_ceiling_mutex_Control *the_mutex, + const Scheduler_Control *scheduler +) +{ +#if defined(RTEMS_SMP) + if ( scheduler != _CORE_ceiling_mutex_Get_scheduler( the_mutex ) ) { + return RTEMS_NOT_DEFINED; + } +#endif + + return RTEMS_SUCCESSFUL; +} + static rtems_status_code _Semaphore_Set_priority( Semaphore_Control *the_semaphore, const Scheduler_Control *scheduler, @@ -32,49 +46,51 @@ static rtems_status_code _Semaphore_Set_priority( bool valid; Priority_Control core_priority; Priority_Control old_priority; -#if defined(RTEMS_SMP) - MRSP_Control *mrsp; - uint32_t scheduler_index; -#endif core_priority = _RTEMS_Priority_To_core( scheduler, new_priority, &valid ); if ( new_priority != RTEMS_CURRENT_PRIORITY && !valid ) { return RTEMS_INVALID_PRIORITY; } + _Thread_queue_Acquire_critical( + &the_semaphore->Core_control.Wait_queue, + &queue_context->Lock_context + ); + switch ( the_semaphore->variant ) { case SEMAPHORE_VARIANT_MUTEX_PRIORITY_CEILING: - _CORE_mutex_Acquire_critical( - &the_semaphore->Core_control.Mutex.Recursive.Mutex, - queue_context + sc = _Semaphore_Is_scheduler_valid( + &the_semaphore->Core_control.Mutex, + scheduler ); - old_priority = the_semaphore->Core_control.Mutex.priority_ceiling; + old_priority = _CORE_ceiling_mutex_Get_priority( + &the_semaphore->Core_control.Mutex + ); - if ( new_priority != RTEMS_CURRENT_PRIORITY ) { - the_semaphore->Core_control.Mutex.priority_ceiling = core_priority; + if ( sc == RTEMS_SUCCESSFUL && new_priority != RTEMS_CURRENT_PRIORITY ) { + _CORE_ceiling_mutex_Set_priority( + &the_semaphore->Core_control.Mutex, + core_priority + ); } - _CORE_mutex_Release( - &the_semaphore->Core_control.Mutex.Recursive.Mutex, - queue_context - ); - sc = RTEMS_SUCCESSFUL; break; #if defined(RTEMS_SMP) case SEMAPHORE_VARIANT_MRSP: - mrsp = &the_semaphore->Core_control.MRSP; - scheduler_index = _Scheduler_Get_index( scheduler ); - - _MRSP_Acquire_critical( mrsp, queue_context ); - - old_priority = _MRSP_Get_ceiling_priority( mrsp, scheduler_index ); + old_priority = _MRSP_Get_priority( + &the_semaphore->Core_control.MRSP, + scheduler + ); if ( new_priority != RTEMS_CURRENT_PRIORITY ) { - _MRSP_Set_ceiling_priority( mrsp, scheduler_index, core_priority ); + _MRSP_Set_priority( + &the_semaphore->Core_control.MRSP, + scheduler, + core_priority + ); } - _MRSP_Release( mrsp, queue_context ); sc = RTEMS_SUCCESSFUL; break; #endif @@ -85,14 +101,17 @@ static rtems_status_code _Semaphore_Set_priority( || the_semaphore->variant == SEMAPHORE_VARIANT_SIMPLE_BINARY || the_semaphore->variant == SEMAPHORE_VARIANT_COUNTING ); - _ISR_lock_ISR_enable( &queue_context->Lock_context ); old_priority = 0; sc = RTEMS_NOT_DEFINED; break; } - *old_priority_p = _RTEMS_Priority_From_core( scheduler, old_priority ); + _Thread_queue_Release( + &the_semaphore->Core_control.Wait_queue, + &queue_context->Lock_context + ); + *old_priority_p = _RTEMS_Priority_From_core( scheduler, old_priority ); return sc; } diff --git a/cpukit/score/Makefile.am b/cpukit/score/Makefile.am index 7166d72750..97f0b3d615 100644 --- a/cpukit/score/Makefile.am +++ b/cpukit/score/Makefile.am @@ -227,6 +227,7 @@ libscore_a_SOURCES += src/log2table.c libscore_a_SOURCES += src/scheduler.c libscore_a_SOURCES += src/schedulergetaffinity.c libscore_a_SOURCES += src/schedulersetaffinity.c +libscore_a_SOURCES += src/schedulerdefaultmappriority.c libscore_a_SOURCES += src/schedulerdefaultnodedestroy.c libscore_a_SOURCES += src/schedulerdefaultnodeinit.c libscore_a_SOURCES += src/schedulerdefaultreleasejob.c diff --git a/cpukit/score/include/rtems/score/coremutex.h b/cpukit/score/include/rtems/score/coremutex.h index 26bb53920a..a3dcabf523 100644 --- a/cpukit/score/include/rtems/score/coremutex.h +++ b/cpukit/score/include/rtems/score/coremutex.h @@ -27,6 +27,8 @@ #include #include +struct Scheduler_Control; + #ifdef __cplusplus extern "C" { #endif @@ -83,6 +85,13 @@ typedef struct { * @brief The priority ceiling value for the mutex owner. */ Priority_Control priority_ceiling; + +#if defined(RTEMS_SMP) + /** + * @brief The scheduler instance for this priority ceiling mutex. + */ + const struct Scheduler_Control *scheduler; +#endif } CORE_ceiling_mutex_Control; /**@}*/ diff --git a/cpukit/score/include/rtems/score/coremuteximpl.h b/cpukit/score/include/rtems/score/coremuteximpl.h index 956dfa81ee..3a5ae99a95 100644 --- a/cpukit/score/include/rtems/score/coremuteximpl.h +++ b/cpukit/score/include/rtems/score/coremuteximpl.h @@ -20,6 +20,7 @@ #include #include +#include #include #include #include @@ -358,11 +359,42 @@ RTEMS_INLINE_ROUTINE Status_Control _CORE_recursive_mutex_Surrender_no_protocol( RTEMS_INLINE_ROUTINE void _CORE_ceiling_mutex_Initialize( CORE_ceiling_mutex_Control *the_mutex, + const Scheduler_Control *scheduler, Priority_Control priority_ceiling ) { _CORE_recursive_mutex_Initialize( &the_mutex->Recursive ); the_mutex->priority_ceiling = priority_ceiling; +#if defined(RTEMS_SMP) + the_mutex->scheduler = scheduler; +#endif +} + +RTEMS_INLINE_ROUTINE const Scheduler_Control * +_CORE_ceiling_mutex_Get_scheduler( + const CORE_ceiling_mutex_Control *the_mutex +) +{ +#if defined(RTEMS_SMP) + return the_mutex->scheduler; +#else + return _Scheduler_Get_by_CPU_index( 0 ); +#endif +} + +RTEMS_INLINE_ROUTINE void _CORE_ceiling_mutex_Set_priority( + CORE_ceiling_mutex_Control *the_mutex, + Priority_Control priority_ceiling +) +{ + the_mutex->priority_ceiling = priority_ceiling; +} + +RTEMS_INLINE_ROUTINE Priority_Control _CORE_ceiling_mutex_Get_priority( + const CORE_ceiling_mutex_Control *the_mutex +) +{ + return the_mutex->priority_ceiling; } RTEMS_INLINE_ROUTINE Status_Control _CORE_ceiling_mutex_Set_owner( @@ -414,6 +446,16 @@ RTEMS_INLINE_ROUTINE Status_Control _CORE_ceiling_mutex_Seize( owner = _CORE_mutex_Get_owner( &the_mutex->Recursive.Mutex ); if ( owner == NULL ) { +#if defined(RTEMS_SMP) + if ( + _Scheduler_Get_own( executing ) + != _CORE_ceiling_mutex_Get_scheduler( the_mutex ) + ) { + _CORE_mutex_Release( &the_mutex->Recursive.Mutex, queue_context ); + return STATUS_NOT_DEFINED; + } +#endif + return _CORE_ceiling_mutex_Set_owner( the_mutex, executing, diff --git a/cpukit/score/include/rtems/score/mrspimpl.h b/cpukit/score/include/rtems/score/mrspimpl.h index cdeaff35c1..66f5cc6640 100644 --- a/cpukit/score/include/rtems/score/mrspimpl.h +++ b/cpukit/score/include/rtems/score/mrspimpl.h @@ -138,10 +138,11 @@ RTEMS_INLINE_ROUTINE void _MRSP_Claim_ownership( } RTEMS_INLINE_ROUTINE Status_Control _MRSP_Initialize( - MRSP_Control *mrsp, - Priority_Control ceiling_priority, - Thread_Control *executing, - bool initially_locked + MRSP_Control *mrsp, + const Scheduler_Control *scheduler, + Priority_Control ceiling_priority, + Thread_Control *executing, + bool initially_locked ) { uint32_t scheduler_count = _Scheduler_Count; @@ -159,7 +160,16 @@ RTEMS_INLINE_ROUTINE Status_Control _MRSP_Initialize( } for ( i = 0 ; i < scheduler_count ; ++i ) { - mrsp->ceiling_priorities[ i ] = ceiling_priority; + const Scheduler_Control *scheduler_of_cpu; + + scheduler_of_cpu = _Scheduler_Get_by_CPU_index( i ); + + if ( scheduler != scheduler_of_cpu ) { + mrsp->ceiling_priorities[ i ] = + _Scheduler_Map_priority( scheduler_of_cpu, 0 ); + } else { + mrsp->ceiling_priorities[ i ] = ceiling_priority; + } } _Resource_Initialize( &mrsp->Resource ); @@ -169,21 +179,27 @@ RTEMS_INLINE_ROUTINE Status_Control _MRSP_Initialize( return STATUS_SUCCESSFUL; } -RTEMS_INLINE_ROUTINE Priority_Control _MRSP_Get_ceiling_priority( - MRSP_Control *mrsp, - uint32_t scheduler_index +RTEMS_INLINE_ROUTINE Priority_Control _MRSP_Get_priority( + const MRSP_Control *mrsp, + const Scheduler_Control *scheduler ) { + uint32_t scheduler_index; + + scheduler_index = _Scheduler_Get_index( scheduler ); return mrsp->ceiling_priorities[ scheduler_index ]; } -RTEMS_INLINE_ROUTINE void _MRSP_Set_ceiling_priority( - MRSP_Control *mrsp, - uint32_t scheduler_index, - Priority_Control ceiling_priority +RTEMS_INLINE_ROUTINE void _MRSP_Set_priority( + MRSP_Control *mrsp, + const Scheduler_Control *scheduler, + Priority_Control new_priority ) { - mrsp->ceiling_priorities[ scheduler_index ] = ceiling_priority; + uint32_t scheduler_index; + + scheduler_index = _Scheduler_Get_index( scheduler ); + mrsp->ceiling_priorities[ scheduler_index ] = new_priority; } RTEMS_INLINE_ROUTINE void _MRSP_Timeout( Watchdog_Control *watchdog ) @@ -307,10 +323,8 @@ RTEMS_INLINE_ROUTINE Status_Control _MRSP_Seize( { Status_Control status; const Scheduler_Control *scheduler = _Scheduler_Get_own( executing ); - uint32_t scheduler_index = _Scheduler_Get_index( scheduler ); Priority_Control initial_priority = executing->current_priority; - Priority_Control ceiling_priority = - _MRSP_Get_ceiling_priority( mrsp, scheduler_index ); + Priority_Control ceiling_priority = _MRSP_Get_priority( mrsp, scheduler ); bool priority_ok = !_Thread_Priority_less_than( ceiling_priority, initial_priority diff --git a/cpukit/score/include/rtems/score/scheduler.h b/cpukit/score/include/rtems/score/scheduler.h index 2e9aba5072..ba9c2b50bb 100644 --- a/cpukit/score/include/rtems/score/scheduler.h +++ b/cpukit/score/include/rtems/score/scheduler.h @@ -91,6 +91,18 @@ typedef struct { bool ); + /** @see _Scheduler_Map_priority() */ + Priority_Control ( *map_priority )( + const Scheduler_Control *, + Priority_Control + ); + + /** @see _Scheduler_Unmap_priority() */ + Priority_Control ( *unmap_priority )( + const Scheduler_Control *, + Priority_Control + ); + #if defined(RTEMS_SMP) /** * Ask for help operation. @@ -403,6 +415,21 @@ extern const Scheduler_Control _Scheduler_Table[]; extern const Scheduler_Assignment _Scheduler_Assignments[]; #endif +/** + * @brief Returns the thread priority. + * + * @param[in] scheduler Unused. + * @param[in] priority The thread priority. + * + * @return priority The thread priority. + */ +Priority_Control _Scheduler_default_Map_priority( + const Scheduler_Control *scheduler, + Priority_Control priority +); + +#define _Scheduler_default_Unmap_priority _Scheduler_default_Map_priority + #if defined(RTEMS_SMP) /** * @brief Does nothing. diff --git a/cpukit/score/include/rtems/score/schedulercbs.h b/cpukit/score/include/rtems/score/schedulercbs.h index 397488fc40..4e03e111a6 100644 --- a/cpukit/score/include/rtems/score/schedulercbs.h +++ b/cpukit/score/include/rtems/score/schedulercbs.h @@ -55,6 +55,8 @@ extern "C" { _Scheduler_EDF_Block, /* block entry point */ \ _Scheduler_CBS_Unblock, /* unblock entry point */ \ _Scheduler_EDF_Change_priority, /* change priority entry point */ \ + _Scheduler_EDF_Map_priority, /* map priority entry point */ \ + _Scheduler_EDF_Unmap_priority, /* unmap priority entry point */ \ SCHEDULER_OPERATION_DEFAULT_ASK_FOR_HELP \ _Scheduler_CBS_Node_initialize, /* node initialize entry point */ \ _Scheduler_default_Node_destroy, /* node destroy entry point */ \ diff --git a/cpukit/score/include/rtems/score/scheduleredf.h b/cpukit/score/include/rtems/score/scheduleredf.h index 7d513ca416..042143f80d 100644 --- a/cpukit/score/include/rtems/score/scheduleredf.h +++ b/cpukit/score/include/rtems/score/scheduleredf.h @@ -48,6 +48,8 @@ extern "C" { _Scheduler_EDF_Block, /* block entry point */ \ _Scheduler_EDF_Unblock, /* unblock entry point */ \ _Scheduler_EDF_Change_priority, /* change priority entry point */ \ + _Scheduler_EDF_Map_priority, /* map priority entry point */ \ + _Scheduler_EDF_Unmap_priority, /* unmap priority entry point */ \ SCHEDULER_OPERATION_DEFAULT_ASK_FOR_HELP \ _Scheduler_EDF_Node_initialize, /* node initialize entry point */ \ _Scheduler_default_Node_destroy, /* node destroy entry point */ \ @@ -203,6 +205,16 @@ Scheduler_Void_or_thread _Scheduler_EDF_Change_priority( bool prepend_it ); +Priority_Control _Scheduler_EDF_Map_priority( + const Scheduler_Control *scheduler, + Priority_Control priority +); + +Priority_Control _Scheduler_EDF_Unmap_priority( + const Scheduler_Control *scheduler, + Priority_Control priority +); + /** * @brief invoked when a thread wishes to voluntarily * transfer control of the processor to another thread diff --git a/cpukit/score/include/rtems/score/schedulerimpl.h b/cpukit/score/include/rtems/score/schedulerimpl.h index 50061fbe67..36214729d7 100644 --- a/cpukit/score/include/rtems/score/schedulerimpl.h +++ b/cpukit/score/include/rtems/score/schedulerimpl.h @@ -419,6 +419,43 @@ RTEMS_INLINE_ROUTINE void _Scheduler_Change_priority( _Scheduler_Release_critical( own_scheduler, &lock_context ); } +/** + * @brief Maps a thread priority from the user domain to the scheduler domain. + * + * Let M be the maximum scheduler priority. The mapping must be bijective in + * the closed interval [0, M], e.g. _Scheduler_Unmap_priority( scheduler, + * _Scheduler_Map_priority( scheduler, p ) ) == p for all p in [0, M]. For + * other values the mapping is undefined. + * + * @param[in] scheduler The scheduler instance. + * @param[in] priority The user domain thread priority. + * + * @return The corresponding thread priority of the scheduler domain is returned. + */ +RTEMS_INLINE_ROUTINE Priority_Control _Scheduler_Map_priority( + const Scheduler_Control *scheduler, + Priority_Control priority +) +{ + return ( *scheduler->Operations.map_priority )( scheduler, priority ); +} + +/** + * @brief Unmaps a thread priority from the scheduler domain to the user domain. + * + * @param[in] scheduler The scheduler instance. + * @param[in] priority The scheduler domain thread priority. + * + * @return The corresponding thread priority of the user domain is returned. + */ +RTEMS_INLINE_ROUTINE Priority_Control _Scheduler_Unmap_priority( + const Scheduler_Control *scheduler, + Priority_Control priority +) +{ + return ( *scheduler->Operations.unmap_priority )( scheduler, priority ); +} + /** * @brief Initializes a scheduler node. * diff --git a/cpukit/score/include/rtems/score/schedulerpriority.h b/cpukit/score/include/rtems/score/schedulerpriority.h index 07599416d6..d5e73c19fc 100644 --- a/cpukit/score/include/rtems/score/schedulerpriority.h +++ b/cpukit/score/include/rtems/score/schedulerpriority.h @@ -45,6 +45,8 @@ extern "C" { _Scheduler_priority_Block, /* block entry point */ \ _Scheduler_priority_Unblock, /* unblock entry point */ \ _Scheduler_priority_Change_priority, /* change priority entry point */ \ + _Scheduler_default_Map_priority, /* map priority entry point */ \ + _Scheduler_default_Unmap_priority, /* unmap priority entry point */ \ SCHEDULER_OPERATION_DEFAULT_ASK_FOR_HELP \ _Scheduler_default_Node_initialize, /* node initialize entry point */ \ _Scheduler_default_Node_destroy, /* node destroy entry point */ \ diff --git a/cpukit/score/include/rtems/score/schedulerpriorityaffinitysmp.h b/cpukit/score/include/rtems/score/schedulerpriorityaffinitysmp.h index e2d6f3b1c7..b0a704478c 100644 --- a/cpukit/score/include/rtems/score/schedulerpriorityaffinitysmp.h +++ b/cpukit/score/include/rtems/score/schedulerpriorityaffinitysmp.h @@ -55,6 +55,8 @@ extern "C" { _Scheduler_priority_affinity_SMP_Block, \ _Scheduler_priority_affinity_SMP_Unblock, \ _Scheduler_priority_affinity_SMP_Change_priority, \ + _Scheduler_default_Map_priority, \ + _Scheduler_default_Unmap_priority, \ _Scheduler_priority_affinity_SMP_Ask_for_help, \ _Scheduler_priority_affinity_SMP_Node_initialize, \ _Scheduler_default_Node_destroy, \ diff --git a/cpukit/score/include/rtems/score/schedulerprioritysmp.h b/cpukit/score/include/rtems/score/schedulerprioritysmp.h index d550c78836..0af7000808 100644 --- a/cpukit/score/include/rtems/score/schedulerprioritysmp.h +++ b/cpukit/score/include/rtems/score/schedulerprioritysmp.h @@ -84,6 +84,8 @@ typedef struct { _Scheduler_priority_SMP_Block, \ _Scheduler_priority_SMP_Unblock, \ _Scheduler_priority_SMP_Change_priority, \ + _Scheduler_default_Map_priority, \ + _Scheduler_default_Unmap_priority, \ _Scheduler_priority_SMP_Ask_for_help, \ _Scheduler_priority_SMP_Node_initialize, \ _Scheduler_default_Node_destroy, \ diff --git a/cpukit/score/include/rtems/score/schedulersimple.h b/cpukit/score/include/rtems/score/schedulersimple.h index 9e40c4ac44..00f8dd790f 100644 --- a/cpukit/score/include/rtems/score/schedulersimple.h +++ b/cpukit/score/include/rtems/score/schedulersimple.h @@ -45,6 +45,8 @@ extern "C" { _Scheduler_simple_Block, /* block entry point */ \ _Scheduler_simple_Unblock, /* unblock entry point */ \ _Scheduler_simple_Change_priority, /* change priority entry point */ \ + _Scheduler_default_Map_priority, /* map priority entry point */ \ + _Scheduler_default_Unmap_priority, /* unmap priority entry point */ \ SCHEDULER_OPERATION_DEFAULT_ASK_FOR_HELP \ _Scheduler_default_Node_initialize, /* node initialize entry point */ \ _Scheduler_default_Node_destroy, /* node destroy entry point */ \ diff --git a/cpukit/score/include/rtems/score/schedulersimplesmp.h b/cpukit/score/include/rtems/score/schedulersimplesmp.h index b9433534c6..31c837d00d 100644 --- a/cpukit/score/include/rtems/score/schedulersimplesmp.h +++ b/cpukit/score/include/rtems/score/schedulersimplesmp.h @@ -67,6 +67,8 @@ typedef struct { _Scheduler_simple_SMP_Block, \ _Scheduler_simple_SMP_Unblock, \ _Scheduler_simple_SMP_Change_priority, \ + _Scheduler_default_Map_priority, \ + _Scheduler_default_Unmap_priority, \ _Scheduler_simple_SMP_Ask_for_help, \ _Scheduler_simple_SMP_Node_initialize, \ _Scheduler_default_Node_destroy, \ diff --git a/cpukit/score/include/rtems/score/schedulerstrongapa.h b/cpukit/score/include/rtems/score/schedulerstrongapa.h index 4f95aac8fb..d7c3888d5a 100644 --- a/cpukit/score/include/rtems/score/schedulerstrongapa.h +++ b/cpukit/score/include/rtems/score/schedulerstrongapa.h @@ -84,6 +84,8 @@ typedef struct { _Scheduler_strong_APA_Block, \ _Scheduler_strong_APA_Unblock, \ _Scheduler_strong_APA_Change_priority, \ + _Scheduler_default_Map_priority, \ + _Scheduler_default_Unmap_priority, \ _Scheduler_strong_APA_Ask_for_help, \ _Scheduler_strong_APA_Node_initialize, \ _Scheduler_default_Node_destroy, \ diff --git a/cpukit/score/include/rtems/score/status.h b/cpukit/score/include/rtems/score/status.h index f6ebaa46f1..d30f731a70 100644 --- a/cpukit/score/include/rtems/score/status.h +++ b/cpukit/score/include/rtems/score/status.h @@ -38,6 +38,7 @@ typedef enum { STATUS_CLASSIC_INVALID_PRIORITY = 19, STATUS_CLASSIC_INVALID_SIZE = 8, STATUS_CLASSIC_NO_MEMORY = 26, + STATUS_CLASSIC_NOT_DEFINED = 11, STATUS_CLASSIC_NOT_OWNER_OF_RESOURCE = 23, STATUS_CLASSIC_OBJECT_WAS_DELETED = 7, STATUS_CLASSIC_RESOURCE_IN_USE = 12, @@ -104,6 +105,8 @@ typedef enum { STATUS_BUILD( STATUS_CLASSIC_UNSATISFIED, EDEADLK ), STATUS_NO_MEMORY = STATUS_BUILD( STATUS_CLASSIC_NO_MEMORY, EINVAL ), + STATUS_NOT_DEFINED = + STATUS_BUILD( STATUS_CLASSIC_NOT_DEFINED, EINVAL ), STATUS_NOT_OWNER = STATUS_BUILD( STATUS_CLASSIC_NOT_OWNER_OF_RESOURCE, EPERM ), STATUS_OBJECT_WAS_DELETED = diff --git a/cpukit/score/src/schedulerdefaultmappriority.c b/cpukit/score/src/schedulerdefaultmappriority.c new file mode 100644 index 0000000000..37a600011e --- /dev/null +++ b/cpukit/score/src/schedulerdefaultmappriority.c @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2016 embedded brains GmbH + * + * 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 + +Priority_Control _Scheduler_default_Map_priority( + const Scheduler_Control *scheduler, + Priority_Control priority +) +{ + return priority; +} diff --git a/cpukit/score/src/scheduleredfchangepriority.c b/cpukit/score/src/scheduleredfchangepriority.c index 61e0481d03..6efbf87ad3 100644 --- a/cpukit/score/src/scheduleredfchangepriority.c +++ b/cpukit/score/src/scheduleredfchangepriority.c @@ -20,6 +20,22 @@ #include +Priority_Control _Scheduler_EDF_Map_priority( + const Scheduler_Control *scheduler, + Priority_Control priority +) +{ + return SCHEDULER_EDF_PRIO_MSB | priority; +} + +Priority_Control _Scheduler_EDF_Unmap_priority( + const Scheduler_Control *scheduler, + Priority_Control priority +) +{ + return priority & ~SCHEDULER_EDF_PRIO_MSB; +} + Scheduler_Void_or_thread _Scheduler_EDF_Change_priority( const Scheduler_Control *scheduler, Thread_Control *the_thread, diff --git a/cpukit/score/src/threadcreateidle.c b/cpukit/score/src/threadcreateidle.c index 0df53ecfab..89e5d60a18 100644 --- a/cpukit/score/src/threadcreateidle.c +++ b/cpukit/score/src/threadcreateidle.c @@ -19,6 +19,7 @@ #endif #include +#include #include #include #include @@ -47,6 +48,7 @@ static void _Thread_Create_idle_for_CPU( Per_CPU_Control *cpu ) * _Workspace_Initialization. */ idle = _Thread_Internal_allocate(); + _Assert( idle != NULL ); _Thread_Initialize( &_Thread_Internal_information, @@ -55,7 +57,7 @@ static void _Thread_Create_idle_for_CPU( Per_CPU_Control *cpu ) NULL, /* allocate the stack */ _Stack_Ensure_minimum( rtems_configuration_get_idle_task_stack_size() ), CPU_IDLE_TASK_IS_FP, - scheduler->maximum_priority, + _Scheduler_Map_priority( scheduler, scheduler->maximum_priority ), true, /* preemptable */ THREAD_CPU_BUDGET_ALGORITHM_NONE, NULL, /* no budget algorithm callout */ -- cgit v1.2.3