Changeset b50468c in rtems


Ignore:
Timestamp:
Dec 21, 2017, 6:04:50 PM (22 months ago)
Author:
Gedare Bloom <gedare@…>
Branches:
4.10
Children:
680d7650
Parents:
78b867e2
git-author:
Gedare Bloom <gedare@…> (12/21/17 18:04:50)
git-committer:
Gedare Bloom <gedare@…> (03/23/18 15:33:59)
Message:

score: add Inherited_priorities priority queue and functions

Adds enqueue, dequeue, requeue, evaluate, and release functions
for the thread priority node priority queue of inherited priorities.
Add calls to these functions as needed to maintain the priority
queue due to blocking, unblocking, and priority changes.

Closes #3359.

Location:
cpukit
Files:
1 added
11 edited

Legend:

Unmodified
Added
Removed
  • cpukit/rtems/src/tasksetpriority.c

    r78b867e2 rb50468c  
    7676      if ( new_priority != RTEMS_CURRENT_PRIORITY ) {
    7777        the_thread->Priority_node.real_priority = new_priority;
    78         if ( the_thread->resource_count == 0 ||
    79              the_thread->Priority_node.current_priority > new_priority )
    80           _Thread_Change_priority( the_thread, new_priority, false );
     78        _Thread_Evaluate_priority( the_thread );
    8179      }
    8280      _Thread_Enable_dispatch();
  • cpukit/score/Makefile.am

    r78b867e2 rb50468c  
    155155    src/threadstartmultitasking.c src/threadsuspend.c \
    156156    src/threadtickletimeslice.c src/threadyieldprocessor.c \
    157     src/iterateoverthreads.c src/threadblockingoperationcancel.c
     157    src/iterateoverthreads.c src/threadblockingoperationcancel.c \
     158    src/threadprioritynode.c
    158159
    159160## THREAD_C_FILES only used by ITRON API
  • cpukit/score/include/rtems/score/coremutex.h

    r78b867e2 rb50468c  
    217217 *  The following defines the control block used to manage each mutex.
    218218 */
    219 typedef struct {
     219typedef struct CORE_mutex_Control {
    220220  /** This field is the Waiting Queue used to manage the set of tasks
    221221   *  which are blocked waiting to lock the mutex.
  • cpukit/score/include/rtems/score/thread.h

    r78b867e2 rb50468c  
    277277}   Thread_Wait_information;
    278278
     279struct CORE_mutex_Control;
    279280/**
    280281 * @brief Encapsulates base and inherited priority.
    281282 */
    282283typedef struct Thread_Priority_node {
    283   Chain_Node               Node;
     284  Chain_Node                   Node;
    284285  /** current priority = min(real_priority, min(Inherited_priorities)) */
    285   Priority_Control         current_priority;
     286  Priority_Control             current_priority;
    286287  /** base priority irrespective of inheritance/ceiling */
    287   Priority_Control         real_priority;
     288  Priority_Control             real_priority;
     289  /** NULL if not waiting, or the mutex blocked upon
     290   * if waiting. If not NULL, then this Priority_node is on the mutex holder's
     291   * Priority_node.Inherited_priorities list. */
     292  struct CORE_mutex_Control   *waiting_to_hold;
     293  /** Priority Queue of thread Priority_nodes blocked by this one, thus
     294   * possibly contributing their priority to the current_priority. */
     295  Chain_Control                Inherited_priorities;
    288296} Thread_Priority_node;
    289297
     
    788796bool _Thread_Evaluate_mode( void );
    789797
     798/**
     799 * This routine sets the thread's priority_node->current_priority to the
     800 * minimum of the real_priority and the first node of Inherited_priorities,
     801 * if any.
     802 */
     803void _Thread_Evaluate_priority(
     804  Thread_Control *the_thread
     805);
     806
     807/**
     808 * This routine adds a thread's Priority_node to the mutex holder's
     809 * Inherited_priorities list, and sets the waiting_to_hold field to the
     810 * mutex.
     811 *
     812 * Returns true if the enqueued node is at the head of the holder's
     813 * Inherited priorities, and therefore the holder's priority may change.
     814 */
     815bool _Thread_Enqueue_priority_node(
     816  Thread_Control *the_thread,
     817  struct CORE_mutex_Control *the_mutex
     818);
     819
     820/**
     821 * This routine removes a thread's Priority_node from an
     822 * Inherited_priorities list, updates the mutex holder's
     823 * current_priority if needed, and clears the mutex field.
     824 *
     825 * Returns the mutex that the thread was waiting on.
     826 */
     827struct CORE_mutex_Control* _Thread_Dequeue_priority_node(
     828  Thread_Priority_node *thread_pn
     829);
     830
     831/**
     832 * This routine updates the position of a thread's Priority_node in an
     833 * Inherited_priorities list if on one.
     834 */
     835void _Thread_Requeue_priority_node(
     836  Thread_Control *the_thread
     837);
     838
     839/**
     840 * This routine removes the inherited priorities from the mutex being
     841 * released and updates the holder's priority if necessary.
     842 */
     843void _Thread_Release_inherited_priority(
     844  struct CORE_mutex_Control *the_mutex
     845);
     846
    790847#if (CPU_PROVIDES_IDLE_THREAD_BODY == FALSE)
    791848/**
  • cpukit/score/src/coremutexseize.c

    r78b867e2 rb50468c  
    6262  executing = _Thread_Executing;
    6363  if ( _CORE_mutex_Is_inherit_priority( &the_mutex->Attributes ) ) {
    64     if ( the_mutex->holder->Priority_node.current_priority > executing->Priority_node.current_priority ) {
    65       _Thread_Change_priority(
    66         the_mutex->holder,
    67         executing->Priority_node.current_priority,
    68         false
    69       );
    70     }
     64    _Thread_Enqueue_priority_node( executing, the_mutex );
     65    _Thread_Evaluate_priority( the_mutex->holder );
    7166  }
    7267
  • cpukit/score/src/coremutexsurrender.c

    r78b867e2 rb50468c  
    125125    holder->resource_count--;
    126126  }
     127  if ( _CORE_mutex_Is_inherit_priority( &the_mutex->Attributes ) ) {
     128    _Thread_Release_inherited_priority( the_mutex );
     129  }
    127130  the_mutex->holder    = NULL;
    128131  the_mutex->holder_id = 0;
     
    133136   *  mutex (i.e. resource) this task has.
    134137   */
    135   if ( _CORE_mutex_Is_inherit_priority( &the_mutex->Attributes ) ||
    136        _CORE_mutex_Is_priority_ceiling( &the_mutex->Attributes ) ) {
     138  if ( _CORE_mutex_Is_priority_ceiling( &the_mutex->Attributes ) ) {
    137139#ifdef __RTEMS_STRICT_ORDER_MUTEX__
    138140    if(the_mutex->queue.priority_before != holder->Priority_node.current_priority)
  • cpukit/score/src/threadchangepriority.c

    r78b867e2 rb50468c  
    8989   *  we are not REALLY changing priority.
    9090   */
    91  if ( the_thread->Priority_node.current_priority != new_priority )
     91  if ( the_thread->Priority_node.current_priority != new_priority ) {
    9292    _Thread_Set_priority( the_thread, new_priority );
     93    _Thread_Requeue_priority_node( the_thread );
     94  }
    9395
    9496  _ISR_Disable( level );
  • cpukit/score/src/threadinitialize.c

    r78b867e2 rb50468c  
    193193    the_thread->suspend_count         = 0;
    194194  #endif
    195   the_thread->Priority_node.real_priority           = priority;
     195  _Chain_Set_off_chain( &the_thread->Priority_node.Node );
     196  the_thread->Priority_node.real_priority    = priority;
     197  the_thread->Priority_node.current_priority = priority;
     198  the_thread->Priority_node.waiting_to_hold  = NULL;
     199  _Chain_Initialize_empty( &the_thread->Priority_node.Inherited_priorities );
    196200  the_thread->Start.initial_priority  = priority;
    197201  _Thread_Set_priority( the_thread, priority );
  • cpukit/score/src/threadqextractpriority.c

    r78b867e2 rb50468c  
    1919#include <rtems/system.h>
    2020#include <rtems/score/chain.h>
     21#include <rtems/score/coremutex.h>
    2122#include <rtems/score/isr.h>
    2223#include <rtems/score/object.h>
     
    5859  Chain_Node     *new_second_node;
    5960  Chain_Node     *last_node;
     61  CORE_mutex_Control *mutex;
    6062
    6163  the_node = (Chain_Node *) the_thread;
     
    107109  }
    108110
     111  mutex = _Thread_Dequeue_priority_node( &the_thread->Priority_node );
     112  _Thread_Evaluate_priority( mutex->holder );
     113
    109114  if ( !_Watchdog_Is_active( &the_thread->Timer ) ) {
    110115    _ISR_Enable( level );
  • cpukit/score/src/threadqflush.c

    r78b867e2 rb50468c  
    1919#include <rtems/system.h>
    2020#include <rtems/score/chain.h>
     21#include <rtems/score/coremutex.h>
    2122#include <rtems/score/isr.h>
    2223#include <rtems/score/object.h>
     
    5152{
    5253  Thread_Control *the_thread;
     54  CORE_mutex_Control *mutex;
    5355
    5456  while ( (the_thread = _Thread_queue_Dequeue( the_thread_queue )) ) {
     
    5961#endif
    6062      the_thread->Wait.return_code = status;
     63    if ( the_thread->Priority_node.waiting_to_hold != NULL ) {
     64      mutex = _Thread_Dequeue_priority_node( &the_thread->Priority_node );
     65      _Thread_Evaluate_priority( mutex->holder );
     66    }
    6167  }
    6268}
  • cpukit/score/src/threadreset.c

    r78b867e2 rb50468c  
    2020#include <rtems/score/apiext.h>
    2121#include <rtems/score/context.h>
     22#include <rtems/score/coremutex.h>
    2223#include <rtems/score/interr.h>
    2324#include <rtems/score/isr.h>
     
    4748)
    4849{
     50  CORE_mutex_Control *mutex;
     51
    4952  the_thread->resource_count   = 0;
    5053  #if defined(RTEMS_ITRON_API)
     
    6467  }
    6568
     69  if ( the_thread->Priority_node.waiting_to_hold != NULL ) {
     70    mutex = _Thread_Dequeue_priority_node( &the_thread->Priority_node );
     71    _Thread_Evaluate_priority( mutex->holder );
     72  }
     73
     74  while ( !_Chain_Is_empty( &the_thread->Priority_node.Inherited_priorities ) ) {
     75    _Thread_Dequeue_priority_node(
     76      ((Thread_Priority_node*)_Chain_First(
     77        &the_thread->Priority_node.Inherited_priorities
     78      ))
     79    );
     80  }
     81
    6682  if ( the_thread->Priority_node.current_priority != the_thread->Start.initial_priority ) {
    6783    the_thread->Priority_node.real_priority = the_thread->Start.initial_priority;
Note: See TracChangeset for help on using the changeset viewer.