/* -*- C++ -*- */
/**
* @file DSRT_Sched_Queue_T.h
*
* $Id$
*
* @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 */