diff options
author | Phil Mesnier <mesnier_p@ociweb.com> | 2013-02-19 02:08:55 +0000 |
---|---|---|
committer | Phil Mesnier <mesnier_p@ociweb.com> | 2013-02-19 02:08:55 +0000 |
commit | cd36447f44d172d820a2cc464572a56f560b9f83 (patch) | |
tree | f1550e396bf73f63eedab006cdd3c5b6078254bc | |
parent | 76debafe81ddd5a8e701d15986289bdd5fd5c935 (diff) | |
download | ATCD-cd36447f44d172d820a2cc464572a56f560b9f83.tar.gz |
Tue Feb 19 01:48:59 UTC 2013 Phil Mesnier <mesnier_p@ociweb.com>
-rw-r--r-- | TAO/ChangeLog | 30 | ||||
-rw-r--r-- | TAO/tao/Dynamic_TP/DTP_ORBInitializer.cpp | 4 | ||||
-rw-r--r-- | TAO/tao/Dynamic_TP/DTP_Thread_Pool.cpp | 18 | ||||
-rw-r--r-- | TAO/tao/Dynamic_TP/DTP_Thread_Pool.h | 2 | ||||
-rw-r--r-- | TAO/tao/Leader_Follower.cpp | 82 | ||||
-rw-r--r-- | TAO/tao/Leader_Follower.h | 14 | ||||
-rw-r--r-- | TAO/tao/Leader_Follower.inl | 12 | ||||
-rw-r--r-- | TAO/tao/New_Leader_Generator.h | 2 | ||||
-rw-r--r-- | TAO/tao/RTCORBA/Thread_Pool.cpp | 4 | ||||
-rw-r--r-- | TAO/tao/RTCORBA/Thread_Pool.h | 2 | ||||
-rw-r--r-- | TAO/tests/Dynamic_TP/ORB_ThreadPool/middle.conf | 5 |
11 files changed, 127 insertions, 48 deletions
diff --git a/TAO/ChangeLog b/TAO/ChangeLog index ec996ae76b5..54e2d06a4da 100644 --- a/TAO/ChangeLog +++ b/TAO/ChangeLog @@ -1,3 +1,33 @@ +Tue Feb 19 01:48:59 UTC 2013 Phil Mesnier <mesnier_p@ociweb.com> + + * tao/Leader_Follower.h: + * tao/Leader_Follower.inl: + * tao/Leader_Follower.cpp: + * tao/New_Leader_Generator.h: + + Added an explicit call to start a new thread when a dynamic thread pool is + attached and a client thread would otherwise become a client leader. This + adds a conditional on the critical path, but only when a client would become + a leader anyway, which is a suboptimal performance path. The formerly void + no_leader_available call now returns a bool, which is necessary to decide + whether to continue waiting or press on as a client leader. + + * tao/Dynamic_TP/DTP_ORBInitializer.cpp: + + When the ORB has a dynamic thread pool attached, this sets the new client + leader avoidance flag. + + * tao/Dynamic_TP/DTP_Thread_Pool.h: + * tao/Dynamic_TP/DTP_Thread_Pool.cpp: + * tao/RTCORBA/Thread_Pool.h: + * tao/RTCORBA/Thread_Pool.cpp: + + Propagate the return value change. + + * tests/Dynamic_TP/ORB_ThreadPool/middle.conf: + + Update to use the noupcall wait strategy. + Mon Feb 18 22:49:18 UTC 2013 Kevin Stanley <stanleyk@ociweb.com> * orbsvcs/orbsvcs/Naming/FaultTolerant/FT_Naming_Manager.cpp: diff --git a/TAO/tao/Dynamic_TP/DTP_ORBInitializer.cpp b/TAO/tao/Dynamic_TP/DTP_ORBInitializer.cpp index f71f499527f..5ce868d61b1 100644 --- a/TAO/tao/Dynamic_TP/DTP_ORBInitializer.cpp +++ b/TAO/tao/Dynamic_TP/DTP_ORBInitializer.cpp @@ -11,6 +11,7 @@ #include "tao/ORB_Core.h" #include "tao/PI/ORBInitInfo.h" #include "tao/debug.h" +#include "tao/Leader_Follower.h" #include "ace/Service_Repository.h" #include "ace/Svc_Conf.h" @@ -121,6 +122,9 @@ TAO_DTP_ORBInitializer::post_init (PortableInterceptor::ORBInitInfo_ptr info) dynamic_cast<TAO_DTP_Thread_Lane_Resources_Manager &>(tlrm); dtp_tlrm.tp_manager().create_threadpool (def); + + tao_info->orb_core ()->leader_follower ().set_avoid_client_leader (); + } diff --git a/TAO/tao/Dynamic_TP/DTP_Thread_Pool.cpp b/TAO/tao/Dynamic_TP/DTP_Thread_Pool.cpp index b29b757793e..1aa8134e253 100644 --- a/TAO/tao/Dynamic_TP/DTP_Thread_Pool.cpp +++ b/TAO/tao/Dynamic_TP/DTP_Thread_Pool.cpp @@ -27,10 +27,10 @@ TAO_DTP_New_Leader_Generator::TAO_DTP_New_Leader_Generator ( { } -void +bool TAO_DTP_New_Leader_Generator::no_leaders_available (void) { - this->pool_.new_dynamic_thread (); + return this->pool_.new_dynamic_thread (); } TAO_DTP_Thread_Pool_Threads::TAO_DTP_Thread_Pool_Threads (TAO_DTP_Thread_Pool &p) @@ -140,7 +140,7 @@ TAO_DTP_Thread_Pool::new_dynamic_thread (void) this->id_, this->definition_.max_threads_, (int)this->threads_.thr_count ())); } if (this->definition_.max_threads_ > 0 && - (int)this->threads_.thr_count () >= this->definition_.max_threads_) + (int)this->active_count_ >= this->definition_.max_threads_) return false; ACE_GUARD_RETURN (TAO_SYNCH_MUTEX, @@ -150,18 +150,14 @@ TAO_DTP_Thread_Pool::new_dynamic_thread (void) if (!this->manager_.orb_core ().has_shutdown () && !this->shutdown_ && (this->definition_.max_threads_ == -1 || - (int)this->threads_.thr_count () < this->definition_.max_threads_)) + (int)this->active_count_ < this->definition_.max_threads_)) { if (TAO_debug_level > 7) ACE_DEBUG ((LM_DEBUG, - ACE_TEXT ("TAO (%P|%t) DTP Pool %d ") - ACE_TEXT ("Current number of threads = %d; ") - ACE_TEXT ("min threads = %d; max threads = %d\n") - ACE_TEXT ("No leaders available; DTP creating new leader!\n"), + ACE_TEXT ("TAO (%P|%t) DTP Pool %d new_dynamic_thread, ") + ACE_TEXT ("count = %d, creating new thread\n"), this->id_, - this->threads_.thr_count (), - this->definition_.min_threads_, - this->definition_.max_threads_)); + this->active_count_)); if (this->create_threads_i (1, THR_NEW_LWP | THR_JOINABLE)) { diff --git a/TAO/tao/Dynamic_TP/DTP_Thread_Pool.h b/TAO/tao/Dynamic_TP/DTP_Thread_Pool.h index 1577ebfd619..8f174815321 100644 --- a/TAO/tao/Dynamic_TP/DTP_Thread_Pool.h +++ b/TAO/tao/Dynamic_TP/DTP_Thread_Pool.h @@ -56,7 +56,7 @@ public: /// Leader/Follower class uses this method to notify the system that /// we are out of leaders. - void no_leaders_available (void); + bool no_leaders_available (void); private: diff --git a/TAO/tao/Leader_Follower.cpp b/TAO/tao/Leader_Follower.cpp index 7a5d014efc7..cdc9255a2e0 100644 --- a/TAO/tao/Leader_Follower.cpp +++ b/TAO/tao/Leader_Follower.cpp @@ -80,8 +80,8 @@ TAO_Leader_Follower::elect_new_leader_i (void) #if defined (TAO_DEBUG_LEADER_FOLLOWER) ACE_DEBUG ((LM_DEBUG, - "TAO (%P|%t) - TAO_Leader_Follower::elect_new_leader_i - " - "follower is %@\n", + ACE_TEXT ("TAO (%P|%t) - TAO_Leader_Follower::elect_new_leader_i - ") + ACE_TEXT ("follower is %@\n"), follower)); #endif /* TAO_DEBUG_LEADER_FOLLOWER */ @@ -210,8 +210,8 @@ TAO_Leader_Follower::defer_event (ACE_Event_Handler* eh) if (TAO_debug_level > 7) ACE_DEBUG ((LM_DEBUG, - "TAO (%P|%t) - TAO_Leader_Follower::defer_event, " - "deferring event handler[%d]\n", + ACE_TEXT ("TAO (%P|%t) - TAO_Leader_Follower::defer_event, ") + ACE_TEXT ("deferring event handler[%d]\n"), eh->get_handle ())); Deferred_Event* ptr = 0; ACE_NEW_RETURN (ptr, @@ -303,8 +303,8 @@ TAO_Leader_Follower::wait_for_event (TAO_LF_Event *event, if (TAO_debug_level >= 5) ACE_DEBUG ((LM_DEBUG, - "TAO (%P|%t) - Leader_Follower[%d]::wait_for_event," - " (follower), cond <%@>\n", + ACE_TEXT ("TAO (%P|%t) - Leader_Follower[%d]::wait_for_event,") + ACE_TEXT (" (follower), cond <%@>\n"), t_id, follower.get ())); // Bound the follower and the LF_Event, this is important to @@ -346,8 +346,8 @@ TAO_Leader_Follower::wait_for_event (TAO_LF_Event *event, { if (TAO_debug_level >= 5) ACE_DEBUG ((LM_DEBUG, - "TAO (%P|%t) - Leader_Follower[%d]::wait_for_event, " - " (follower) [no timer, cond failed]\n", + ACE_TEXT ("TAO (%P|%t) - Leader_Follower[%d]::wait_for_event, ") + ACE_TEXT (" (follower) [no timer, cond failed]\n"), t_id)); // @@ Michael: What is our error handling in this case? @@ -365,8 +365,8 @@ TAO_Leader_Follower::wait_for_event (TAO_LF_Event *event, { if (TAO_debug_level >= 5) ACE_DEBUG ((LM_DEBUG, - "TAO (%P|%t) - Leader_Follower[%d]::wait, " - "(follower) [has timer, follower failed]\n", + ACE_TEXT ("TAO (%P|%t) - Leader_Follower[%d]::wait, ") + ACE_TEXT ("(follower) [has timer, follower failed]\n"), t_id )); // If we have timedout set the state in the @@ -397,8 +397,8 @@ TAO_Leader_Follower::wait_for_event (TAO_LF_Event *event, && TAO_debug_level > 0) { ACE_ERROR ((LM_ERROR, - "TAO (%P|%t) - Leader_Follower[%d]::wait_for_event, " - "elect_new_leader failed\n", + ACE_TEXT("TAO (%P|%t) - Leader_Follower[%d]::wait_for_event, ") + ACE_TEXT("elect_new_leader failed\n"), t_id )); } } @@ -419,8 +419,8 @@ TAO_Leader_Follower::wait_for_event (TAO_LF_Event *event, if (TAO_debug_level >= 5) ACE_DEBUG ((LM_DEBUG, - "TAO (%P|%t) - Leader_Follower[%d]::wait_for_event," - " done (follower), successful %d\n", + ACE_TEXT ("TAO (%P|%t) - Leader_Follower[%d]::wait_for_event,") + ACE_TEXT (" done (follower), successful %d\n"), t_id, event->successful ())); @@ -439,6 +439,36 @@ TAO_Leader_Follower::wait_for_event (TAO_LF_Event *event, // i.e. ACE_ASSERT (event->successful () == 0); } // End Scope #3: we are no longer a follower + // One last attempt to avoid becoming a client-leader + // If there is a new_leader_generator attached, give it a chance to + // create a leader thread before becoming a leader. + if (this->avoid_client_leader_ && this->no_leaders_available()) + { + if (TAO_debug_level >= 5) + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("TAO (%P|%t) - Leader_Follower[%d]::wait_for_event, ") + ACE_TEXT ("Would become client leader, ") + ACE_TEXT ("but generating new thread\n"), + t_id)); + } + + // Yield, providing the event thread some time to grab leadership + ACE_GUARD_RETURN (ACE_Reverse_Lock<TAO_SYNCH_MUTEX>, rev_mon, + this->reverse_lock (), -1); + ACE_OS::thr_yield (); + continue; + } + else + { + if (TAO_debug_level >= 5) + { + ACE_DEBUG ((LM_DEBUG, + ACE_TEXT ("TAO (%P|%t) - Leader_Follower[%d]::wait_for_event, ") + ACE_TEXT ("Becoming client leader.\n"), + t_id)); + } + } // = Leader Code. // The only way to reach this point is if we must become the @@ -465,8 +495,8 @@ TAO_Leader_Follower::wait_for_event (TAO_LF_Event *event, // Run the reactor event loop. if (TAO_debug_level >= 5) ACE_DEBUG ((LM_DEBUG, - "TAO (%P|%t) - Leader_Follower[%d]::wait_for_event," - " (leader) enter reactor event loop\n", + ACE_TEXT ("TAO (%P|%t) - Leader_Follower[%d]::wait_for_event,") + ACE_TEXT (" (leader) enter reactor event loop\n"), t_id)); // If we got our event, no need to run the event loop any @@ -500,8 +530,8 @@ TAO_Leader_Follower::wait_for_event (TAO_LF_Event *event, if (TAO_debug_level >= 5) ACE_DEBUG ((LM_DEBUG, - "TAO (%P|%t) - Leader_Follower[%d]::wait_for_event," - " (leader) exit reactor event loop\n", + ACE_TEXT ("TAO (%P|%t) - Leader_Follower[%d]::wait_for_event,") + ACE_TEXT (" (leader) exit reactor event loop\n"), t_id)); } // End Scope #6: we should now hold the lock again @@ -523,15 +553,15 @@ TAO_Leader_Follower::wait_for_event (TAO_LF_Event *event, { if (TAO_debug_level >= 5) ACE_DEBUG ((LM_DEBUG, - "TAO (%P|%t) - Leader_Follower[%d]::wait_for_event," - " (client) waking and yielding to allow event thread leadership\n", + ACE_TEXT ("TAO (%P|%t) - Leader_Follower[%d]::wait_for_event,") + ACE_TEXT (" (client) waking and yielding to allow event thread leadership\n"), t_id)); // Wake up the next leader (in case not yet done) if (this->elect_new_leader () == -1) ACE_ERROR_RETURN ((LM_ERROR, - "TAO (%P|%t) - Leader_Follower[%d]::wait_for_event," - " failed to elect new leader\n", + ACE_TEXT ("TAO (%P|%t) - Leader_Follower[%d]::wait_for_event,") + ACE_TEXT (" failed to elect new leader\n"), t_id), -1); @@ -559,15 +589,15 @@ TAO_Leader_Follower::wait_for_event (TAO_LF_Event *event, if (this->elect_new_leader () == -1) ACE_ERROR_RETURN ((LM_ERROR, - "TAO (%P|%t) - Leader_Follower[%d]::wait_for_event," - " failed to elect new leader\n", + ACE_TEXT ("TAO (%P|%t) - Leader_Follower[%d]::wait_for_event,") + ACE_TEXT (" failed to elect new leader\n"), t_id), -1); if (result == -1 && !this->reactor_->reactor_event_loop_done ()) ACE_ERROR_RETURN ((LM_ERROR, - "TAO (%P|%t) - Leader_Follower[%d]::wait_for_event," - " handle_events failed\n", + ACE_TEXT ("TAO (%P|%t) - Leader_Follower[%d]::wait_for_event,") + ACE_TEXT (" handle_events failed\n"), t_id), -1); diff --git a/TAO/tao/Leader_Follower.h b/TAO/tao/Leader_Follower.h index 36291bea902..e28ec49651b 100644 --- a/TAO/tao/Leader_Follower.h +++ b/TAO/tao/Leader_Follower.h @@ -111,6 +111,11 @@ public: /// Checks if we are a leader thread bool is_client_leader_thread (void) const; + /// Sets the client leader avoidance flag true. This is used with the + /// noupcall wait strategy to allow the creation of dynamic threads + /// when possible + void set_avoid_client_leader (void); + /** * A leader thread is relinquishing its role, unless there are more * leader threads running pick up a follower (if there is any) to @@ -183,7 +188,7 @@ public: ACE_Reactor *reactor (void); /// Called when we are out of leaders. - void no_leaders_available (void); + bool no_leaders_available (void); /// Set the new leader generator. void set_new_leader_generator(TAO_New_Leader_Generator *new_leader_generator); @@ -258,6 +263,13 @@ private: /// The reactor ACE_Reactor *reactor_; + /// Flag to indicate that it is preferable to start a new thread, if possible + /// rather than become a client leader. In particular when using the no-upcall + /// wait strategy along with the dynamic thread pool, this is the case. It is + /// still possible for a client leader to emerge in the case when no additional + /// threads may be generated. + bool avoid_client_leader_; + /// Is a client thread the current leader? int client_thread_is_leader_; diff --git a/TAO/tao/Leader_Follower.inl b/TAO/tao/Leader_Follower.inl index 258c4dda450..fce063c5f01 100644 --- a/TAO/tao/Leader_Follower.inl +++ b/TAO/tao/Leader_Follower.inl @@ -17,6 +17,7 @@ TAO_Leader_Follower::TAO_Leader_Follower (TAO_ORB_Core* orb_core, leaders_ (0), clients_ (0), reactor_ (0), + avoid_client_leader_ (false), client_thread_is_leader_ (0), event_loop_threads_waiting_ (0), event_loop_threads_condition_ (lock_), @@ -30,17 +31,24 @@ TAO_Leader_Follower::get_tss_resources (void) const return this->orb_core_->get_tss_resources (); } +ACE_INLINE void +TAO_Leader_Follower::set_avoid_client_leader (void) +{ + this->avoid_client_leader_ = true; +} + ACE_INLINE bool TAO_Leader_Follower::follower_available (void) const { return !this->follower_set_.is_empty (); } -ACE_INLINE void +ACE_INLINE bool TAO_Leader_Follower::no_leaders_available (void) { if (this->new_leader_generator_) - this->new_leader_generator_->no_leaders_available (); + return this->new_leader_generator_->no_leaders_available (); + return false; } ACE_INLINE int diff --git a/TAO/tao/New_Leader_Generator.h b/TAO/tao/New_Leader_Generator.h index d932c51b605..e3918b29c47 100644 --- a/TAO/tao/New_Leader_Generator.h +++ b/TAO/tao/New_Leader_Generator.h @@ -41,7 +41,7 @@ public: /// Leader/Follower class uses this method to notify the system that /// we are out of leaders. - virtual void no_leaders_available (void) = 0; + virtual bool no_leaders_available (void) = 0; }; TAO_END_VERSIONED_NAMESPACE_DECL diff --git a/TAO/tao/RTCORBA/Thread_Pool.cpp b/TAO/tao/RTCORBA/Thread_Pool.cpp index 248fc203aa4..9eba4ece9d3 100644 --- a/TAO/tao/RTCORBA/Thread_Pool.cpp +++ b/TAO/tao/RTCORBA/Thread_Pool.cpp @@ -28,11 +28,11 @@ TAO_RT_New_Leader_Generator::TAO_RT_New_Leader_Generator ( { } -void +bool TAO_RT_New_Leader_Generator::no_leaders_available (void) { // Request a new dynamic thread from the Thread Lane - this->lane_.new_dynamic_thread (); + return this->lane_.new_dynamic_thread (); } TAO_Thread_Pool_Threads::TAO_Thread_Pool_Threads (TAO_Thread_Lane &lane) diff --git a/TAO/tao/RTCORBA/Thread_Pool.h b/TAO/tao/RTCORBA/Thread_Pool.h index d89acdaa822..7154a9517ec 100644 --- a/TAO/tao/RTCORBA/Thread_Pool.h +++ b/TAO/tao/RTCORBA/Thread_Pool.h @@ -53,7 +53,7 @@ public: /// Leader/Follower class uses this method to notify the system that /// we are out of leaders. - void no_leaders_available (void); + bool no_leaders_available (void); private: diff --git a/TAO/tests/Dynamic_TP/ORB_ThreadPool/middle.conf b/TAO/tests/Dynamic_TP/ORB_ThreadPool/middle.conf index 4902b200c2f..099f3b2d1e3 100644 --- a/TAO/tests/Dynamic_TP/ORB_ThreadPool/middle.conf +++ b/TAO/tests/Dynamic_TP/ORB_ThreadPool/middle.conf @@ -1,6 +1,5 @@ # $Id$ -dynamic DTP_Config Service_Object * TAO_Dynamic_TP:_make_TAO_DTP_Config() "-DTPName ORBPool -DTPMin 2 -DTPInit 2" - # -DTPMax 7 -DTPTimeout 30" +dynamic DTP_Config Service_Object * TAO_Dynamic_TP:_make_TAO_DTP_Config() "-DTPName ORBPool -DTPMin 2 -DTPInit 2 -DTPTimeout 30" dynamic DTP_ORB_Loader Service_Object * TAO_Dynamic_TP:_make_TAO_DTP_ORB_Loader() "" -#static Client_Strategy_Factory "-ORBWaitStrategy MT_NOUPCALL" +static Client_Strategy_Factory "-ORBWaitStrategy MT_NOUPCALL" |