source: rtems/cpukit/score/src/schedulercbsunblock.c @ 24934e36

4.115
Last change on this file since 24934e36 was 24934e36, checked in by Sebastian Huber <sebastian.huber@…>, on 04/03/14 at 13:03:35

score: Add scheduler control to scheduler ops

Scheduler operations must be free of a global scheduler context to
enable partitioned/clustered scheduling.

  • 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/schedulercbs.h>
23#include <rtems/score/schedulerimpl.h>
24#include <rtems/score/threadimpl.h>
25#include <rtems/score/watchdogimpl.h>
26
27void _Scheduler_CBS_Unblock(
28  Scheduler_Control *scheduler,
29  Thread_Control    *the_thread
30)
31{
32  Scheduler_CBS_Per_thread *sched_info;
33  Scheduler_CBS_Server *serv_info;
34  Priority_Control new_priority;
35
36  _Scheduler_EDF_Enqueue( scheduler, the_thread );
37  /* TODO: flash critical section? */
38
39  sched_info = (Scheduler_CBS_Per_thread *) the_thread->scheduler_info;
40  serv_info = (Scheduler_CBS_Server *) sched_info->cbs_server;
41
42  /*
43   * Late unblock rule for deadline-driven tasks. The remaining time to
44   * deadline must be sufficient to serve the remaining computation time
45   * without increased utilization of this task. It might cause a deadline
46   * miss of another task.
47   */
48  if (serv_info) {
49    time_t deadline = serv_info->parameters.deadline;
50    time_t budget = serv_info->parameters.budget;
51    time_t deadline_left = the_thread->cpu_time_budget;
52    time_t budget_left = the_thread->real_priority -
53                           _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      new_priority = the_thread->Start.initial_priority;
58      if ( the_thread->real_priority != new_priority )
59        the_thread->real_priority = new_priority;
60      if ( the_thread->current_priority != new_priority )
61        _Thread_Change_priority(the_thread, new_priority, true);
62    }
63  }
64
65  /*
66   *  If the thread that was unblocked is more important than the heir,
67   *  then we have a new heir.  This may or may not result in a
68   *  context switch.
69   *
70   *  Normal case:
71   *    If the current thread is preemptible, then we need to do
72   *    a context switch.
73   *  Pseudo-ISR case:
74   *    Even if the thread isn't preemptible, if the new heir is
75   *    a pseudo-ISR system task, we need to do a context switch.
76   */
77  if (
78    _Scheduler_Is_priority_higher_than(
79       scheduler,
80       the_thread->current_priority,
81       _Thread_Heir->current_priority
82    )
83  ) {
84    _Thread_Heir = the_thread;
85    if ( _Thread_Executing->is_preemptible ||
86         the_thread->current_priority == 0 )
87      _Thread_Dispatch_necessary = true;
88  }
89}
Note: See TracBrowser for help on using the repository browser.