diff options
author | venkita <venkita@ae88bc3d-4319-0410-8dbf-d08b4c9d3795> | 2003-10-11 04:01:58 +0000 |
---|---|---|
committer | venkita <venkita@ae88bc3d-4319-0410-8dbf-d08b4c9d3795> | 2003-10-11 04:01:58 +0000 |
commit | 0097c6e53e2720ef3a7b3cc36bd1311bd83ae961 (patch) | |
tree | 3d559cb14f56df14c2bbe34f9f22aa2d2eb86e81 /Kokyu | |
parent | c623dfc293b22ac883bd06b306a7c418420928d8 (diff) | |
download | ATCD-0097c6e53e2720ef3a7b3cc36bd1311bd83ae961.tar.gz |
ChangeLogTag: Fri Oct 10 22:56:35 2003 Venkita Subramonian <venkita@cs.wustl.edu>
Diffstat (limited to 'Kokyu')
-rw-r--r-- | Kokyu/Default_Dispatcher_Impl.cpp | 32 | ||||
-rw-r--r-- | Kokyu/Dispatcher_Impl.h | 2 | ||||
-rw-r--r-- | Kokyu/Dispatcher_Task.cpp | 34 | ||||
-rw-r--r-- | Kokyu/Dispatcher_Task.h | 6 | ||||
-rw-r--r-- | Kokyu/Dispatcher_Task.i | 33 | ||||
-rw-r--r-- | Kokyu/Kokyu_defs.cpp | 5 | ||||
-rw-r--r-- | Kokyu/Kokyu_defs.h | 42 | ||||
-rw-r--r-- | Kokyu/Kokyu_defs.i | 78 | ||||
-rw-r--r-- | Kokyu/tests/EDF/test.cpp | 58 | ||||
-rw-r--r-- | Kokyu/tests/FIFO/test.cpp | 69 |
10 files changed, 302 insertions, 57 deletions
diff --git a/Kokyu/Default_Dispatcher_Impl.cpp b/Kokyu/Default_Dispatcher_Impl.cpp index 111a8581eaa..04b42f9a2d1 100644 --- a/Kokyu/Default_Dispatcher_Impl.cpp +++ b/Kokyu/Default_Dispatcher_Impl.cpp @@ -49,15 +49,20 @@ Default_Dispatcher_Impl::init_i (const Dispatcher_Attributes& attrs) { //ACE_DEBUG ((LM_DEBUG, "iter = %d\n", i)); Dispatcher_Task* task=0; - ACE_NEW_RETURN (task, Dispatcher_Task (*config, ACE_Thread_Manager::instance ()), -1); + ACE_NEW_RETURN (task, + Dispatcher_Task (*config, + ACE_Thread_Manager::instance()), + -1); auto_ptr<Dispatcher_Task> tmp_task_auto_ptr (task); tasks_[i++] = tmp_task_auto_ptr; - //I couldn't use reset because MSVC++ auto_ptr does not have reset method. + //I couldn't use reset because MSVC6 auto_ptr does not have reset method. //So in configurations where the auto_ptr maps to the std::auto_ptr instead //of ACE auto_ptr, this would be a problem. //tasks_[i++].reset (task); } + thr_creation_flags_ = attrs.thread_creation_flags (); + if (attrs.immediate_activation_ && !this->activated_) { this->activate_i (); @@ -77,19 +82,16 @@ Default_Dispatcher_Impl::activate_i () for(i=0; i<ntasks_; ++i) { - long flags = THR_NEW_LWP | THR_BOUND | THR_SCHED_FIFO | THR_JOINABLE; - Priority_t priority = tasks_[i]->get_curr_config_info ().thread_priority_; - if (this->tasks_[i]->activate (flags, 1, 1, priority) == -1) + if (this->tasks_[i]->activate (this->thr_creation_flags_, + 1, 1, priority) == -1) { - flags = THR_BOUND | THR_JOINABLE; - priority = ACE_Sched_Params::priority_min (ACE_SCHED_OTHER, - ACE_SCOPE_THREAD); - if (this->tasks_[i]->activate (flags, 1, 1, priority) == -1) - ACE_ERROR ((LM_ERROR, - "EC (%P|%t) cannot activate queue %d", i)); + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("EC (%P|%t) cannot activate queue.") + ACE_TEXT ("Need superuser privilege to run in RT class\n")), + -1); } } @@ -125,12 +127,10 @@ Default_Dispatcher_Impl::dispatch_i (const Dispatch_Command* cmd, Dispatcher_Task* task = find_task_with_preemption_prio (qos_info.preemption_priority_); - if (task != 0) - task->enqueue (cmd, qos_info); - else - tasks_[0]->enqueue (cmd, qos_info); + if (task == 0) + task = tasks_[0].get (); - return 0; + return task->enqueue (cmd, qos_info); } int diff --git a/Kokyu/Dispatcher_Impl.h b/Kokyu/Dispatcher_Impl.h index d0d0cae42fc..8facb5eb5dd 100644 --- a/Kokyu/Dispatcher_Impl.h +++ b/Kokyu/Dispatcher_Impl.h @@ -61,6 +61,8 @@ namespace Kokyu virtual int shutdown_i () =0; virtual int activate_i () =0; + protected: + int thr_creation_flags_; }; } //end of namespace diff --git a/Kokyu/Dispatcher_Task.cpp b/Kokyu/Dispatcher_Task.cpp index 28ac43452ca..3b4b509c7a3 100644 --- a/Kokyu/Dispatcher_Task.cpp +++ b/Kokyu/Dispatcher_Task.cpp @@ -2,15 +2,26 @@ #include "Dispatcher_Task.h" +#include "ace/Malloc_T.h" +#include "ace/Synch_T.h" + #if ! defined (__ACE_INLINE__) #include "Dispatcher_Task.i" #endif /* __ACE_INLINE__ */ ACE_RCSID(Kokyu, Dispatcher_Task, "$Id$") +namespace +{ + const int ALLOC_POOL_CHUNKS = 200; +} + namespace Kokyu { +typedef ACE_Cached_Allocator<Dispatch_Queue_Item, ACE_SYNCH_NULL_MUTEX> +Dispatch_Queue_Item_Allocator; + int Dispatcher_Task::initialize () { @@ -46,6 +57,15 @@ Dispatcher_Task::initialize () { this->msg_queue(this->the_queue_); } + + if (this->allocator_ == 0) + { + ACE_NEW_RETURN (this->allocator_, + Dispatch_Queue_Item_Allocator(ALLOC_POOL_CHUNKS), + -1); + own_allocator_ = 1; + } + return 0; } @@ -116,9 +136,6 @@ int Dispatcher_Task::enqueue (const Dispatch_Command* cmd, const QoSDescriptor& qos_info) { - if (this->allocator_ == 0) - this->allocator_ = ACE_Allocator::instance (); - void* buf = this->allocator_->malloc (sizeof (Dispatch_Queue_Item)); if (buf == 0) @@ -173,7 +190,18 @@ void Dispatch_Queue_Item::init_i (const QoSDescriptor& qos_info) template class ACE_Locked_Data_Block<ACE_Lock_Adapter<ACE_SYNCH_MUTEX> >; template class ACE_Lock_Adapter<ACE_Thread_Mutex>; +template class ACE_Cached_Allocator<Kokyu::Dispatch_Queue_Item, ACE_SYNCH_NULL_MUTEX>; +template class ACE_Free_List<ACE_Cached_Mem_Pool_Node<Kokyu::Dispatch_Queue_Item> >; +template class ACE_Locked_Free_List<ACE_Cached_Mem_Pool_Node<Kokyu::Dispatch_Queue_Item>, + ACE_SYNCH_NULL_MUTEX>; +template class ACE_Cached_Mem_Pool_Node<Kokyu::Dispatch_Queue_Item>; + #elif defined(ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA) #pragma instantiate ACE_Locked_Data_Block<ACE_Lock_Adapter<ACE_SYNCH_MUTEX> > #pragma instantiate ACE_Lock_Adapter<ACE_Thread_Mutex> +#pragma instantiate ACE_Free_List<ACE_Cached_Mem_Pool_Node<Kokyu::Dispatch_Queue_Item> > +#pragma instantiate ACE_Cached_Allocator<Kokyu::Dispatch_Queue_Item, ACE_SYNCH_NULL_MUTEX> +#pragma instantiate ACE_Locked_Free_List<ACE_Cached_Mem_Pool_Node<Kokyu::Dispatch_Queue_Item, ACE_SYNCH_NULL_MUTEX> +#pragma instantiate ACE_Cached_Mem_Pool_Node<Kokyu::Dispatch_Queue_Item> + #endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */ diff --git a/Kokyu/Dispatcher_Task.h b/Kokyu/Dispatcher_Task.h index 8584af36e87..0c57b38c952 100644 --- a/Kokyu/Dispatcher_Task.h +++ b/Kokyu/Dispatcher_Task.h @@ -66,6 +66,8 @@ public: Dispatcher_Task (const ConfigInfo& config_info, ACE_Thread_Manager* thr_manager = 0); + + ~Dispatcher_Task (); int initialize(); int enqueue (const Dispatch_Command* cmd, @@ -81,8 +83,11 @@ private: static int get_native_prio(); private: + ConfigInfo curr_config_info_; + /// An per-task allocator ACE_Allocator *allocator_; + int own_allocator_; /// Helper data structure to minimize memory allocations... ACE_Locked_Data_Block<ACE_Lock_Adapter<ACE_SYNCH_MUTEX> > data_block_; @@ -90,7 +95,6 @@ private: /// The queue ACE_Message_Queue<ACE_SYNCH>* the_queue_; - ConfigInfo curr_config_info_; ACE_Deadline_Message_Strategy deadline_msg_strategy_; ACE_Laxity_Message_Strategy laxity_msg_strategy_; }; diff --git a/Kokyu/Dispatcher_Task.i b/Kokyu/Dispatcher_Task.i index 63246307178..80987e3fd9a 100644 --- a/Kokyu/Dispatcher_Task.i +++ b/Kokyu/Dispatcher_Task.i @@ -6,24 +6,35 @@ ACE_INLINE Dispatcher_Task::Dispatcher_Task (const ConfigInfo& config_info, ACE_Thread_Manager* thr_manager) : ACE_Task<ACE_SYNCH> (thr_manager), - allocator_ (ACE_Allocator::instance ()), curr_config_info_ (config_info), - deadline_msg_strategy_ (0, 0, 0x7FFFFFFFUL, 0x08000000UL ), - //bits for static priority = 0 - //max dynamic prio = 2^31 - 1 - //pending offset = 15/16th of the dynamic prio range - //which means that the LATE population will be in the - //1/16th part of the range. - laxity_msg_strategy_ (0, 0, 0x7FFFFFFFUL, 0x08000000UL ) + allocator_ (config_info.allocator_), + own_allocator_ (0), + deadline_msg_strategy_ (config_info.reordering_flags_.static_bit_field_mask_, + config_info.reordering_flags_.static_bit_field_shift_, + config_info.reordering_flags_.dynamic_priority_max_, + config_info.reordering_flags_.dynamic_priority_offset_), + laxity_msg_strategy_ (config_info.reordering_flags_.static_bit_field_mask_, + config_info.reordering_flags_.static_bit_field_shift_, + config_info.reordering_flags_.dynamic_priority_max_, + config_info.reordering_flags_.dynamic_priority_offset_) { this->initialize(); } ACE_INLINE +Dispatcher_Task::~Dispatcher_Task () +{ + if (own_allocator_) + { + delete allocator_; + } +} + +ACE_INLINE Priority_t Dispatcher_Task::preemption_priority() const { - return curr_config_info_.preemption_priority_; + return curr_config_info_.preemption_priority_; } @@ -51,8 +62,8 @@ Dispatch_Queue_Item::Dispatch_Queue_Item ( int flags, ACE_Allocator* mb_allocator) : ACE_Message_Block (data_block, - flags, - mb_allocator), + flags, + mb_allocator), command_ (cmd), qos_info_ (qos_info) { diff --git a/Kokyu/Kokyu_defs.cpp b/Kokyu/Kokyu_defs.cpp index 8084195d8b8..cf5445b7946 100644 --- a/Kokyu/Kokyu_defs.cpp +++ b/Kokyu/Kokyu_defs.cpp @@ -14,11 +14,6 @@ namespace Kokyu { } - Dispatcher_Attributes::Dispatcher_Attributes () - :immediate_activation_ (0) - { - } - DSRT_ConfigInfo::DSRT_ConfigInfo () :sched_policy_ (ACE_SCHED_RR), sched_scope_ (ACE_SCOPE_THREAD) diff --git a/Kokyu/Kokyu_defs.h b/Kokyu/Kokyu_defs.h index b5cd071dcea..37f717e6073 100644 --- a/Kokyu/Kokyu_defs.h +++ b/Kokyu/Kokyu_defs.h @@ -16,6 +16,7 @@ #include "ace/Auto_Ptr.h" #include "ace/Message_Block.h" #include "ace/Sched_Params.h" +#include "ace/Malloc_Allocator.h" #if !defined (ACE_LACKS_PRAGMA_ONCE) # pragma once @@ -23,6 +24,8 @@ #include "kokyu_export.h" +class ACE_Allocator; + namespace Kokyu { typedef long Priority_t; @@ -63,6 +66,15 @@ namespace Kokyu VERY_HIGH_IMPORTANCE }; + struct Reordering_Queue_Attributes + { + Reordering_Queue_Attributes (); + unsigned long static_bit_field_mask_; + unsigned long static_bit_field_shift_; + unsigned long dynamic_priority_max_; + unsigned long dynamic_priority_offset_; + }; + struct ConfigInfo { Priority_t preemption_priority_; @@ -73,15 +85,30 @@ namespace Kokyu // type of dispatching queue Dispatching_Type_t dispatching_type_; + //allocator to be used for dynamic memory allocation. If each + //thread gets its own memory pool, contention will be less + ACE_Allocator *allocator_; + + Reordering_Queue_Attributes reordering_flags_; }; typedef ACE_Array<ConfigInfo> ConfigInfoSet; - struct Kokyu_Export Dispatcher_Attributes + class Kokyu_Export Dispatcher_Attributes { - Dispatcher_Attributes(); + public: ConfigInfoSet config_info_set_; int immediate_activation_; + void sched_policy (int); + void sched_scope (int); + + public: + Dispatcher_Attributes (); + int thread_creation_flags () const; + + private: + int base_thread_creation_flags_; + int thread_creation_flags_; }; @@ -95,17 +122,6 @@ namespace Kokyu enum Block_Flag_t {BLOCK, UNBLOCK}; - /* - struct DSRT_QoSDescriptor - { - long importance_; - long criticality_; - Priority_t priority_; - Deadline_t deadline_; - Execution_Time_t exec_time_; - }; - */ - class Kokyu_Export Dispatch_Command { public: diff --git a/Kokyu/Kokyu_defs.i b/Kokyu/Kokyu_defs.i index e87720db45c..a6b35304909 100644 --- a/Kokyu/Kokyu_defs.i +++ b/Kokyu/Kokyu_defs.i @@ -5,6 +5,84 @@ namespace Kokyu { ACE_INLINE +Dispatcher_Attributes::Dispatcher_Attributes() + :immediate_activation_ (0), + base_thread_creation_flags_ (THR_NEW_LWP | THR_BOUND | THR_JOINABLE), + thread_creation_flags_ (base_thread_creation_flags_) +{ + sched_policy (ACE_SCHED_FIFO); + sched_scope (ACE_SCOPE_PROCESS); +} + +ACE_INLINE +void Dispatcher_Attributes::sched_policy(int policy) +{ + switch (policy) + { + case ACE_SCHED_FIFO: + thread_creation_flags_ = + base_thread_creation_flags_ | THR_SCHED_FIFO; + break; + + case ACE_SCHED_OTHER: + thread_creation_flags_ = + base_thread_creation_flags_ | THR_SCHED_DEFAULT; + break; + + case ACE_SCHED_RR: + thread_creation_flags_ = + base_thread_creation_flags_ | THR_SCHED_RR; + break; + } +} + +ACE_INLINE +void Dispatcher_Attributes::sched_scope(int scope) +{ + switch (scope) + { + case ACE_SCOPE_PROCESS: + case ACE_SCOPE_LWP: + thread_creation_flags_ = + base_thread_creation_flags_ | THR_SCOPE_PROCESS; + break; + + case ACE_SCOPE_THREAD: + default: + thread_creation_flags_ = + base_thread_creation_flags_ | THR_SCOPE_SYSTEM; + break; + } +} + +ACE_INLINE +int Dispatcher_Attributes::thread_creation_flags () const +{ + return thread_creation_flags_; +} + +ACE_INLINE +Reordering_Queue_Attributes::Reordering_Queue_Attributes () + :static_bit_field_mask_ (0), // 2^(10) - 1 + static_bit_field_shift_ (0), // 10 low order bits + dynamic_priority_max_ (0x7FFFFFFFUL), // 2^31-1 + dynamic_priority_offset_ (0x08000000UL) // 15/16th of dynamic prio range +{ + //bits for static priority = 0 + //max dynamic prio = 2^31 - 1 + //pending offset = 15/16th of the dynamic prio range + //which means that the LATE population will be in the + //1/16th part of the range. + + //For the Laxity and Deadline strategies these are the + //defaults defined in Message_Block.h + //static_bit_field_mask (0x3FFUL), // 2^(10) - 1 + //static_bit_field_shift (10), // 10 low order bits + //dynamic_priority_max (0x3FFFFFUL), // 2^(22)-1 + //dynamic_priority_offset (0x200000UL) // 2^(22-1) +} + +ACE_INLINE Dispatch_Command::Dispatch_Command (int dont_delete, ACE_Allocator *allocator) :dont_delete_ (dont_delete), diff --git a/Kokyu/tests/EDF/test.cpp b/Kokyu/tests/EDF/test.cpp index b03c46a3713..8b8882f88e3 100644 --- a/Kokyu/tests/EDF/test.cpp +++ b/Kokyu/tests/EDF/test.cpp @@ -5,6 +5,12 @@ #include "Kokyu.h" #include "ace/Task.h" #include "ace/Sched_Params.h" +#include "ace/SString.h" +#include "ace/Get_Opt.h" + +ACE_CString sched_policy_str = "fifo"; + +int parse_args (int argc, char *argv[]); class MyCommand : public Kokyu::Dispatch_Command { @@ -46,12 +52,34 @@ private: }; -int main (int,char**) +int main (int argc, char** argv) { Kokyu::ConfigInfoSet config_info(3); + int sched_policy=ACE_SCHED_FIFO; + + Kokyu::Dispatcher_Attributes attrs; + + if (parse_args (argc, argv) == -1) + return 0; + + if (ACE_OS::strcasecmp(sched_policy_str.c_str(), "fifo") == 0) + { + sched_policy = ACE_SCHED_FIFO; + } + else if (ACE_OS::strcasecmp(sched_policy_str.c_str(), "other") == 0) + { + sched_policy = ACE_SCHED_OTHER; + } + else if (ACE_OS::strcasecmp(sched_policy_str.c_str(), "rr") == 0) + { + sched_policy = ACE_SCHED_RR; + } + + attrs.sched_policy (sched_policy); + Kokyu::Priority_t min_prio = - ACE_Sched_Params::priority_min (ACE_SCHED_FIFO); + ACE_Sched_Params::priority_min (sched_policy); config_info[0].preemption_priority_ = 1; config_info[0].thread_priority_ = min_prio; @@ -59,7 +87,6 @@ int main (int,char**) ACE_DEBUG ((LM_DEBUG, "before create_dispatcher\n" )); - Kokyu::Dispatcher_Attributes attrs; attrs.config_info_set_ = config_info; auto_ptr<Kokyu::Dispatcher> disp (Kokyu::Dispatcher_Factory::create_dispatcher (attrs)); @@ -101,3 +128,28 @@ int main (int,char**) return 0; } + +int parse_args (int argc, char *argv[]) +{ + ACE_Get_Opt get_opts (argc, argv, "p:"); + int c; + + while ((c = get_opts ()) != -1) + switch (c) + { + case 'p': + sched_policy_str = ACE_TEXT_ALWAYS_CHAR(get_opts.opt_arg ()); + break; + + case '?': + default: + ACE_ERROR_RETURN ((LM_ERROR, + "usage: %s %s" + "\n", + argv [0], + "-p <fifo|rr|other>"), + -1); + } + // Indicates sucessful parsing of the command line + return 0; +} diff --git a/Kokyu/tests/FIFO/test.cpp b/Kokyu/tests/FIFO/test.cpp index 52423dcf688..2800600902f 100644 --- a/Kokyu/tests/FIFO/test.cpp +++ b/Kokyu/tests/FIFO/test.cpp @@ -4,6 +4,12 @@ #include "Kokyu.h" #include "ace/Task.h" +#include "ace/SString.h" +#include "ace/Get_Opt.h" + +ACE_CString sched_policy_str = "fifo"; + +int parse_args (int argc, char *argv[]); class MyCommand : public Kokyu::Dispatch_Command { @@ -45,24 +51,52 @@ private: }; -int main (int,char**) +int main (int argc, char** argv) { Kokyu::ConfigInfoSet config_info(3); + int hi_prio, me_prio, lo_prio; + int sched_policy=ACE_SCHED_FIFO; + + Kokyu::Dispatcher_Attributes attrs; + + if (parse_args (argc, argv) == -1) + return 0; + + if (ACE_OS::strcasecmp(sched_policy_str.c_str(), "fifo") == 0) + { + sched_policy = ACE_SCHED_FIFO; + } + else if (ACE_OS::strcasecmp(sched_policy_str.c_str(), "other") == 0) + { + sched_policy = ACE_SCHED_OTHER; + } + else if (ACE_OS::strcasecmp(sched_policy_str.c_str(), "rr") == 0) + { + sched_policy = ACE_SCHED_RR; + } + + attrs.sched_policy (sched_policy); + hi_prio = ACE_Sched_Params::priority_max (sched_policy); + me_prio = ACE_Sched_Params::previous_priority (sched_policy, + hi_prio); + lo_prio = ACE_Sched_Params::previous_priority (sched_policy, + me_prio); + config_info[0].preemption_priority_ = 1; - config_info[0].thread_priority_ = 15; + config_info[0].thread_priority_ = hi_prio ; config_info[0].dispatching_type_ = Kokyu::FIFO_DISPATCHING; config_info[1].preemption_priority_ = 2; - config_info[1].thread_priority_ = 2; + config_info[1].thread_priority_ = me_prio; config_info[1].dispatching_type_ = Kokyu::FIFO_DISPATCHING; config_info[2].preemption_priority_ = 3; - config_info[2].thread_priority_ = 0; + config_info[2].thread_priority_ = lo_prio; config_info[2].dispatching_type_ = Kokyu::FIFO_DISPATCHING; - Kokyu::Dispatcher_Attributes attrs; attrs.config_info_set_ = config_info; + ACE_DEBUG ((LM_DEBUG, "before create_dispatcher\n" )); auto_ptr<Kokyu::Dispatcher> disp (Kokyu::Dispatcher_Factory::create_dispatcher (attrs)); @@ -88,3 +122,28 @@ int main (int,char**) ACE_DEBUG ((LM_DEBUG, "after shutdown\n")); return 0; } + +int parse_args (int argc, char *argv[]) +{ + ACE_Get_Opt get_opts (argc, argv, "p:"); + int c; + + while ((c = get_opts ()) != -1) + switch (c) + { + case 'p': + sched_policy_str = ACE_TEXT_ALWAYS_CHAR(get_opts.opt_arg ()); + break; + + case '?': + default: + ACE_ERROR_RETURN ((LM_ERROR, + "usage: %s %s" + "\n", + argv [0], + "-p <fifo|rr|other>"), + -1); + } + // Indicates sucessful parsing of the command line + return 0; +} |