The EDF does not fire yet, necessary to readjust the rbtree.
Sorry for this huge commit.
#include_HEADERS =
-appfoo_SOURCES += init.c task_1.c
+appfoo_SOURCES += init.c task_1.c task_2.c scheduler_edf.c scheduler_priority.c rbtree.c
#appfoo_EMBEDTARFILES = rootfs
COND_EXTERN rtems_id Task_1_id; /* Task 1 id */
COND_EXTERN rtems_name Task_1_name; /* Task 1 name */
+COND_EXTERN rtems_id Task_2_id; /* Task 2 id */
+COND_EXTERN rtems_name Task_2_name; /* Task 2 name */
+
+
rtems_task Task_1(
rtems_task_argument argument
);
+rtems_task Task_2(
+ rtems_task_argument argument
+);
void bad_rtems_status(rtems_status_code status, int fail_level, const char *text);
}
#define TASK_1_PRIORITY 30
+#define TASK_2_PRIORITY 40
#define SHELL_TASK_PRIORITY 50
#ifdef __cplusplus
#include <rtems/monitor.h>
#include <rtems/shell.h>
+
#define BUILD_VERSION_STRING(major,minor,patch) \
__XSTRING(major) "." __XSTRING(minor) "." __XSTRING(patch)
"\n" );
Task_1_name = rtems_build_name( 'T', 'S', 'K', '1' );
+ Task_2_name = rtems_build_name( 'T', 'S', 'K', '2' );
status = rtems_task_create(
Task_1_name,
RTEMS_DEFAULT_ATTRIBUTES,
&Task_1_id
);
+
+
check_rtems_status(status, 0, "rtems_task_create of Task_1");
+
+ status = rtems_task_create(
+ Task_2_name,
+ TASK_2_PRIORITY,
+ RTEMS_MINIMUM_STACK_SIZE+0x10000,
+ RTEMS_DEFAULT_MODES /*& ~(RTEMS_TIMESLICE_MASK) | RTEMS_TIMESLICE*/,
+ RTEMS_DEFAULT_ATTRIBUTES,
+ &Task_2_id
+ );
+
+ check_rtems_status(status, 0, "rtems_task_create of Task_2");
+
status = rtems_task_start( Task_1_id, Task_1, 0 );
check_rtems_status(status, 0, "rtems_task_start of Task_1\n");
+ status = rtems_task_start( Task_2_id, Task_2, 0 );
+ check_rtems_status(status, 0, "rtems_task_start of Task_2\n");
+
+
rtems_shell_init("SHLL",RTEMS_MINIMUM_STACK_SIZE+0x1000,
SHELL_TASK_PRIORITY,"/dev/console",1,0, NULL);
status = rtems_task_delete( RTEMS_SELF );
- printf( "*** END OF TEST2 ***\n" );
+ printf( "*** END OF TEST3 ***\n" );
exit( 0 );
}
--- /dev/null
+#include <rtems/score/rbtree.h>
+#include <rtems/score/thread.h>
+#include "edf_types.h"
+
+
+static void _Rotate_Left(
+ EDF_Chain_Control *chain,
+ EDF_Node *node
+)
+{
+ EDF_Node *right = node->right;
+
+ if ((node->right = right->left))
+ right->left->parent = node;
+ right->left = node;
+ if ((right->parent = node->parent))
+ {
+ if (node == node->parent->left)
+ node->parent->left = right;
+ else
+ node->parent->right = right;
+ }
+ else
+ chain->root = right;
+ node->parent = right;
+}
+
+static void _Rotate_Right(
+ EDF_Chain_Control *chain,
+ EDF_Node *node
+)
+{
+ EDF_Node *left = node->left;
+
+ if ((node->left = left->right))
+ left->right->parent = node;
+ left->right = node;
+
+ if ((left->parent = node->parent))
+ {
+ if (node == node->parent->right)
+ node->parent->right = left;
+ else
+ node->parent->left = left;
+ }
+ else
+ chain->root = left;
+ node->parent = left;
+}
+
+void _RBT_Insert(
+ EDF_Chain_Control *chain,
+ EDF_Node *node
+)
+{
+ EDF_Node *parent, *child, *uncle, *gparent, *tmp;
+
+ parent = NULL;
+ child = chain->root;
+
+ /* Insert new node into tree */
+
+ while (child)
+ {
+ parent = child;
+ child = ( node->abs_deadline < child->abs_deadline ) \
+ ? child->left : child->right;
+ }
+
+ node->parent = parent;
+ node->left = NULL;
+ node->right = NULL;
+ node->color = RED;
+
+ if (parent)
+ {
+ if ( node->abs_deadline < parent->abs_deadline )
+ {
+ parent->left = node;
+ if ( parent == chain->first ) chain->first = node;
+ }
+ else parent->right = node;
+ } else
+ {
+ chain->root = node;
+ chain->first = node;
+ }
+
+ /* Insert_FixUp */
+ /* check and fix red-back properties eventually */
+ while ((parent = node->parent) && parent->color == RED)
+ {
+ gparent = parent->parent;
+
+ if (parent == gparent->left)
+ {
+ uncle = gparent->right;
+
+ if ( uncle && uncle->color == RED)
+ {
+ parent->color = BLACK;
+ uncle->color = BLACK;
+ gparent->color = RED;
+ node = gparent;
+ continue;
+ }
+
+ if (node == parent->right)
+ {
+ _Rotate_Left(chain,parent);
+ tmp = parent;
+ parent = node;
+ node = tmp;
+ }
+
+ parent->color = BLACK;
+ gparent->color = RED;
+ _Rotate_Right(chain, gparent);
+
+ } else {
+ uncle = gparent->left;
+
+ if (uncle && uncle->color == RED )
+ {
+ parent->color = BLACK;
+ uncle->color = BLACK;
+ gparent->color = RED;
+ node = parent->parent;
+ continue;
+ }
+
+ if (node == parent->left)
+ {
+ _Rotate_Right(chain, parent);
+ tmp = parent;
+ parent = node;
+ node = tmp;
+
+ }
+
+ parent->color = BLACK;
+ gparent->color = RED;
+ _Rotate_Left(chain, gparent);
+ }
+ }
+
+ chain->root->color = BLACK;
+}
+
+static void _RBT_Delete_Fixup(
+ EDF_Chain_Control *chain,
+ EDF_Node *node,
+ EDF_Node *parent
+)
+{
+ EDF_Node *other, *o_child;
+
+ while ((!node || node->color == BLACK) && node != chain->root)
+ {
+ if (parent->left == node)
+ {
+ other = parent->right;
+ if (other->color == RED)
+ {
+ other->color = BLACK;
+ parent->color = RED;
+ _Rotate_Left(chain, parent);
+ other = parent->right;
+ }
+ if ((!other->left ||
+ other->left->color == BLACK)
+ && (!other->right ||
+ other->right->color == BLACK))
+ {
+ other->color = RED;
+ node = parent;
+ parent = node->parent;
+ }
+ else
+ {
+ if (!other->right ||
+ other->right->color == BLACK)
+ {
+ if ((o_child = other->left))
+ o_child->color = BLACK;
+ other->color = RED;
+ _Rotate_Right(chain,other);
+ other = parent->right;
+ }
+ other->color = parent->color;
+ parent->color = BLACK;
+ if (other->right)
+ other->right->color = BLACK;
+ _Rotate_Left(chain,parent);
+ node = chain->root;
+ break;
+ }
+ }
+ else
+ {
+ other = parent->left;
+ if (other->color == RED)
+ {
+ other->color = BLACK;
+ parent->color = RED;
+ _Rotate_Right(chain,parent);
+ other = parent->left;
+ }
+ if ((!other->left ||
+ other->left->color == BLACK)
+ && (!other->right ||
+ other->right->color == BLACK))
+ {
+ other->color = RED;
+ node = parent;
+ parent = node->parent;
+ }
+ else
+ {
+ if (!other->left ||
+ other->left->color == BLACK)
+ {
+ register struct rb_node *o_right;
+ if ((o_child = other->right))
+ o_child->color = BLACK;
+ other->color = RED;
+ _Rotate_Left(chain,other);
+ other = parent->left;
+ }
+ other->color = parent->color;
+ parent->color = BLACK;
+ if (other->left)
+ other->left->color = BLACK;
+ _Rotate_Right(chain,parent);
+ node = chain->root;
+ break;
+ }
+ }
+ }
+ if (node)
+ node->color = BLACK;
+}
+
+
+void _RBT_Extract(
+ EDF_Chain_Control *chain,
+ EDF_Node *node
+)
+{
+ EDF_Node *child, *parent;
+ int color;
+
+ if ( chain->first == node )
+ {
+ if ( chain->first->right) chain->first = chain->first->right;
+ else chain->first = chain->first->parent;
+ }
+
+ if (!node->left)
+ child = node->right;
+ else if (!node->right)
+ child = node->left;
+ else
+ {
+ /* this will never happen since only the first node
+ * is being removed every time
+ */
+
+ EDF_Node *old = node, *left;
+
+ node = node->right;
+ while ((left = node->left) != NULL)
+ node = left;
+ child = node->right;
+ parent = node->parent;
+ color = node->color;
+
+ if (child)
+ child->parent = parent;
+ if (parent)
+ {
+ if (parent->left == node)
+ parent->left = child;
+ else
+ parent->right = child;
+ }
+ else
+ chain->root = child;
+
+ if (node->parent == old)
+ parent = node;
+ node->parent = old->parent;
+ node->color = old->color;
+ node->right = old->right;
+ node->left = old->left;
+
+ if (old->parent)
+ {
+ if (old->parent->left == old)
+ old->parent->left = node;
+ else
+ old->parent->right = node;
+ } else
+ chain->root = node;
+
+ old->left->parent = node;
+ if (old->right)
+ old->right->parent = node;
+ goto color;
+ }
+
+ parent = node->parent;
+ color = node->color;
+
+ if (child)
+ child->parent = parent;
+ if (parent)
+ {
+ if (parent->left == node)
+ parent->left = child;
+ else
+ parent->right = child;
+ }
+ else
+ chain->root = child;
+
+ color:
+ if (color == BLACK)
+ _RBT_Delete_Fixup(chain,child,parent);
+}
+
+/*
+ * TRUE if there is only one node in tree
+ */
+
+boolean _RBT_Has_only_one_node(
+ EDF_Chain_Control *chain
+)
+{
+ if ( !chain->root ) return 0;
+ return ( chain->root->left == chain->root->right == NULL ) ;
+}
+
+/*
+ * Returns node with specific absolute deadline
+ */
+
+EDF_Node* _RBT_Search(
+ EDF_Chain_Control *chain,
+ Deadline_Control absdeadline
+)
+{
+ EDF_Node *current;
+
+ current = chain->root;
+ while (current != NULL) {
+ if ( absdeadline == current->abs_deadline) return current;
+ else {
+ current = (absdeadline < current->abs_deadline) ?
+ current->left : current->right;
+ }
+ }
+ return NULL;
+}
+
--- /dev/null
+#ifndef __RBTREE_h
+#define __RBTREE_h
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "edf_types.h"
+
+// This struct will be embedded into the Thread_Control control
+// as scheduler_info
+typedef struct RBT_node_struct {
+ Deadline_Control abs_deadline;
+ Deadline_Control rel_deadline;
+ EDF_Node *left;
+ EDF_Node *right;
+ EDF_Node *parent;
+ Node_Color color;
+ EDF_Chain_Control *ready_chain;
+} RBT_Node;
+
+void _RBT_Insert(EDF_Chain_Control *chain,EDF_Node *node);
+void _RBT_Extract(EDF_Chain_Control *chain,EDF_Node *node);
+EDF_Node* _RBT_Search(EDF_Chain_Control *chain,Deadline_Control absdeadline);
+boolean _RBT_Has_only_one_node(EDF_Chain_Control *chain);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __RBTREE_h */
--- /dev/null
+#include "scheduler_edf.h"
+#include "rbtree.h"
+#include <stdio.h>
+#include <rtems/system.h>
+#include <rtems/score/isr.h>
+
+/* let the scheduler talk */
+//#define SCHED_VERBOSE
+
+
+void _Scheduler_edf_Initialize(void) {
+ #ifdef SCHED_VERBOSE
+ printf("Sched: Initialize");
+ #endif
+ // nainicializovat strom
+ _Thread_Ready_EDF_chain.root = NULL;
+ _Thread_Ready_EDF_chain.first = NULL;
+}
+
+void _Scheduler_edf_Block( Thread_Control *the_thread ) {
+ #ifdef SCHED_VERBOSE
+ printf("Sched: Block");
+ #endif
+ _Scheduler_edf_Extract(the_thread);
+}
+
+void _Scheduler_edf_Schedule(void) {
+ #ifdef SCHED_VERBOSE
+ printf("Sched: Schedule");
+ #endif
+ // hastavit 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;
+ mem = _Workspace_Allocate (sizeof(RBT_node));
+ the_thread->scheduler_info = (RBT_node *) sched;
+ return mem;
+}
+
+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
+ _Scheduler_edf_Extract(the_thread);
+ _Scheduler_edf_Enqueue(the_thread);
+}
+
+void _Scheduler_edf_Unblock( Thread_Control *the_thread ) {
+ #ifdef SCHED_VERBOSE
+ printf("Sched: Unblock");
+ #endif
+ _Scheduler_edf_Enqueue(the_thread);
+}
+
+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);
+
+ _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
+ // insert do stromu
+ EDF_Chain_Control* chain = the_thread->scheduler_info->ready_chain;
+ _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
+ EDF_Chain_Control* chain = the_thread->scheduler_info->ready_chain;
+ _RBT_Insert(chain,the_thread);
+}
+
+void _Scheduler_edf_Extract( Thread_Control *the_thread) {
+ #ifdef SCHED_VERBOSE
+ printf("Sched: Extract");
+ #endif
+ EDF_Chain_Control* chain = 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
--- /dev/null
+// =====================================================================================
+// =====================================================================================
+// =====================================================================================
+
+/*
+ * Scheduler Priority Handler / Allocate
+ *
+ * Copyright (C) 2010 Gedare Bloom.
+ * Copyright (C) 2011 On-Line Applications Research Corporation (OAR).
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.com/license/LICENSE.
+ *
+ * $Id: schedulerpriorityallocate.c,v 1.1 2011/02/18 15:12:43 joel Exp $
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/config.h>
+#include <rtems/score/scheduler.h>
+#include <rtems/score/schedulerpriority.h>
+#include <rtems/score/wkspace.h>
+
+void* _Scheduler_priority_Allocate (
+ Thread_Control *the_thread
+)
+{
+ void *sched;
+
+ sched = _Workspace_Allocate( sizeof(Scheduler_priority_Per_thread) );
+
+ the_thread->scheduler_info = (Scheduler_priority_Per_thread*) sched;
+
+ return sched;
+}
+/*
+ * Scheduler Handler
+ *
+ * Copyright (C) 2010 Gedare Bloom.
+ * Copyright (C) 2011 On-Line Applications Research Corporation (OAR).
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.com/license/LICENSE.
+ *
+ * $Id: schedulerpriorityblock.c,v 1.4 2011/02/18 15:12:43 joel Exp $
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/score/context.h>
+#include <rtems/score/interr.h>
+#include <rtems/score/isr.h>
+#include <rtems/score/object.h>
+#include <rtems/score/priority.h>
+#include <rtems/score/scheduler.h>
+#include <rtems/score/schedulerpriority.h>
+#include <rtems/score/thread.h>
+
+void _Scheduler_priority_Block(
+ Thread_Control *the_thread
+)
+{
+ _Scheduler_priority_Ready_queue_extract( the_thread );
+
+ /* TODO: flash critical section? */
+
+ if ( _Thread_Is_heir( the_thread ) )
+ _Scheduler_priority_Schedule_body();
+
+ if ( _Thread_Is_executing( the_thread ) )
+ _Thread_Dispatch_necessary = true;
+
+}
+/*
+ * Scheduler Handler
+ *
+ * Copyright (C) 2010 Gedare Bloom.
+ * Copyright (C) 2011 On-Line Applications Research Corporation (OAR).
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.com/license/LICENSE.
+ *
+ * $Id: schedulerpriority.c,v 1.5 2011/02/28 00:10:38 joel Exp $
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/config.h>
+#include <rtems/score/prioritybitmap.h>
+#include <rtems/score/scheduler.h>
+#include <rtems/score/schedulerpriority.h>
+
+/* Instantiate any global variables needed by the priority scheduler */
+volatile Priority_bit_map_Control _Priority_Major_bit_map;
+
+Priority_bit_map_Control _Priority_Bit_map[16] CPU_STRUCTURE_ALIGNMENT;
+
+void _Scheduler_priority_Initialize(void)
+{
+ _Scheduler_priority_Ready_queue_initialize();
+ _Priority_bit_map_Handler_initialization();
+}
+/*
+ * COPYRIGHT (c) 2011.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.com/license/LICENSE.
+ *
+ * $Id: schedulerpriorityenqueue.c,v 1.1 2011/02/18 15:12:44 joel Exp $
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/config.h>
+#include <rtems/score/scheduler.h>
+#include <rtems/score/schedulerpriority.h>
+
+void _Scheduler_priority_Enqueue(
+ Thread_Control *the_thread
+)
+{
+ _Scheduler_priority_Ready_queue_enqueue( the_thread );
+}
+/*
+ * COPYRIGHT (c) 2011.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.com/license/LICENSE.
+ *
+ * $Id: schedulerpriorityenqueuefirst.c,v 1.1 2011/02/18 15:12:44 joel Exp $
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/config.h>
+#include <rtems/score/chain.h>
+#include <rtems/score/schedulerpriority.h>
+
+void _Scheduler_priority_Enqueue_first(
+ Thread_Control *the_thread
+)
+{
+ _Scheduler_priority_Ready_queue_enqueue_first( the_thread );
+}
+
+/* Scheduler Simple Handler / Extract
+ *
+ * COPYRIGHT (c) 2011.
+ * On-Line Applications Research Corporation (OAR).
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.com/license/LICENSE.
+ *
+ * $Id: schedulerpriorityextract.c,v 1.2 2011/02/28 00:10:38 joel Exp $
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/config.h>
+#include <rtems/score/chain.h>
+#include <rtems/score/schedulerpriority.h>
+
+void _Scheduler_priority_Extract(
+ Thread_Control *the_thread
+)
+{
+ _Scheduler_priority_Ready_queue_extract( the_thread );
+}
+/*
+ * Scheduler Handler
+ *
+ * Copyright (C) 2010 Gedare Bloom.
+ * Copyright (C) 2011 On-Line Applications Research Corporation (OAR).
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.com/license/LICENSE.
+ *
+ * $Id: schedulerpriorityfree.c,v 1.1 2011/02/18 15:12:44 joel Exp $
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/config.h>
+#include <rtems/score/scheduler.h>
+#include <rtems/score/schedulerpriority.h>
+#include <rtems/score/wkspace.h>
+
+void _Scheduler_priority_Free (
+ Thread_Control *the_thread
+)
+{
+ _Workspace_Free( the_thread->scheduler_info );
+}
+/*
+ * Scheduler Handler / Scheduler
+ *
+ * Copyright (C) 2010 Gedare Bloom.
+ * Copyright (C) 2011 On-Line Applications Research Corporation (OAR).
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.com/license/LICENSE.
+ *
+ * $Id: schedulerpriorityschedule.c,v 1.4 2011/02/18 15:12:44 joel Exp $
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/score/scheduler.h>
+#include <rtems/score/schedulerpriority.h>
+
+void _Scheduler_priority_Schedule(void)
+{
+ _Scheduler_priority_Schedule_body();
+}
+/*
+ * Scheduler Handler
+ *
+ * Copyright (C) 2010 Gedare Bloom.
+ * Copyright (C) 2011 On-Line Applications Research Corporation (OAR).
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.com/license/LICENSE.
+ *
+ * $Id: schedulerpriorityunblock.c,v 1.4 2011/02/18 15:12:44 joel Exp $
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/score/scheduler.h>
+#include <rtems/score/schedulerpriority.h>
+
+void _Scheduler_priority_Unblock (
+ Thread_Control *the_thread
+)
+{
+ _Scheduler_priority_Ready_queue_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;
+ }
+}
+/*
+ * Scheduler Handler
+ *
+ * Copyright (C) 2010 Gedare Bloom.
+ * Copyright (C) 2011 On-Line Applications Research Corporation (OAR).
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.com/license/LICENSE.
+ *
+ * $Id: schedulerpriorityupdate.c,v 1.2 2011/02/28 00:10:38 joel Exp $
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/config.h>
+#include <rtems/score/priority.h>
+#include <rtems/score/prioritybitmap.h>
+#include <rtems/score/scheduler.h>
+#include <rtems/score/schedulerpriority.h>
+#include <rtems/score/thread.h>
+
+void _Scheduler_priority_Update(
+ Thread_Control *the_thread
+)
+{
+ Scheduler_priority_Per_thread *sched_info;
+ Chain_Control *rq;
+
+ sched_info = (Scheduler_priority_Per_thread *) the_thread->scheduler_info;
+ rq = (Chain_Control *) _Scheduler.information;
+
+ sched_info->ready_chain = &rq[ the_thread->current_priority ];
+
+ _Priority_bit_map_Initialize_information(
+ &sched_info->Priority_map,
+ the_thread->current_priority
+ );
+}
+/*
+ * Scheduler Priority Handler / Yield
+ *
+ * Copyright (C) 2010 Gedare Bloom.
+ * Copyright (C) 2011 On-Line Applications Research Corporation (OAR).
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.com/license/LICENSE.
+ *
+ * $Id: schedulerpriorityyield.c,v 1.6 2011/02/18 15:12:44 joel Exp $
+ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/system.h>
+#include <rtems/score/isr.h>
+#include <rtems/score/scheduler.h>
+#include <rtems/score/schedulerpriority.h>
+#include <rtems/score/thread.h>
+
+/*
+ * INTERRUPT LATENCY:
+ * ready chain
+ * select heir
+ */
+
+void _Scheduler_priority_Yield(void)
+{
+ Scheduler_priority_Per_thread *sched_info;
+ ISR_Level level;
+ Thread_Control *executing;
+ Chain_Control *ready;
+
+ executing = _Thread_Executing;
+ sched_info = (Scheduler_priority_Per_thread *) executing->scheduler_info;
+ ready = sched_info->ready_chain;
+ _ISR_Disable( level );
+ if ( !_Chain_Has_only_one_node( ready ) ) {
+ _Chain_Extract_unprotected( &executing->Object.Node );
+ _Chain_Append_unprotected( ready, &executing->Object.Node );
+
+ _ISR_Flash( level );
+
+ if ( _Thread_Is_heir( executing ) )
+ _Thread_Heir = (Thread_Control *) _Chain_First( ready );
+ _Thread_Dispatch_necessary = true;
+ }
+ else if ( !_Thread_Is_heir( executing ) )
+ _Thread_Dispatch_necessary = true;
+
+ _ISR_Enable( level );
+}
--- /dev/null
+/**
+ * @file rtems/score/schedulerpriority.h
+ *
+ * This include file contains all the constants and structures associated
+ * with the manipulation of threads for the priority-based scheduler.
+ */
+
+/*
+ * Copryight (c) 2010 Gedare Bloom.
+ * Copyright (C) 2011 On-Line Applications Research Corporation (OAR).
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.com/license/LICENSE.
+ *
+ * $Id: schedulerpriority.h,v 1.8 2011/03/08 19:27:35 joel Exp $
+ */
+
+#ifndef _RTEMS_SCORE_SCHEDULERPRIORITY_H
+#define _RTEMS_SCORE_SCHEDULERPRIORITY_H
+
+#include <rtems/score/chain.h>
+#include <rtems/score/priority.h>
+#include <rtems/score/scheduler.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @addtogroup ScoreScheduler
+ *
+ */
+/**@{*/
+
+/**
+ * Entry points for the Deterministic Priority Based Scheduler.
+ */
+#define SCHEDULER_PRIORITY_ENTRY_POINTS \
+ { \
+ _Scheduler_priority_Initialize, /* initialize entry point */ \
+ _Scheduler_priority_Schedule, /* schedule entry point */ \
+ _Scheduler_priority_Yield, /* yield entry point */ \
+ _Scheduler_priority_Block, /* block entry point */ \
+ _Scheduler_priority_Unblock, /* unblock entry point */ \
+ _Scheduler_priority_Allocate, /* allocate entry point */ \
+ _Scheduler_priority_Free, /* free entry point */ \
+ _Scheduler_priority_Update, /* update entry point */ \
+ _Scheduler_priority_Enqueue, /* enqueue entry point */ \
+ _Scheduler_priority_Enqueue_first, /* enqueue_first entry point */ \
+ _Scheduler_priority_Extract /* extract entry point */ \
+ }
+
+/**
+ * Per-thread data related to the _Scheduler_PRIORITY scheduling policy.
+ */
+typedef struct {
+ /** This field points to the Ready FIFO for this thread's priority. */
+ Chain_Control *ready_chain;
+
+ /** This field contains precalculated priority map indices. */
+ Priority_bit_map_Information Priority_map;
+} Scheduler_priority_Per_thread;
+
+/**
+ * This routine initializes the priority scheduler.
+ */
+void _Scheduler_priority_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_priority_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_priority_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_priority_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_priority_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_priority_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_priority_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_priority_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_priority_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_priority_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_priority_Extract(
+ Thread_Control *the_thread
+);
+
+/**
+ * This is the major bit map.
+ */
+extern volatile Priority_bit_map_Control _Priority_Major_bit_map;
+
+/**
+ * This is the minor bit map.
+ */
+extern Priority_bit_map_Control _Priority_Bit_map[16] CPU_STRUCTURE_ALIGNMENT;
+
+#ifndef __RTEMS_APPLICATION__
+#include <rtems/score/schedulerpriority.inl>
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+/**@}*/
+
+#endif
+/* end of include file */
RTEMS_NO_ASR | \
RTEMS_INTERRUPT_LEVEL(0))
+
+
+/*
+ * Scheduler configuration.
+ *
+ * The scheduler configuration allows an application to select the
+ * scheduling policy to use. The supported configurations are:
+ * CONFIGURE_SCHEDULER_USER - user provided scheduler
+ * CONFIGURE_SCHEDULER_PRIORITY - Deterministic Priority Scheduler
+ *
+ * If no configuration is specified by the application, then
+ * CONFIGURE_SCHEDULER_PRIORITY is assumed to be the default.
+ *
+ * An application can define its own scheduling policy by defining
+ * CONFIGURE_SCHEDULER_USER and the following:
+ * - CONFIGURE_SCHEDULER_ENTRY_POINTS
+ * - CONFIGURE_MEMORY_FOR_SCHEDULER - base memory
+ * - CONFIGURE_MEMORY_PER_TASK_FOR_SCHEDULER - per task memory
+ */
+
+// to enable our own scheduler
+#define CONFIGURE_SCHEDULER_USER
+
+/**
+ * Entry points for a edf Scheduler.
+ */
+#define CONFIGURE_SCHEDULER_USER_ENTRY_POINTS
+// EDF
+#include "scheduler_edf.h"
+#define SCHEDULER_ENTRY_POINTS SCHEDULER_EDF_ENTRY_POINTS
+// Priority
+#include "scheduler_priority.h"
+#define SCHEDULER_ENTRY_POINTS SCHEDULER_PRIORITY_ENTRY_POINTS
+
+#define CONFIGURE_MEMORY_FOR_SCHEDULER (1024)
+#define CONFIGURE_MEMORY_PER_TASK_FOR_SCHEDULER (256)
+
+
+
+
#include <rtems/confdefs.h>
+
+
+
/* end of include file */
--- /dev/null
+#include <system_def.h>
+#include "system.h"
+#include "app_def.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <rtems/untar.h>
+#include <rtems/error.h>
+#include <rtems/mw_uid.h>
+#include <errno.h>
+
+
+rtems_task Task_2(
+ rtems_task_argument argument
+)
+{
+ int i;
+ int s;
+ rtems_status_code status;
+ printf("*** Starting up Task_2 ***\n");
+
+ while(1){
+ printf("Task_2 woken and calculating\n");
+ for (i=0; i<10000; i++) {
+ s = i + i;
+ }
+ status = rtems_task_wake_after( TICKS_PER_SECOND*2 );
+ check_rtems_status( status, 0, "rtems_task_wake_after" );
+ }
+}
+