+++ /dev/null
-#include "scheduler_edf.h"
-#include "rbtree.h"
-#include <stdio.h>
-#include <rtems/system.h>
-#include <rtems/score/isr.h>
-#include <rtems/score/watchdog.h>
-#include <rtems/score/wkspace.h>
-#include <rtems/score/percpu.h>
-
-/* let the scheduler talk */
-//#define SCHED_VERBOSE
-
-
-void _Scheduler_edf_Initialize(void) {
- #ifdef SCHED_VERBOSE
- printf("Sched: Initialize");
- #endif
- // initialize the RB tree
- _Thread_Ready_EDF_chain.root = NULL;
- _Thread_Ready_EDF_chain.first = NULL;
- _Thread_Heir = NULL;
- _Thread_Executing = NULL;
-}
-
-void _Scheduler_edf_Block( Thread_Control *the_thread ) {
- #ifdef SCHED_VERBOSE
- printf("Sched: Block");
- #endif
- _Scheduler_edf_Extract(the_thread);
-
- /* TODO: flash critical section? */
-
- if ( _Thread_Is_heir( the_thread ) )
- _Scheduler_edf_Schedule();
-
- if ( _Thread_Is_executing( the_thread ) )
- _Thread_Dispatch_necessary = true;
-}
-
-void _Scheduler_edf_Schedule(void) {
- #ifdef SCHED_VERBOSE
- printf("Sched: Schedule");
- #endif
- // set the heir
- _Thread_Heir = (Thread_Control *) _Thread_Ready_EDF_chain.first;
-}
-
-void * _Scheduler_edf_Allocate( Thread_Control *the_thread) {
- #ifdef SCHED_VERBOSE
- printf("Sched: Allocate");
- #endif
- void * sched;
- RBT_Node *schinfo;
- sched = _Workspace_Allocate (sizeof(RBT_Node));
- the_thread->scheduler_info = (RBT_Node *) sched;
- //the_thread->real_priority = ABS_DEADLINE_MAXIMUM - _Watchdog_Ticks_since_boot-2;
- //the_thread->is_preemptible = TRUE;
- //the_thread->budget_algorithm = THREAD_CPU_BUDGET_ALGORITHM_NONE;
- //the_thread->budget_callout = NULL;
-
- schinfo = (RBT_Node *)(the_thread->scheduler_info);
- schinfo->rel_deadline = the_thread->real_priority;
- schinfo->abs_deadline = 0;
- schinfo->left = NULL;
- schinfo->right = NULL;
- schinfo->parent = NULL;
- schinfo->ready_chain = &_Thread_Ready_EDF_chain;
-
- return sched;
-}
-
-void _Scheduler_edf_Free( Thread_Control *the_thread) {
- #ifdef SCHED_VERBOSE
- printf("Sched: Free");
- #endif
- _Workspace_Free (the_thread->scheduler_info);
-}
-
-void _Scheduler_edf_Update( Thread_Control *the_thread) {
- #ifdef SCHED_VERBOSE
- printf("Sched: Update");
- #endif
- // after a priority changes, just extract and insert again
- //in case it is in the tree
-// EDF_Chain_Control* chain = ((RBT_Node*)the_thread->scheduler_info)->ready_chain;
-// _RBT_Extract(chain, the_thread);
-// _RBT_Insert(chain, the_thread); // preserve the abs_deadline
-}
-
-void _Scheduler_edf_Unblock( Thread_Control *the_thread ) {
- #ifdef SCHED_VERBOSE
- printf("Sched: Unblock");
- #endif
- _Scheduler_edf_Enqueue(the_thread);
- /* TODO: flash critical section? */
-
- /*
- * If the thread that was unblocked is more important than the heir,
- * then we have a new heir. This may or may not result in a
- * context switch.
- *
- * Normal case:
- * If the current thread is preemptible, then we need to do
- * a context switch.
- * Pseudo-ISR case:
- * Even if the thread isn't preemptible, if the new heir is
- * a pseudo-ISR system task, we need to do a context switch.
- */
- if ( the_thread->current_priority < _Thread_Heir->current_priority ) {
- _Thread_Heir = the_thread;
- if ( _Thread_Executing->is_preemptible || the_thread->current_priority == 0 )
- _Thread_Dispatch_necessary = true;
- }
-}
-
-void _Scheduler_edf_Yield( void ) {
- #ifdef SCHED_VERBOSE
- printf("Sched: Yield");
- #endif
-
- RBT_Node *sched_info;
- ISR_Level level;
- Thread_Control *executing;
- EDF_Chain_Control *ready;
-
- executing = _Thread_Executing;
- sched_info = (RBT_Node *) executing->scheduler_info;
- ready = sched_info->ready_chain;
- _ISR_Disable( level );
- if ( !_RBT_Has_only_one_node( ready ) ) {
- _RBT_Extract(ready,executing);
- _RBT_Insert(ready,executing); // preserve the abs_deadline
-
- _ISR_Flash( level );
-
- if ( _Thread_Is_heir( executing ) )
- _Thread_Heir = (Thread_Control *) ready->first;
- _Thread_Dispatch_necessary = TRUE;
- }
- else if ( !_Thread_Is_heir( executing ) )
- _Thread_Dispatch_necessary = TRUE;
-
- _ISR_Enable( level );
-
-}
-
-void _Scheduler_edf_Enqueue( Thread_Control *the_thread) {
- #ifdef SCHED_VERBOSE
- printf("Sched: Enqueue");
- #endif
- RBT_Node *node = (RBT_Node*)the_thread->scheduler_info;
- EDF_Chain_Control *chain = node->ready_chain;
- if (node->rel_deadline == 255) //hack for idle task
- node->abs_deadline = ABS_DEADLINE_MAXIMUM;
- else
- node->abs_deadline = _Watchdog_Ticks_since_boot + node->rel_deadline;
- _RBT_Insert(chain,the_thread);
-
-}
-
-void _Scheduler_edf_Enqueue_first( Thread_Control *the_thread) {
- #ifdef SCHED_VERBOSE
- printf("Sched: Enqueue_first");
- #endif
- // FIXME: force first position
- _Scheduler_edf_Enqueue(the_thread);
-}
-
-void _Scheduler_edf_Extract( Thread_Control *the_thread) {
- #ifdef SCHED_VERBOSE
- printf("Sched: Extract");
- #endif
- EDF_Chain_Control* chain = ((RBT_Node*)the_thread->scheduler_info)->ready_chain;
- _RBT_Extract(chain,the_thread);
-}
-
+++ /dev/null
-#ifndef _SCHEDULER_EDF_H
-#define _SCHEDULER_EDF_H
-
-#include <rtems/score/scheduler.h>
-#include <rtems/score/chain.h>
-#include <rtems/score/thread.h>
-#include "edf_types.h"
-
-// keeps the ready queue for EDF
-EDF_Chain_Control _Thread_Ready_EDF_chain;
-
-#define SCHEDULER_EDF_ENTRY_POINTS \
- { \
- _Scheduler_edf_Initialize, /* initialize entry point */ \
- _Scheduler_edf_Schedule, /* schedule entry point */ \
- _Scheduler_edf_Yield, /* yield entry point */ \
- _Scheduler_edf_Block, /* block entry point */ \
- _Scheduler_edf_Unblock, /* unblock entry point */ \
- _Scheduler_edf_Allocate, /* allocate entry point */ \
- _Scheduler_edf_Free, /* free entry point */ \
- _Scheduler_edf_Update, /* update entry point */ \
- _Scheduler_edf_Enqueue, /* enqueue entry point */ \
- _Scheduler_edf_Enqueue_first, /* enqueue_first entry point */ \
- _Scheduler_edf_Extract /* extract entry point */ \
- }
-
-
-
-/**
- * This routine initializes the priority scheduler.
- */
-void _Scheduler_edf_Initialize(void);
-
-/**
- * This routine removes @a the_thread from the scheduling decision,
- * that is, removes it from the ready queue. It performs
- * any necessary scheduling operations including the selection of
- * a new heir thread.
- *
- * @param[in] the_thread is the thread to be blocked
- */
-void _Scheduler_edf_Block(
- Thread_Control *the_thread
-);
-
-/**
- * This kernel routine sets the heir thread to be the next ready thread
- * by invoking the_scheduler->ready_queue->operations->first().
- */
-void _Scheduler_edf_Schedule(void);
-
-/**
- * This routine allocates @a the_thread->scheduler.
- *
- * @param[in] the_thread is the thread the scheduler is allocating
- * management memory for
- */
-void * _Scheduler_edf_Allocate(
- Thread_Control *the_thread
-);
-
-/**
- * This routine frees @a the_thread->scheduler.
- *
- * @param[in] the_thread is the thread whose scheduler specific information
- * will be deallocated.
- */
-void _Scheduler_edf_Free(
- Thread_Control *the_thread
-);
-
-/**
- * This routine updates @a the_thread->scheduler based on @a the_scheduler
- * structures and thread state.
- *
- * @param[in] the_thread will have its scheduler specific information
- * structure updated.
- */
-void _Scheduler_edf_Update(
- Thread_Control *the_thread
-);
-
-/**
- * This routine adds @a the_thread to the scheduling decision,
- * that is, adds it to the ready queue and
- * updates any appropriate scheduling variables, for example the heir thread.
- *
- * @param[in] the_thread will be unblocked
- */
-void _Scheduler_edf_Unblock(
- Thread_Control *the_thread
-);
-
-/**
- * This routine is invoked when a thread wishes to voluntarily
- * transfer control of the processor to another thread in the queue.
- *
- * This routine will remove the running THREAD from the ready queue
- * and place it immediately at the rear of this chain. Reset timeslice
- * and yield the processor functions both use this routine, therefore if
- * reset is true and this is the only thread on the queue then the
- * timeslice counter is reset. The heir THREAD will be updated if the
- * running is also the currently the heir.
- */
-void _Scheduler_edf_Yield( void );
-
-/**
- * This routine puts @a the_thread on to the priority-based ready queue.
- *
- * @param[in] the_thread will be enqueued at the TAIL of its priority.
- */
-void _Scheduler_edf_Enqueue(
- Thread_Control *the_thread
-);
-
-/**
- * This routine puts @a the_thread to the head of the ready queue.
- * For priority-based ready queues, the thread will be the first thread
- * at its priority level.
- *
- * @param[in] the_thread will be enqueued at the HEAD of its priority.
- */
-void _Scheduler_edf_Enqueue_first(
- Thread_Control *the_thread
-);
-
-/**
- * This routine removes a specific thread from the scheduler's set
- * of ready threads.
- *
- * @param[in] the_thread will be extracted from the ready set.
- */
-void _Scheduler_edf_Extract(
- Thread_Control *the_thread
-);
-
-
-
-#endif /*_SCHEDULER_EDF_H*/
\ No newline at end of file