/* -*- C++ -*- */ /** * @file DSRT_Sched_Queue_T.h * * @author Venkita Subramonian (venkita@cs.wustl.edu) */ #ifndef DSRT_SCHED_QUEUE_T_H #define DSRT_SCHED_QUEUE_T_H #include /**/ "ace/pre.h" #include "DSRT_Dispatch_Item_T.h" #include "ace/RB_Tree.h" #include "ace/Hash_Map_Manager_T.h" #include "ace/Null_Mutex.h" #if !defined (ACE_LACKS_PRAGMA_ONCE) # pragma once #endif /* ACE_LACKS_PRAGMA_ONCE */ #include "Kokyu_dsrt.h" namespace Kokyu { /** * @class Sched_Ready_Queue * * @brief RB_Tree based template class for implementation of * reordering queue. * * This queue is used as a priority queue to store schedulable * entities. The item at the top of the RB_Tree is the most eligible * item. The comparator used to determine the most eligible item is * passed as a template parameter More_Eligible_Comparator * . This is expected to be a functor which compares two * schedulable items. The mutex type template parameter for RB_Tree * is chosen to be a null mutex since all the methods in the * enclosing Sched_Ready_Queue class are thread * safe. Since QoS is used for comparison between two schedulable * items, QoSDescriptor is the ideal candidate to be used as the key * or the EXT_ID for RB_Tree instantiation. But two qos descriptors * could be the same. The existing implementation of RB_Tree does * not allow duplicate keys. In order to facilitate insertion of * duplicate qos descriptors, the qos descriptors are contained in a * DSRT_Dispatch_Item and this is used as the basis * of comparison. To resolve tie between equal qos values, an * insertion time stamp is maintained in each item and an item with * an earlier time stamp is more eligible than an item with an * identical qos value. Another requirement is that it should be * possible to remove an item from the RB_Tree based on guid. Since * we have already used up the qos descriptor for the key, we need a * separate index into the list of schedulable items. The second * index should be based on guid. This is achieved by using a hash * map to store pairs. This makes the deletion * of nodes from RB_Tree more efficient. * */ template class Sched_Ready_Queue { /// Extract the necessary types from the traits class typedef typename DSRT_Scheduler_Traits::Guid_t Guid_t; typedef typename DSRT_Scheduler_Traits::QoSDescriptor_t DSRT_QoSDescriptor_t; public: /** * Given a guid, find an item in the priority queue. * * @param guid Guid of item * * @param found_item Reference to DSRT_Dispatch_Item_var * to hold the found item. * @return -1 if no item found and 0 otherwise. */ int find(Guid_t guid, DSRT_Dispatch_Item_var& found_item); /** * Insert an item in the priority queue. If item with same guid is * already in the queue, the existing one is deleted and the new * one inserted. A deletion and insertion has to happen instead of * update since the rebalancing of the RB_Tree should take place. * * @param item DSRT_Dispatch_Item object containing guid and qos. * * @return -1 if insertion failed and 0 otherwise. */ int insert(DSRT_Dispatch_Item* item); /** * Remove an item from the priority queue. * * @param guid Guid of item. * * @param qos QoS associated with item. * * @return -1 if removal failed and 0 otherwise. */ int remove(Guid_t guid); /** * Returns current size of the priority queue. */ int current_size (); /** * Get the most eligible item from the priority queue. * * @param item Item which is most eligible, i.e. one at the * "top" of the priority queue. * * @return -1 if there are no items in the priority queue. */ int most_eligible (DSRT_Dispatch_Item_var& item); /** * change blocked_prio_ item to inactive_prio_ */ int change_prio (int old_prio, int new_prio, int policy); void dump(); private: /** * @class Guid_Hash * * @brief Internal class to generate hash for guid. * * This acts just as a wrapper functor to the Hash functor passed * as part of the traits class DSRT_Scheduler_Traits * . * */ class Guid_Hash { public: /// Returns hash value. u_long operator () (const typename DSRT_Scheduler_Traits::Guid_t &id) { typename DSRT_Scheduler_Traits::Guid_Hash guid_hash; return guid_hash(id); } }; // RB_Tree related typedefs typedef ACE_RB_Tree , DSRT_Dispatch_Item_var, More_Eligible_Comparator, ACE_SYNCH_NULL_MUTEX> Dispatch_Items_Priority_Queue; typedef ACE_RB_Tree_Node, DSRT_Dispatch_Item_var > RB_Tree_Dispatch_Item_Node; typedef typename Dispatch_Items_Priority_Queue::ITERATOR PRIO_QUEUE_ITERATOR; typedef typename Dispatch_Items_Priority_Queue::ENTRY PRIO_QUEUE_ENTRY; // Hash map related typedefs typedef ACE_Hash_Map_Manager_Ex, ACE_SYNCH_NULL_MUTEX> Dispatch_Items_Hash_Map; typedef ACE_Hash_Map_Iterator_Ex, ACE_SYNCH_NULL_MUTEX> Dispatch_Items_Hash_Map_Iterator; typedef ACE_Hash_Map_Entry Dispatch_Items_Hash_Map_Entry; /** * Lock used to protect the state of the scheduler queue. A * separate lock is not used for the internal RB_Tree and hashmap. */ ACE_LOCK lock_; /** * Hash table to maintain a second index into the list of * schedulable items. This is for efficient removal of items from * the RB_Tree based on guid. The guid is used as the key for the * hash map, whereas the qos value is used as the key for the * RB_Tree. */ Dispatch_Items_Hash_Map dispatch_items_hash_map_; /** * RB_Tree implementation of priority queue of schedulable items. */ Dispatch_Items_Priority_Queue dispatch_items_prio_queue_; }; } #if !defined (__ACE_INLINE__) //#include "DSRT_Sched_Queue_T.i" #endif /* __ACE_INLINE__ */ #if defined (ACE_TEMPLATES_REQUIRE_SOURCE) #include "DSRT_Sched_Queue_T.cpp" #endif /* ACE_TEMPLATES_REQUIRE_SOURCE */ #if defined (ACE_TEMPLATES_REQUIRE_PRAGMA) #pragma implementation ("DSRT_Sched_Queue_T.cpp") #endif /* ACE_TEMPLATES_REQUIRE_PRAGMA */ #include /**/ "ace/post.h" #endif /* DSRT_SCHED_QUEUE_T_H */