source: rtems/cpukit/score/src/schedulercbsunblock.c @ b20b736

5
Last change on this file since b20b736 was b20b736, checked in by Sebastian Huber <sebastian.huber@…>, on 06/28/16 at 04:54:50

score: Introduce _Thread_Get_priority()

Avoid direct access to thread internal data fields.

  • Property mode set to 100644
File size: 2.8 KB
Line 
1/**
2 * @file
3 *
4 * @brief Unblocks a Thread from the Queue
5 *
6 * @ingroup ScoreScheduler
7 */
8
9/*
10 *  Copyright (C) 2011 Petr Benes.
11 *  Copyright (C) 2011 On-Line Applications Research Corporation (OAR).
12 *
13 *  The license and distribution terms for this file may be
14 *  found in the file LICENSE in this distribution or at
15 *  http://www.rtems.org/license/LICENSE.
16 */
17
18#if HAVE_CONFIG_H
19#include "config.h"
20#endif
21
22#include <rtems/score/schedulercbsimpl.h>
23#include <rtems/score/scheduleredfimpl.h>
24#include <rtems/score/schedulerimpl.h>
25#include <rtems/score/threadimpl.h>
26#include <rtems/score/watchdogimpl.h>
27
28Scheduler_Void_or_thread _Scheduler_CBS_Unblock(
29  const Scheduler_Control *scheduler,
30  Thread_Control          *the_thread
31)
32{
33  Scheduler_EDF_Context *context;
34  Scheduler_CBS_Node    *node;
35  Scheduler_CBS_Server  *serv_info;
36  Priority_Control       priority;
37  bool                   prepend_it;
38
39  context = _Scheduler_EDF_Get_context( scheduler );
40  node = _Scheduler_CBS_Thread_get_node( the_thread );
41  serv_info = node->cbs_server;
42  priority = _Scheduler_Node_get_priority( &node->Base.Base, &prepend_it );
43  (void) prepend_it;
44
45  /*
46   * Late unblock rule for deadline-driven tasks. The remaining time to
47   * deadline must be sufficient to serve the remaining computation time
48   * without increased utilization of this task. It might cause a deadline
49   * miss of another task.
50   */
51  if ( serv_info != NULL && ( priority & SCHEDULER_EDF_PRIO_MSB ) == 0 ) {
52    time_t deadline = serv_info->parameters.deadline;
53    time_t budget = serv_info->parameters.budget;
54    uint32_t deadline_left = the_thread->cpu_time_budget;
55    Priority_Control budget_left = priority - _Watchdog_Ticks_since_boot;
56
57    if ( deadline * budget_left > budget * deadline_left ) {
58      /* Put late unblocked task to background until the end of period. */
59
60      priority = node->Base.background_priority;
61      the_thread->real_priority = priority;
62
63      if (
64        _Thread_Priority_less_than(
65          _Thread_Get_priority( the_thread ),
66          priority
67        ) || !_Thread_Owns_resources( the_thread )
68      ) {
69        the_thread->current_priority = priority;
70      }
71    }
72  }
73
74  node->Base.current_priority = priority;
75  _Scheduler_EDF_Enqueue( context, &node->Base, priority );
76
77  /*
78   *  If the thread that was unblocked is more important than the heir,
79   *  then we have a new heir.  This may or may not result in a
80   *  context switch.
81   *
82   *  Normal case:
83   *    If the current thread is preemptible, then we need to do
84   *    a context switch.
85   *  Pseudo-ISR case:
86   *    Even if the thread isn't preemptible, if the new heir is
87   *    a pseudo-ISR system task, we need to do a context switch.
88   */
89  if ( priority < _Thread_Get_priority( _Thread_Heir ) ) {
90    _Scheduler_Update_heir( the_thread, priority == PRIORITY_PSEUDO_ISR );
91  }
92
93  SCHEDULER_RETURN_VOID_OR_NULL;
94}
Note: See TracBrowser for help on using the repository browser.