source: rtems/cpukit/score/src/schedulercbsunblock.c @ 99fc1d1d

5
Last change on this file since 99fc1d1d was 99fc1d1d, checked in by Sebastian Huber <sebastian.huber@…>, on Jun 9, 2016 at 7:30:40 PM

score: Rework EDF scheduler

Use inline red-black tree insert. Do not use shifting priorities since
this is not supported by the thread queues. Due to the 32-bit
Priority_Control this currently limits the uptime to 49days with a 1ms
clock tick.

Update #2173.

  • Property mode set to 100644
File size: 2.7 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
38  context = _Scheduler_EDF_Get_context( scheduler );
39  node = _Scheduler_CBS_Thread_get_node( the_thread );
40  serv_info = node->cbs_server;
41  priority = node->Base.current_priority;
42
43  /*
44   * Late unblock rule for deadline-driven tasks. The remaining time to
45   * deadline must be sufficient to serve the remaining computation time
46   * without increased utilization of this task. It might cause a deadline
47   * miss of another task.
48   */
49  if ( serv_info != NULL && ( priority & SCHEDULER_EDF_PRIO_MSB ) == 0 ) {
50    time_t deadline = serv_info->parameters.deadline;
51    time_t budget = serv_info->parameters.budget;
52    uint32_t deadline_left = the_thread->cpu_time_budget;
53    Priority_Control budget_left = priority - _Watchdog_Ticks_since_boot;
54
55    if ( deadline * budget_left > budget * deadline_left ) {
56      /* Put late unblocked task to background until the end of period. */
57
58      priority = node->Base.background_priority;
59      the_thread->real_priority = priority;
60
61      if (
62        _Thread_Priority_less_than( the_thread->current_priority, priority )
63          || !_Thread_Owns_resources( the_thread )
64      ) {
65        the_thread->current_priority = priority;
66      }
67    }
68  }
69
70  node->Base.current_priority = priority;
71  _Scheduler_EDF_Enqueue( context, &node->Base, priority );
72
73  /*
74   *  If the thread that was unblocked is more important than the heir,
75   *  then we have a new heir.  This may or may not result in a
76   *  context switch.
77   *
78   *  Normal case:
79   *    If the current thread is preemptible, then we need to do
80   *    a context switch.
81   *  Pseudo-ISR case:
82   *    Even if the thread isn't preemptible, if the new heir is
83   *    a pseudo-ISR system task, we need to do a context switch.
84   */
85  if ( priority < _Thread_Heir->current_priority ) {
86    _Scheduler_Update_heir( the_thread, priority == PRIORITY_PSEUDO_ISR );
87  }
88
89  SCHEDULER_RETURN_VOID_OR_NULL;
90}
Note: See TracBrowser for help on using the repository browser.