summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPhil Mesnier <mesnier_p@ociweb.com>2013-02-19 02:08:55 +0000
committerPhil Mesnier <mesnier_p@ociweb.com>2013-02-19 02:08:55 +0000
commitcd36447f44d172d820a2cc464572a56f560b9f83 (patch)
treef1550e396bf73f63eedab006cdd3c5b6078254bc
parent76debafe81ddd5a8e701d15986289bdd5fd5c935 (diff)
downloadATCD-cd36447f44d172d820a2cc464572a56f560b9f83.tar.gz
Tue Feb 19 01:48:59 UTC 2013 Phil Mesnier <mesnier_p@ociweb.com>
-rw-r--r--TAO/ChangeLog30
-rw-r--r--TAO/tao/Dynamic_TP/DTP_ORBInitializer.cpp4
-rw-r--r--TAO/tao/Dynamic_TP/DTP_Thread_Pool.cpp18
-rw-r--r--TAO/tao/Dynamic_TP/DTP_Thread_Pool.h2
-rw-r--r--TAO/tao/Leader_Follower.cpp82
-rw-r--r--TAO/tao/Leader_Follower.h14
-rw-r--r--TAO/tao/Leader_Follower.inl12
-rw-r--r--TAO/tao/New_Leader_Generator.h2
-rw-r--r--TAO/tao/RTCORBA/Thread_Pool.cpp4
-rw-r--r--TAO/tao/RTCORBA/Thread_Pool.h2
-rw-r--r--TAO/tests/Dynamic_TP/ORB_ThreadPool/middle.conf5
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"