예제 #1
0
    def Schedule(self, kernelspace, abb):
        if abb.function.subtask.is_isr:
            self.Comment(kernelspace, """OPTIMIZATION: Each ABB is either in an
                ISR or not, therefore we can surely decide if we have to
                reschedule in the AST or not""")
            self.stats.add_data(abb, "opt:Schedule:in-ast", True)
            self.call_function(kernelspace, "request_reschedule_ast",
                               "void", [])
            return

        abb_info = self.global_abb_info.for_abb(abb)
        # All following tasks (Subtask->ABB)
        next_subtasks = abb_info.tasks_after

        if len(next_subtasks) == 1:
            next_subtask = unwrap_seq(list(next_subtasks.keys()))
            self.Comment(kernelspace,
                         "OPTIMIZATION: There is only one possible subtask continuing"
                         + " to, we directly dispatch to that task: %s", next_subtask)
            self.stats.add_data(abb, "opt:Schedule:possible-tasks", 1)
            self.RescheduleTo(kernelspace, abb, next_subtask)
            return


        tasks = list(abb_info.tasks_after.keys())
        self.Comment(kernelspace, "OPTIMIZATION: Only the following tasks are possible %s", 
                     tasks)
        schedule_hint = self.ScheduleTargetHint(tasks)
        self.stats.add_data(abb, "opt:Schedule:possible-tasks", len(tasks))

        self.call_function(kernelspace,
                           "scheduler_.Reschedule< %s >" % (schedule_hint),
                           "void", [])
예제 #2
0
    def Schedule(self, kernelspace, abb):
        if abb.subtask.conf.is_isr:
            self.Comment(
                kernelspace, """OPTIMIZATION: Each ABB is either in an
                ISR or not, therefore we can surely decide if we have to
                reschedule in the AST or not""")
            self.stats.add_data(abb, "opt:Schedule:in-ast", True)
            self.call_function(kernelspace, "request_reschedule_ast", "void",
                               [])
            return

        abb_info = self.global_abb_info.for_abb(abb)
        # All following tasks (Subtask->ABB)
        next_subtasks = abb_info.tasks_after

        if len(next_subtasks) == 1:
            next_subtask = unwrap_seq(list(next_subtasks.keys()))
            self.Comment(
                kernelspace,
                "OPTIMIZATION: There is only one possible subtask continuing" +
                " to, we directly dispatch to that task: %s", next_subtask)
            self.stats.add_data(abb, "opt:Schedule:possible-tasks", 1)
            self.RescheduleTo(kernelspace, abb, next_subtask)
            return

        tasks = list(abb_info.tasks_after.keys())
        self.Comment(kernelspace,
                     "OPTIMIZATION: Only the following tasks are possible %s",
                     tasks)
        self.stats.add_data(abb, "opt:Schedule:possible-tasks", len(tasks))

        self.call_function(kernelspace, "scheduler_.Reschedule", "void", [])
예제 #3
0
    def RescheduleTo(self, kernelspace, abb, task):
        """Reschedule to a specific task"""

        # Step 1: Set the current running marker. The current running
        # task is absolutly sure here.
        if abb.function.subtask == task:
            self.Comment(
                kernelspace,
                "OPTIMIZATION: We do not have to update the current_task entry"
            )
        elif task.name == "Idle":
            kernelspace.add(
                Statement("scheduler_.current_task = TaskList::idle_id"))
        else:
            kernelspace.add(
                Statement("scheduler_.SetCurrentTask(%s)" %
                          self.task_desc(task)))

        # Step 2: Determine the current system priority.
        abb_info = self.global_abb_info.for_abb(abb)
        priorities = set([x.dynamic_priority for x in abb_info.abbs_after])
        # When task is non-preemptable, we have to set the system
        # priority to RES_SCHEDULER
        if not task.conf.preemptable:
            priorities = [
                task.entry_abb.definite_after(
                    E.function_level).dynamic_priority
            ]
        if len(priorities) == 1:
            next_prio = unwrap_seq(priorities)
            if next_prio == abb.dynamic_priority:
                self.Comment(
                    kernelspace,
                    "OPTIMIZATION: We do not have to update the current system priority"
                )
                self.stats.add_data(abb, "opt:SetSystemPriority:not-needed",
                                    next_prio)
            else:
                self.Comment(
                    kernelspace,
                    "OPTIMIZATION: The system priority is determined." +
                    " Therefore we set it from a constant: %d == %s",
                    next_prio, self.system_graph.who_has_prio(next_prio))
                kernelspace.add(
                    Statement("scheduler_.SetSystemPriority(%d)" % next_prio))
                self.stats.add_data(abb, "opt:SetSystemPriority:constant",
                                    next_prio)
        else:
            # The current system priority is the priority of the next running task
            kernelspace.add(
                Statement("scheduler_.current_prio = scheduler_.tlist.%s" %
                          task.name))
            self.stats.add_data(abb, "opt:SetSystemPriority:general", True)

        # Step 3: Call the dispatcher!
        self.Dispatch(kernelspace, abb, task)
예제 #4
0
    def dump(self):
        ret = {"ABB": str(self.current_abb)}
        for subtask in self.get_unordered_subtasks():
            state = self.states[subtask.subtask_id]
            ret[subtask.name] = self.format_state(state)
            conts = self.get_continuations(subtask)
            assert len(conts) <= 1
            if len(conts) == 1:
                ret[subtask.name] += " " + str(unwrap_seq(conts))

        return ret
예제 #5
0
    def dump(self):
        ret = {"ABB": str(self.current_abb)}
        for subtask in self.get_unordered_subtasks():
            state = self.states[subtask.subtask_id]
            ret[subtask.name] = self.format_state(state)
            conts = self.get_continuations(subtask)
            assert len(conts) <= 1
            if len(conts) == 1:
                ret[subtask.name] += " " + str(unwrap_seq(conts))

        return ret
예제 #6
0
    def RescheduleTo(self, kernelspace, abb, task):
        """Reschedule to a specific task"""

        # Step 1: Set the current running marker. The current running
        # task is absolutly sure here.
        if abb.function.subtask == task:
            self.Comment(kernelspace, "OPTIMIZATION: We do not have to update the current_task entry")
        elif task.name == "Idle":
            kernelspace.add(Statement("scheduler_.current_task = TaskList::idle_id"))
        else:
            kernelspace.add(Statement("scheduler_.SetCurrentTask(%s)" % self.task_desc(task)))

        # Step 2: Determine the current system priority.
        abb_info = self.global_abb_info.for_abb(abb)
        priorities = set([x.dynamic_priority for x in abb_info.abbs_after])
        # When task is non-preemptable, we have to set the system
        # priority to RES_SCHEDULER
        if not task.preemptable:
            priorities = [task.entry_abb.definite_after(E.function_level).dynamic_priority]
        if len(priorities) == 1:
            next_prio = unwrap_seq(priorities)
            if next_prio == abb.dynamic_priority:
                self.Comment(kernelspace, "OPTIMIZATION: We do not have to update the current system priority")
                self.stats.add_data(abb, "opt:SetSystemPriority:not-needed", next_prio)
            else:
                self.Comment(kernelspace, 
                             "OPTIMIZATION: The system priority is determined."
                             + " Therefore we set it from a constant: %d == %s",
                             next_prio, self.system_graph.who_has_prio(next_prio))
                kernelspace.add(Statement("scheduler_.SetSystemPriority(%d)" % next_prio))
                self.stats.add_data(abb, "opt:SetSystemPriority:constant", next_prio)
        else:
            # The current system priority is the priority of the next running task
            kernelspace.add(Statement("scheduler_.current_prio = scheduler_.tlist.%s" % task.name))
            self.stats.add_data(abb, "opt:SetSystemPriority:general", True)

        # Step 3: Call the dispatcher!
        self.Dispatch(kernelspace, abb, task)