TABLE OF CONTENTS


/Scheduler-FPPT [ Modules ]

[ Top ] [ Modules ]

DESCRIPTION

Earliest deadline first, automatic/fixed priorities with preemption threshold EDF,A/F PPT


Scheduler-FPPT/Os_sched_settings [ Constants ]

[ Top ] [ Scheduler-FPPT ] [ Constants ]

DESCRIPTION

FPPT scheduler Settings

DECLARATION

#if Varexist( "Os_sched_enable_threshold") = False
   Const Os_sched_enable_threshold = True                   ' False   '
#endif

#if Varexist( "Os_sched_enable_automatic") = False
   Const Os_sched_enable_automatic = False
#endif

#if Varexist( "Os_sched_priority_inheritance") = False
   Const Os_sched_priority_inheritance = True
#endif

#if Varexist( "Os_sched_max_priorities") = False
   Const Os_sched_max_priorities = 16
#endif

Scheduler-FPPT/Scheduler_Header [ Object Headers ]

[ Top ] [ Scheduler-FPPT ] [ Object Headers ]

DESCRIPTION

Scheduler-specific Task header extension

DECLARATION

Const Os_sched_hdr_priority_ptr = Os_task_hdr_size_common + 0
Const Os_sched_hdr_interval_ptr = Os_task_hdr_size_common + 1
Const Os_sched_hdr_deadline_ptr = Os_task_hdr_size_common + 3
Const Os_sched_hdr_elapsed_ptr = Os_task_hdr_size_common + 5
Const Os_sched_hdr_remaining_ptr = Os_task_hdr_size_common + 7
Const Os_sched_hdr_parent_ptr = Os_task_hdr_size_common + 9
Const Os_sched_hdr_next_ptr = Os_task_hdr_size_common + 11
Const Os_sched_hdr_queuenext_ptr = Os_task_hdr_size_common + 13
Const Os_task_hdr_size_scheduler_0 = 15
#if Os_sched_enable_threshold = True
   Const Os_sched_hdr_threshold_ptr = Os_task_hdr_size_scheduler_0 + 0
   Const Os_task_hdr_size_scheduler_1 = Os_task_hdr_size_scheduler_0 + 1
#else
   Const Os_task_hdr_size_scheduler_1 = Os_task_hdr_size_scheduler_0
#endif
#if Os_sched_enable_automatic = True
   Const Os_sched_hdr_bla = Os_task_hdr_size_scheduler_1 + 0
   Const Os_task_hdr_size_scheduler_2 = Os_task_hdr_size_scheduler_1 + 0
#else
   Os_task_hdr_size_scheduler_2 = Os_task_hdr_size_scheduler_1
#endif
#if Os_sched_priority_inheritance = True
   Const Os_sched_hdr_runningprio_ptr = Os_task_hdr_size_scheduler_2 + 0
   Const Os_task_hdr_size_scheduler_3 = Os_task_hdr_size_scheduler_2 + 1
#else
   Const Os_task_hdr_size_scheduler_3 = Os_task_hdr_size_scheduler_2
#endif
Const Os_task_hdr_size_scheduler = Os_task_hdr_size_scheduler_3

Scheduler-FPPT/Taskqueue_Header [ Object Headers ]

[ Top ] [ Scheduler-FPPT ] [ Object Headers ]

DESCRIPTION

Priority sorted Task waiting queue

DECLARATION

Const Os_sched_taskqueue_hdr_head_ptr = 0
Const Os_sched_taskqueue_hdr_size = 2

Scheduler-FPPT/Os_sched_check [ Functions ]

[ Top ] [ Scheduler-FPPT ] [ Functions ]

DESCRIPTION

Checks inside the Timer isr if the scheduler update needs to be called

DECLARATION

Macro Os_sched_check

SOURCE

   Decr Os_sched_next_event
   Incr Os_sched_time_delta
   If Os_sched_next_event = 0 Then Os_timer_enable_kernel = Os_timer_enable_kernel + 2
End Macro

Scheduler-FPPT/Os_sched_event [ Functions ]

[ Top ] [ Scheduler-FPPT ] [ Functions ]

DESCRIPTION

Handles a Task event, resumes the Task if blocked.

DECLARATION

Sub Os_sched_event()

SOURCE

   Local Tempblock As Word

   ' check if Task is active   '
   Tempblock = Getword(os_event_task , Os_sched_hdr_next_ptr)
   If Tempblock = 0 Then
      ' no, resume   '
      Os_sched_resume Os_event_task
   End If
End Sub

Scheduler-FPPT/Os_sched_idle_task [ Functions ]

[ Top ] [ Scheduler-FPPT ] [ Functions ]

DESCRIPTION

The idle Task is called when there are no other tasks left need to run. It waits all the time if another Task becomes ready.

DECLARATION

Os_sched_idle_task_entry:

SOURCE

   Do
      Os_sched_time_delta = 0                               ' FIXME   '
      Os_task_yield
   Loop

Scheduler-FPPT/Os_sched_priority_inheritance [ Functions ]

[ Top ] [ Scheduler-FPPT ] [ Functions ]

DESCRIPTION

The running Task inherits the higher priority of a Task waiting for a resource occupied by a lesser priority Task.

DECLARATION

Macro Os_sched_priority_inheritance

SOURCE

   #if Os_enable_priority_inheritance = True And Varexist( "Os_sched_running_priority") = True
      ' Priority inversion if a blocked Task has a higher priority than the owner Task   '
      ___r16 = Getbyte(Task , Os_sched_hdr_priority_ptr)
      If Os_sched_running_priority < ___r16 Then Setbyte Os_task_active , Os_sched_hdr_runningprio_ptr , ___r16
   #endif
End Macro

Scheduler-FPPT/Os_sched_reset_priority [ Functions ]

[ Top ] [ Scheduler-FPPT ] [ Functions ]

DESCRIPTION

Resets a previously priority inheritance.

DECLARATION

Macro Os_sched_reset_priority

SOURCE

   #if Os_enable_priority_inheritance = True And Varexist( "Os_sched_running_priority") = True
      Setbyte Os_task_active , Os_sched_hdr_runningprio_ptr , 0
   #endif
End Macro

Scheduler-FPPT/Os_sched_resume [ Functions ]

[ Top ] [ Scheduler-FPPT ] [ Functions ]

DESCRIPTION

Puts a blocked Task back back on the ready list

DECLARATION

Sub Os_sched_resume(byref Task As Word)

SOURCE

   Local Task_interval As Word
   Local List_remaining As Word
   Local Object As Word
   Local Previous_object As Word

   Previous_object = 0
   Task_interval = Getword(Task , Os_sched_hdr_interval_ptr)
   Object = Os_sched_waiting_list

   ' insert into waiting list sorted by remaining interval time   '
   Do
      If Object = 0 Then
         ' waiting list is empty or end reached   '
         Setword Task , Os_sched_hdr_next_ptr , 0
         If Os_sched_waiting_list = 0 Then
            ' Task becomes list head   '
            Os_sched_waiting_list = Task
         Else
            ' insert Task after last element   '
            Setword Previous_object , Os_sched_hdr_next_ptr , Task
         End If
         Exit Do
      End If
      List_remaining = Getword(object , Os_sched_hdr_remaining_ptr)
      If Task_interval < List_remaining Then
         ' sort by ascending interval   '
         If Previous_object = 0 Then
            ' insert before first element   '
            Setword Task , Os_sched_hdr_next_ptr , Os_sched_waiting_list
            Os_sched_waiting_list = Task
         Else
            ' current element's remaining time > Task interval, insert after previous element (before current)   '
            Os_list_insert Previous_object , Task , Os_sched_hdr_next_ptr
         End If
         Exit Do
      End If
      Previous_object = Object
      Object = Getword(object , Os_sched_hdr_next_ptr)
   Loop
   Setword Task , Os_sched_hdr_remaining_ptr , Task_interval
   Setword Task , Os_sched_hdr_parent_ptr , Os_sched_waiting_list
   #if Os_sched_priority_inheritance = True
      Setbyte Task , Os_sched_hdr_runningprio , 0
   #endif
End Sub

Scheduler-FPPT/Os_sched_suspend [ Functions ]

[ Top ] [ Scheduler-FPPT ] [ Functions ]

DESCRIPTION

Removes a running Task from the ready list

DECLARATION

Sub Os_sched_suspend(byref Task As Word)

SOURCE

   Local List As Word

   ' remove from waiting or ready list   '
   List = Getword(Task , Os_sched_hdr_parent_ptr)
   Os_list_remove List , Task , Os_sched_hdr_next_ptr

   ' execute next Task   '
   If Task = Os_task_active Then Os_task_yield
End Sub

Scheduler-FPPT/Os_sched_taskqueue_insert [ Functions ]

[ Top ] [ Scheduler-FPPT ] [ Functions ]

DESCRIPTION

Inserts a Task in a Task waiting queue sorted by priority

DECLARATION

Sub Os_sched_taskqueue_insert(byref Taskqueue As Word , Byref Task As Word)

SOURCE

   ' insert into double linked list sorted by priority   '
   Local Queuehead As Word
   Local Taskpriority As Byte
   Local Searchpriority As Byte
   Local Searchtask As Word

   Queuehead = Getword(taskqueue , Os_sched_taskqueue_hdr_head_ptr)
   If Queuehead = 0 Then
      ' queue is empty, Task becomes queue head   '
      Queuehead = Task
      Setword Task , Os_sched_hdr_queuenext_ptr , 0
      'Setword Task , Os_sched_hdr_queueprev_ptr , 0   '
   Else
      ' search through list, insert higher priorities first, equal priorities LIFO   '
      Taskpriority = Getbyte(Task , Os_sched_hdr_priority_ptr)
      Searchtask = 0
      Do
         Searchpriority = Getbyte(queuehead , Os_sched_hdr_priority_ptr)
         If Searchpriority < Taskpriority Then Exit Do
         Searchtask = Queuehead
         Queuehead = Getword(queuehead , Os_sched_hdr_queuenext_ptr)
         If Queuehead = 0 Then
            ' end of queue, insert as last item   '
            Setword Searchtask , Os_sched_hdr_queuenext_ptr , Task
            'Setword Task , Os_sched_hdr_queueprev_ptr , Searchtask   '
            Setword Task , Os_sched_hdr_queuenext_ptr , 0
            Exit Sub
         End If
      Loop
      ' insert before found element   '
      Setword Task , Os_sched_hdr_queuenext_ptr , Queuehead
      If Searchtask <> 0 Then Setword Searchtask , Os_sched_hdr_queuenext_ptr , Task
   End If
End Sub

Scheduler-FPPT/Os_sched_taskqueue_remove [ Functions ]

[ Top ] [ Scheduler-FPPT ] [ Functions ]

DESCRIPTION

Removes a Task from a Task waiting queue

DECLARATION

Function Os_sched_taskqueue_remove(byref Taskqueue As Word) As Word

SOURCE

   Local Queuehead As Word
   Local Queuenext As Word

   Queuehead = Getword(taskqueue , Os_sched_taskqueue_hdr_head_ptr)
   If Queuehead <> 0 Then
      Queuenext = Getword(queuehead , Os_sched_hdr_queuenext_ptr)
      Setword Taskqueue , Os_sched_taskqueue_hdr_head_ptr , Queuenext
      'Setword Queuehead, Os_sched_hdr_queuenext_ptr, 0   '
   End If

   Os_sched_taskqueue_remove = Queuehead
End Function

Scheduler-FPPT/Os_sched_update [ Functions ]

[ Top ] [ Scheduler-FPPT ] [ Functions ]

DESCRIPTION

Updates the Task intervals and ready lists, determines when the update needs to be called again and selects the the running Task by his priority and his deadline.

DECLARATION

Sub Os_sched_update()

SOURCE

   Local Object As Word
   Local Task_priority As Byte
   Local Task_remaining As Word
   Local Search_object As Word
   Local Search_previous As Word
   Local Search_deadline As Word

   Os_sched_next_event = &HFFFF

   ' update waiting tasks intervals and   '
   ' move tasks that reached their interval to the priority- and earliest deadline first - sorted ready lists   '
   Object = Os_sched_waiting_list
   Do
      If Object = 0 Then
         ' waiting list is empty   '
         Exit Do
      End If
      ' calculate elapsed time   '
      Task_remaining = Getword(object , Os_sched_hdr_remaining_ptr)
      If Os_sched_time_delta < Task_remaining Then
         ' Task is not ready yet   '
         Task_remaining = Task_remaining - Os_sched_time_delta
         If Task_remaining < Os_sched_next_event Then Os_sched_next_event = Task_remaining       ' search nearest event   '
      Else                                                  ' Task has become ready to execute   '
         ' calculate time since the Task is ready   '
         Task_remaining = Os_sched_time_delta - Task_remaining
         Search_deadline = Getword(object , Os_sched_hdr_deadline_ptr)
         If Task_remaining < Search_deadline Then
            ' deadline not reached yet   '
            Task_remaining = Search_deadline - Task_remaining
         Else
            ' Task has reached the deadline (unschedulable), insert as first element   '
            Task_remaining = 0
         End If

         ' remove from waiting list   '
         Os_list_remove Os_sched_waiting_list , Object , Os_sched_hdr_next_ptr)

         ' insert into ready list   '
         Task_priority = Getbyte(object , Os_sched_hdr_priority_ptr)
         Search_object = Os_sched_ready_list(task_priority)
         Do
            If Search_object = 0 Then
               ' list is empty or end reached   '
               Setword Object , Os_sched_hdr_parent_ptr , Os_sched_ready_list(task_priority)
               Setword Object , Os_sched_hdr_next_ptr , 0
               If Os_sched_ready_list(task_priority) = 0 Then
                  ' Task becomes list head   '
                  Os_sched_ready_list(task_priority) = Object
               Else
                  ' insert Task after last element   '
                  Setword Search_previous , Os_sched_hdr_next_ptr , Object
               End If
               Exit Do
            End If

            Search_deadline = Getword(searchobject , Os_sched_hdr_remaining_ptr)
            If Task_remaining < Search_deadline Then
               If Search_previous = 0 Then
                  ' insert as first element   '
                  Setword Object , Os_sched_hdr_next_ptr , Os_sched_ready_list(task_priority)
                  Os_sched_ready_list(task_priority) = Object
               Else
                  ' insert after previous element   '
                  Os_list_insert Search_previous , Object , Os_sched_hdr_next_ptr
               End If
               Exit Do
            End If
            Search_previous = Search_object
            Search_object = Getword(search_object , Os_sched_hdr_next_ptr)
         Loop
         Setword Object , Os_sched_hdr_parent_ptr , Os_sched_ready_list(task_priority)
         Task_remaining = Task_remaining + Os_sched_time_delta       ' updated again in ready list   '
      End If
      Setword Object , Os_sched_hdr_remaining_ptr , Task_remaining
      Object = Getword(object , Os_sched_hdr_next_ptr)
   Loop

   ' update ready lists, select next Task to run   '
   Os_task_active = 0
   For Task_priority = Os_sched_max_priorities To 1 Step -1
      If Os_sched_ready_list(task_priority) <> 0 Then
         ' list with ready tasks is not empty   '
         If Os_task_active = 0 And Os_sched_running_priority < Task_priority Then       ' first Task in highest priority list is executed if priority > active Task threshold   '
            Os_task_active = Os_sched_ready_list(task_priority)
            ' remove from ready list   '
            Os_list_remove Os_sched_ready_list(task_priority) , Os_task_active , Os_sched_hdr_next_ptr

            ' insert into waiting list   '
            Os_sched_resume Os_task_active

            ' set running priority   '
            #if Os_sched_enable_threshold = True
               Os_sched_running_priority = Getbyte(Os_task_active , Os_sched_hdr_threshold_ptr)
            #else
               Os_sched_running_priority = Task_priority
            #endif
            #if Os_sched_priority_inheritance = True
               ___r16 = Getbyte(Os_task_active , Os_sched_hdr_runningprio_hdr)
               If Os_sched_running_priority < ___r16 Then Then Os_sched_running_priority = ___r16
            #endif
         End If

         ' update remaining (deadline) time in ready list   '
         Object = Os_sched_ready_list(task_priority)
         Do
            If Object = 0 Then Exit Do
            Task_remaining = Getword(object , Os_sched_hdr_remaining_ptr)
            If Os_sched_time_delta < Task_remaining Then
               ' update deadline   '
               Task_remaining = Task_remaining - Os_sched_time_delta
            Else
               ' Task has reached its deadline (unschedulable)   '
               Task_remaining = 0
            End If
            Setword Object , Os_sched_hdr_remaining_ptr , Task_remaining
            Object = Getword(object , Os_sched_hdr_next_ptr)       ' next element   '
         Loop
      End If
   Next

   If Os_task_active = 0 Then
      ' idle Task   '
      Os_task_active = Os_sched_idle_task
      Os_sched_running_priority = 0
   End If
   Os_sched_time_delta = 0
End Sub

Scheduler-FPPT/Os_sched_yield [ Functions ]

[ Top ] [ Scheduler-FPPT ] [ Functions ]

DESCRIPTION

Hands over CPU processing time to the next Task

DECLARATION

Sub Os_sched_yield()

SOURCE

   Os_sched_running_priority = 0                            ' every priority may preempt   '
'   Os_sched_time_delta = ?         ' FIXME   '
   Os_sched_update
End Sub