Esempio n. 1
0
 def test_get_rta_of_taskset(self):
     tsk = Taskset("default")
     a = Task(2, 5000, 10000, 1, 1, 50000, 50000, 50000, 50000)
     b = Task(2, 5000, 10000, 2, 1, 50000, 50000, 50000, 50000)
     c = Task(2, 5000, 10000, 2, 1, 50000, 50000, 50000, 50000)
     d = Task(2, 5000, 10000, 1, 1, 50000, 50000, 50000, 50000)
     tsk.append(a)
     tsk.append(b)
     tsk.append(c)
     tsk.append(d)
     rta = tsk.get_high_util()
     self.assertEqual(rta, 0.2)
Esempio n. 2
0
 def test_get_lo_crit_utilization_of_taskset(self):
     tsk = Taskset("default")
     a = Task(1, 5000, 10000, 1, 1, 50000, 50000, 50000, 50000)
     b = Task(2, 5000, 10000, 2, 1, 50000, 50000, 50000, 50000)
     c = Task(1, 5000, 10000, 2, 1, 50000, 50000, 50000, 50000)
     d = Task(2, 5000, 10000, 1, 1, 50000, 50000, 50000, 50000)
     tsk.append(a)
     tsk.append(b)
     tsk.append(c)
     tsk.append(d)
     util = tsk.get_high_util()
     self.assertEqual(util, 0.2)
Esempio n. 3
0
 def __init__(self, file, folder="."):
     self.taskset = Taskset("ptamc")
     self.processed_taskset = Taskset("ptamc")
     self.file = folder + '/' + file
     self.pt_array = []
Esempio n. 4
0
class PtAMC(AmcRtb):
    def __init__(self, file, folder="."):
        self.taskset = Taskset("ptamc")
        self.processed_taskset = Taskset("ptamc")
        self.file = folder + '/' + file
        self.pt_array = []

    def __load_from_json(self, file=None):
        """Load taskset from json save."""
        try:
            if file is None:
                file = self.file
            self.taskset.generate_taskset_from_json(file)
        except IOError:
            print("Error opening file {0}.\n".format(file))

    def __assign_priorities(self):
        """Use amc-rtb approach to assign priority."""
        self.taskset = self.assign_priorities(self.taskset)

    def __get_lo_crit_response_time(self, task):
        """get worst case response time in low crit mode."""
        R_i_lo = task.c_lo
        high_prio_tasks = self.taskset.get_high_prio(task)
        for t in high_prio_tasks:
            R_i_lo += math.ceil(R_i_lo / t.t_lo) * t.c_lo
        return R_i_lo

    def __get_max_blocking(self, task, mode='normal'):
        """Determine the maximum blocking encountered by task in mode."""
        B_i = 0
        if mode == 'normal':
            interfer_tasks = self.taskset.get_taskset_low_crit_low_prio(task)
            for t in interfer_tasks:
                if self.pt_array[task.index] < self.pt_array[t.index]:
                    B_i = max(B_i, t.c_lo)
        elif mode == 'high':
            interfer_tasks = self.taskset.get_taskset_high_crit_low_prio(task)
            for t in interfer_tasks:
                if self.pt_array[task.index] < self.pt_array[t.index]:
                    B_i = max(B_i, t.c_hi)
        return B_i

    def __get_hi_crit_response_time(self, task):
        """Get worst case response time in high crit mode."""
        R_i_hi = task.c_hi
        high_prio_tasks = self.taskset.get_taskset_low_crit_high_prio(task)
        for t in high_prio_tasks:
            R_i_hi += math.ceil(R_i_hi / t.t_hi) * t.c_lo
        return R_i_hi

    def __get_worst_case_response_time(self, task):
        """Get the worst case response time for task in crit transition."""

        # First find the level i Busy Period in low crit mode.

        # tasks with priority greater than or equal to task.
        taskset_hep = self.taskset.get_high_equal_prio_tasks(task)
        B_i_lo = self.__get_max_blocking(task, "normal")
        LBP_i_lo = B_i_lo
        for t in taskset_hep:
            LBP_i_lo += math.ceil(LBP_i_lo / t.t_lo) * t.c_lo

        R_i_trans = 0
        for q in range(int(math.floor(LBP_i_lo / task.t_lo))):
            R_i_trans = max(R_i_trans,
                            self.__get_transition_response_time(task, q))
        return R_i_trans

    def __get_transition_response_time(self, task, q=0):
        """Response time for transition from low to high crit."""
        # Determine worst case starting point of task while in low criticality
        # mode.
        B_i_lo = self.__get_max_blocking(task, "normal")
        B_i_hi = self.__get_max_blocking(task, "high")
        S_i_q_lo = B_i_lo + q * task.c_lo
        high_prio_tasks = self.taskset.get_prio_tasks(task)
        for task in high_prio_tasks:
            S_i_q_lo += (1 + math.floor(S_i_q_lo / task.pr_lo)) * task.c_lo
        # Determine worst case stopping time.
        F_i_q_lo = S_i_q_lo + task.c_lo
        for t in high_prio_tasks:
            F_i_q_lo += (math.ceil(F_i_q_lo / t.t_lo) -
                         (1 + math.floor(S_i_q_lo / t.t_lo)) * t.c_lo)

        # Determine the worst case blocking while in transition to high crit.
        # Assuming no offset release of the task.
        if q == 0:
            B_i_q_tran = max(B_i_hi, B_i_lo)
        else:
            B_i_q_tran = B_i_lo
        # Determine Worst case starting point while in criticality transition.
        high_prio_lo_crit_tasks = self.taskset.get_taskset_low_crit_high_prio(
            task)
        high_prio_hi_crit_tasks = self.taskset.get_taskset_high_crit_high_prio(
            task)

        S_i_q_trans = B_i_q_tran + q * task.c_lo

        for t in high_prio_lo_crit_tasks:
            S_i_q_trans += math.ceil(S_i_q_lo / t.t_lo) * t.c_lo

        for t in high_prio_hi_crit_tasks:
            S_i_q_trans += (1 + math.floor(S_i_q_trans / t.t_lo)) * t.c_hi

        # Worst case completion time during criticality transition when transition
        # occurs before S_i_q_lo.
        F_i_q_trans_bf = S_i_q_trans + task.c_hi
        for t in high_prio_hi_crit_tasks:
            F_i_q_trans_bf += ((math.ceil(F_i_q_trans_bf / t.t_lo) -
                                (1 + math.floor(S_i_q_trans / t.t_lo))) *
                               task.c_hi)

        # Worst case completion time during criticality transition, when transition
        # occurs after S_i_q_lo
        F_i_q_trans_af = S_i_q_lo + task.c_hi
        for t in high_prio_lo_crit_tasks:
            F_i_q_trans_af += ((math.ceil(F_i_q_lo / t.t_lo) -
                                (1 + math.floor(S_i_q_lo / t.t_lo))) *
                               task.c_lo)

        for t in high_prio_hi_crit_tasks:
            F_i_q_trans_af += ((math.ceil(F_i_q_trans_af / t.t_lo) -
                                (1 + math.floor(S_i_q_lo / t.t_lo))) * t.c_hi)

        R_i_q = max(F_i_q_trans_bf, F_i_q_trans_af) - q * t.t_lo
        return R_i_q

    def __is_taskset_schedulable(self):
        """Sufficient schedulability test for pt-amc.
        Two necessary conditions are checked:
        1. Schedulability in low criticality.
        2. Schedulability in high crit in transition.
        """
        Lo_schedulable = True
        Hi_schedulable = True
        for task in self.taskset:
            if self.__get_lo_crit_response_time(task) < task.d_lo:
                continue
            else:
                Lo_schedulable = False
                break
        if Lo_schedulable:
            hi_tasks = self.taskset.get_tasks_by_crit('high')
            for task in hi_tasks:
                trans_rta = self.__get_transition_response_time(task)
                hi_rta = self.__get_hi_crit_response_time(task)
                if max(trans_rta, hi_rta) < task.d_lo:
                    continue
                else:
                    Hi_schedulable = False
                    break
        return Lo_schedulable and Hi_schedulable

    def __generate_preemption_threshold(self):
        """Maximal Preemption Threshold Assignment Algorithm(MPTAA) implementation.
        pt_array set with task preemption values, index corresponds to task index in 
        taskset object.
        """
        no_tasks = len(self.taskset)
        pt_array = [self.taskset[i].prio for i in range(no_tasks)]
        for i in reversed(range(no_tasks)):
            schedulable = True
            j = i + 1
            while schedulable and pt_array[i] < no_tasks:
                self.pt_array[i] += 1
                schedulable = self.__is_taskset_schedulable()
                if not schedulable:
                    if pt_array[i]:
                        pt_array[i] -= 1
                    else:
                        ValueError(
                            "Negative preemption threshold assignment.\n")
                j = j + 1
                if j >= no_tasks:
                    break
        for i in range(no_tasks):
            self.processed_taskset[i].pt = pt_array[
                i]  # Assign the calculated preemption threshold to the taskset.

    def get_processed_taskset(self):
        return self.processed_taskset

    def generate_ptamc(self, file):
        """Generate ptamc schedule for taskset given in json file."""
        self.__load_from_json(file)
        self.__generate_preemption_threshold()
        return self.processed_taskset
Esempio n. 5
0
 def __init__(self, folder=None, file=None):
     self.folder = folder
     self.file = folder + '/' + file
     self.taskset = Taskset()
     self.processed_taskset = None
     self.slack_vectors = []
Esempio n. 6
0
class Zss:
    def __init__(self, folder=None, file=None):
        self.folder = folder
        self.file = folder + '/' + file
        self.taskset = Taskset()
        self.processed_taskset = None
        self.slack_vectors = []

    @staticmethod
    def __create_slack_instance(start, duration):
        """Create a new slack tuple: (start time, duratiom)"""
        slack_instance = {
            "budget": duration,
            "start": start,
            "deadline": start + duration
        }
        return slack_instance

    @staticmethod
    def __sort_slack(slacklist):
        """Sort slack by start time."""
        return sorted(slacklist, key=lambda x: x[0])

    def __retrieve_taskset(self):
        """Load tasksets from json file."""
        json_taskset = []
        self.taskset.generate_taskset_from_json(self.file)
        print("loaded {0} tasksets from files".format(len(self.taskset)))

    def __save_zero_slack_taskset(self):
        """Create output folder and save the calculated taskset."""
        output_dir = self.folder + 'output'
        try:
            os.makedirs(self.folder + 'output')
        except OSError as exception:
            if exception.errno != errno.EEXIST:
                raise FileExistsError(errno)
        file_name = output_dir + str("zss") + '_taskset_processed.json'
        self.taskset.save_taskset_to_json(file_name)
        print("wrote {0} tasksets to {1} directory.\n", len(self.taskset),
              output_dir)

    @staticmethod
    def __get_conditional_taskset(task, taskset, condition_check):
        """Filter given taskset as per the given condition check function."""
        filtered_taskset = []
        for t in taskset:
            if condition_check(task, t):
                filtered_taskset.append(task)
        return filtered_taskset

    @staticmethod
    def __start_of_trailing_slack(t_i, slack_vec):
        """Get instance of trailing slack to given task."""
        b_i = t_i.budget  # Task budget.
        d_i = t_i.deadline  # Task deadline.
        trailing_slack_start = -1
        status = True
        index = 0
        rev_slack_vec = sorted(slack_vec,
                               key=lambda x: x["deadline"],
                               reverse=True)
        for i, slack in enumerate(rev_slack_vec):
            # Slack needs to be searched for deadline upto the deadline of
            # task being tested.
            if slack.deadline <= d_i:
                index = i
                break
        if (index):
            slack_accumulated = 0
            for slack in rev_slack_vec[index:]:
                # Search for slack instance able to meet budget in c mode.
                slack_accumulated += slack["budget"]
                if slack_accumulated >= b_i:
                    trailing_slack_start = slack[
                        "start"]  # Coarse starting time of slack.
                    break
            if slack_accumulated <= b_i:  # Couldn't find enough slack for t_i.
                status = False
        else:
            status = False
        return (status, trailing_slack_start)

    @staticmethod
    def __get_slack_upto_instance(slack_vec, slack_instance, t_i):
        """Total available slack upto slack_instance."""
        avail_slack = 0
        slack_index = 0
        for index, slack in enumerate(slack_vec):
            if slack_instance <= slack["start"]:
                slack_index = index
                break

        if slack_index:
            for slack in slack_vec:
                if t_i.budget <= avail_slack:
                    break
                else:
                    avail_slack += slack["budget"]
        return avail_slack

    @staticmethod
    def __get_zero_slack_instant(task, norm_slack, high_slack):
        """Calculate the maximum available slack."""
        pass

    @staticmethod
    def __get_effective_budget(task, prio, mode):
        """Get the effective execution budget for task."""
        effective_budget = 0
        if task.prio > prio:
            if task.crit == 'normal':
                effective_budget = task.b_lo
            else:
                effective_budget = task.b_hi
        else:
            if task.crit == 'high':
                effective_budget = task.b_lo - task.slack

        return effective_budget

    def __get_slack_vector(self, task, taskset, mode='normal'):
        """An ordered list of slacks available in the given given taskset.
           Implementation for a rate-monotonic approach.
           implementation and notations as per Algorithm-3 in paper.
        """
        C_i_v = 0
        R_current = C_i_v
        interfering_tasks_c = self.taskset.__get_taskset_high_crit_high_prio(
            task)
        interfering_tasks_n = self.taskset.__get_taskset_normal_crit_high_prio(
            task)
        while (R_current >= t.period):
            R_previous = R_current
            b = 0
            while R_previous == R_current or R_current <= t:
                R_prevous = R_current
                R_current = C_i_v + self.__get_effective_budget(R_previous)
                b = t
                for task in taskset:
                    A = math.ceil(R_previous / task.period) * task.budget
                    if A < b:
                        A = b
                        I_m = task
                if R_previous == R_current:
                    R_current = R_current + self.__get_effective_budget(
                        I_m, mode)

    @staticmethod
    def __are_vectors_equal(vec1, vec2):
        """Vector element wise comparator"""
        status = True
        if len(vec1) != len(vec2):
            raise ValueError("List should be of same size.\n")
        len_vec = len(vec1)
        comparator_list = [
            vec1[n].budget == vec2[n].budget for n in range(len_vec)
        ]
        for flag in comparator_list:
            if not flag:
                status = False
        return status

    def __compute_final_slack_instant(self, taskset):
        """Calculate the zero slack instance of taskset."""
        slack_instant = None
        slack_before_cycle = []
        slack_after_cycle = []
        taskset_high_crit = taskset.__get_tasks_by_crit(taskset, 'high')

        while slack_before_cycle != slack_after_cycle:
            slack_before_cycle = slack_after_cycle
            for index, task in enumerate(taskset):
                normal_slack_vec = self.__get_slack_vector(task, taskset)
                high_slack_vec = self.__get_slack_vector(
                    task, taskset_high_crit)
                slack_after_cycle = self.__get_zero_slack_instant(
                    task, normal_slack_vec, high_slack_vec)
                # Stop when no more slack movement can be made between normal and
                # critical mode.
                if self.__are_vectors_equal(slack_before_cycle,
                                            slack_after_cycle):
                    break

    def do_zero_slack_assignment(self):
        """public function to invoke zero slack calculation."""
        for taskset in self.tasksets:
            zss_taskset = self.__computer_final_slack_instant(taskset)
Esempio n. 7
0
 def test_add_remove_task_from_taskset(self):
     a = Taskset("default")
     b = Task(2, 5000, 10000, 1, 1, 50000, 50000, 50000, 50000)
     a.append(b)
     c = a.pop()
     self.assertEqual(b.crit, c.crit)
Esempio n. 8
0
 def test_create_taskset(self):
     A = Taskset("default")
     self.assertEqual(A.scheduler, "default")