rtems提供了更新任务优先级的函数,最常用的场景是主动调用rtems_task_set_priority来调整任务的优先级,当前其他相关线程的操作都可以操作优先级,本文仅以最简单和通用的方式解释更新任务优先级
rtems_task_set_priority的函数实现如下:
rtems_status_code rtems_task_set_priority( rtems_id id, rtems_task_priority new_priority, rtems_task_priority *old_priority_p )_RTEMS_tasks_Set_priority { Thread_Control *the_thread; Thread_queue_Context queue_context; const Scheduler_Control *scheduler; Priority_Control old_priority; rtems_status_code status; if ( old_priority_p == NULL ) { return RTEMS_INVALID_ADDRESS; } _Thread_queue_Context_initialize( &queue_context ); _Thread_queue_Context_clear_priority_updates( &queue_context ); the_thread = _Thread_Get( id, &queue_context.Lock_context.Lock_context ); if ( the_thread == NULL ) { #if defined(RTEMS_MULTIPROCESSING) return _RTEMS_tasks_MP_Set_priority( id, new_priority, old_priority_p ); #else return RTEMS_INVALID_ID; #endif } _Thread_Wait_acquire_critical( the_thread, &queue_context ); scheduler = _Thread_Scheduler_get_home( the_thread ); old_priority = _Thread_Get_priority( the_thread ); if ( new_priority != RTEMS_CURRENT_PRIORITY ) { status = _RTEMS_tasks_Set_priority( the_thread, scheduler, new_priority, &queue_context ); } else { _Thread_Wait_release( the_thread, &queue_context ); status = RTEMS_SUCCESSFUL; } *old_priority_p = _RTEMS_Priority_From_core( scheduler, old_priority ); return status; }
对于此函数,其作用主要是获取线程后加锁然后更新优先级,最后释放锁后返回旧的优先级, 所以我们关心主要函数_RTEMS_tasks_Set_priority。其调用路径如下
_RTEMS_tasks_Set_priority--->_Thread_Priority_update--->_Scheduler_Update_priority
测试调整优先级的方法是在task创建之后的任意时间,根据taskid来调整优先级,故部分代码如下
status = rtems_task_start( Task_id[ 1 ], Task_1, 0 ); directive_failed( status, "rtems_task_start of TA1" ); rtems_task_priority previous_priority; status = rtems_task_set_priority( Task_id[ 1 ], 253, &previous_priority ); printf("Kylin: set priority 254 ret=%d prev=%d \n", status, previous_priority ); status = rtems_task_start( Task_id[ 2 ], Task_2, 0 ); directive_failed( status, "rtems_task_start of TA2" ); status = rtems_task_set_priority( Task_id[ 2 ], 254, &previous_priority ); printf("Kylin: set priority 255 ret=%d prev=%d \n", status, previous_priority );
我们可以调整task1和task2的优先级,这样task1和task2的启动顺序会出现不一样。日志如下
task1 优于 task2
Kylin: set priority 254 ret=0 prev=4 Kylin: set priority 255 ret=0 prev=4 TA1 - rtems_signal_send - RTEMS_SIGNAL_16 to self TA1 - rtems_signal_send - RTEMS_SIGNAL_0 to self TA2 - rtems_signal_send - RTEMS_SIGNAL_17 to self TA2 - rtems_signal_send - RTEMS_SIGNAL_18 and RTEMS_SIGNAL_19 to self
task2优于task1
Kylin: set priority 254 ret=0 prev=4 Kylin: set priority 255 ret=0 prev=4 TA2 - rtems_signal_send - RTEMS_SIGNAL_17 to self TA2 - rtems_signal_send - RTEMS_SIGNAL_18 and RTEMS_SIGNAL_19 to self TA1 - rtems_signal_send - RTEMS_SIGNAL_16 to self TA1 - rtems_signal_send - RTEMS_SIGNAL_0 to self
本文简单的演示了调整任务优先级,由于目前未了解不同调度器的实现,故此实验比较简单