diff options
-rw-r--r-- | ChangeLog-99b | 22 | ||||
-rw-r--r-- | ace/OS.cpp | 55 | ||||
-rw-r--r-- | ace/OS.h | 18 | ||||
-rw-r--r-- | ace/OS.i | 92 | ||||
-rw-r--r-- | ace/Synch.cpp | 22 | ||||
-rw-r--r-- | ace/Synch.h | 27 | ||||
-rw-r--r-- | ace/Synch.i | 12 | ||||
-rw-r--r-- | ace/Token.cpp | 31 | ||||
-rw-r--r-- | ace/Token.h | 12 |
9 files changed, 261 insertions, 30 deletions
diff --git a/ChangeLog-99b b/ChangeLog-99b index a6d92764bdc..bb577483eb5 100644 --- a/ChangeLog-99b +++ b/ChangeLog-99b @@ -1,3 +1,25 @@ +Tue Aug 17 17:17:13 1999 Carlos O'Ryan <coryan@cs.wustl.edu> + + * ace/OS.h: + * ace/OS.i: + * ace/OS.cpp: + Added new data type to handle condition variable attributes + (ACE_condattr_t). + New methods to manipulate that data type (ACE_OS::cond_attr_init + and destroy) + Add new method to create a condition variable from a + pre-initialized attribute. + + * ace/Synch.h: + * ace/Synch.i: + * ace/Synch.cpp: + Added new wrapper for the ACE_condattr_t structure. + + * ace/Token.h: + * ace/Token.cpp: + Use ACE_Condition_Attributes to minimize the number of memory + allocations and locks in the critical path of the TP_Reactor. + Tue Aug 17 15:55:17 1999 Nanbor Wang <nanbor@cs.wustl.edu> * performance-tests/TCP/TCP.{dsw,dsp}: diff --git a/ace/OS.cpp b/ace/OS.cpp index aa038af8617..e4f4c998c34 100644 --- a/ace/OS.cpp +++ b/ace/OS.cpp @@ -5297,18 +5297,25 @@ ACE_OS::rwlock_init (ACE_rwlock_t *rw, name4, ACE_UNIQUE_NAME_LEN); - if (ACE_OS::mutex_init (&rw->lock_, type, name1, arg) == 0 - && ACE_OS::cond_init (&rw->waiting_readers_, type, name2, arg) == 0 - && ACE_OS::cond_init (&rw->waiting_writers_, type, name3, arg) == 0 - && ACE_OS::cond_init (&rw->waiting_important_writer_, type, name4, arg) == 0) - { - // Success! - rw->ref_count_ = 0; - rw->num_waiting_writers_ = 0; - rw->num_waiting_readers_ = 0; - rw->important_writer_ = 0; - - result = 0; + ACE_condattr_t attributes; + if (ACE_OS::condattr_init (attributes, type) == 0) + { + if (ACE_OS::mutex_init (&rw->lock_, type, name1, arg) == 0 + && ACE_OS::cond_init (&rw->waiting_readers_, + attributes, name2, arg) == 0 + && ACE_OS::cond_init (&rw->waiting_writers_, + attributes, name3, arg) == 0 + && ACE_OS::cond_init (&rw->waiting_important_writer_, + attributes, name4, arg) == 0) + { + // Success! + rw->ref_count_ = 0; + rw->num_waiting_writers_ = 0; + rw->num_waiting_readers_ = 0; + rw->important_writer_ = 0; + result = 0; + } + ACE_OS::condattr_destroy (attributes); } if (result == -1) @@ -5354,6 +5361,30 @@ ACE_OS::cond_destroy (ACE_cond_t *cv) # endif /* ACE_HAS_THREADS */ } +// @@ The following functions could be inlined if i could figure where +// to put it among the #ifdefs! +int +ACE_OS::condattr_init (ACE_condattr_t &attributes, + int type) +{ + attributes.type = type; + return 0; +} + +int +ACE_OS::condattr_destroy (ACE_condattr_t &) +{ + return 0; +} + +int +ACE_OS::cond_init (ACE_cond_t *cv, + ACE_condatttr_t &attributes, + LPCTSTR name, void *arg) +{ + return ACE_OS::cond_init (cv, attributes.type, name, arg); +} + int ACE_OS::cond_init (ACE_cond_t *cv, int type, LPCTSTR name, void *arg) { @@ -2090,6 +2090,7 @@ typedef pthread_t ACE_thread_t; # if !defined (ACE_LACKS_COND_T) typedef pthread_mutex_t ACE_mutex_t; typedef pthread_cond_t ACE_cond_t; +typedef pthread_condattr_t ACE_condattr_t; # endif /* ! ACE_LACKS_COND_T */ typedef pthread_mutex_t ACE_thread_mutex_t; @@ -2245,7 +2246,12 @@ typedef rwlock_t ACE_rwlock_t; # if !defined (ACE_HAS_POSIX_SEM) typedef sema_t ACE_sema_t; # endif /* !ACE_HAS_POSIX_SEM */ + typedef cond_t ACE_cond_t; +struct ACE_Export ACE_condattr_t +{ + int type; +}; typedef ACE_thread_t ACE_hthread_t; typedef ACE_mutex_t ACE_thread_mutex_t; @@ -2502,6 +2508,11 @@ protected: size_t was_broadcast_; // Keeps track of whether we were broadcasting or just signaling. }; + +struct ACE_Export ACE_condattr_t +{ + int type; +}; # endif /* ACE_LACKS_COND_T */ # if defined (ACE_LACKS_RWLOCK_T) @@ -5278,12 +5289,19 @@ public: static long sysconf (int); // = A set of wrappers for condition variables. + static int condattr_init (ACE_condattr_t &attributes, + int type = ACE_DEFAULT_SYNCH_TYPE); + static int condattr_destroy (ACE_condattr_t &attributes); static int cond_broadcast (ACE_cond_t *cv); static int cond_destroy (ACE_cond_t *cv); static int cond_init (ACE_cond_t *cv, int type = ACE_DEFAULT_SYNCH_TYPE, LPCTSTR name = 0, void *arg = 0); + static int cond_init (ACE_cond_t *cv, + ACE_condattr_t &attributes, + LPCTSTR name = 0, + void *arg = 0); static int cond_signal (ACE_cond_t *cv); static int cond_timedwait (ACE_cond_t *cv, ACE_mutex_t *m, @@ -2308,56 +2308,109 @@ ACE_OS::cond_destroy (ACE_cond_t *cv) } ACE_INLINE int -ACE_OS::cond_init (ACE_cond_t *cv, int type, LPCTSTR name, void *arg) +ACE_OS::condattr_init (ACE_condattr_t &attributes, + int type) { - // ACE_TRACE ("ACE_OS::cond_init"); ACE_UNUSED_ARG (type); - ACE_UNUSED_ARG (name); - ACE_UNUSED_ARG (arg); # if defined (ACE_HAS_THREADS) # if defined (ACE_HAS_PTHREADS) - pthread_condattr_t attributes; int result = -1; + if ( # if defined (ACE_HAS_PTHREADS_DRAFT4) - if (::pthread_condattr_create (&attributes) == 0 - && ::pthread_cond_init (cv, attributes) == 0 + ::pthread_condattr_create (&attributes) == 0 # elif defined (ACE_HAS_PTHREADS_STD) || defined (ACE_HAS_PTHREADS_DRAFT7) - if (ACE_ADAPT_RETVAL(::pthread_condattr_init (&attributes), result) == 0 + ACE_ADAPT_RETVAL(::pthread_condattr_init (&attributes), result) == 0 # if defined (_POSIX_THREAD_PROCESS_SHARED) && !defined (ACE_LACKS_MUTEXATTR_PSHARED) && ACE_ADAPT_RETVAL(::pthread_condattr_setpshared(&attributes, type), result) == 0 # endif /* _POSIX_THREAD_PROCESS_SHARED && ! ACE_LACKS_MUTEXATTR_PSHARED */ - && ACE_ADAPT_RETVAL(::pthread_cond_init (cv, &attributes), result) == 0 # else /* this is draft 6 */ - if (::pthread_condattr_init (&attributes) == 0 + ::pthread_condattr_init (&attributes) == 0 # if !defined (ACE_LACKS_CONDATTR_PSHARED) && ::pthread_condattr_setpshared (&attributes, type) == 0 # endif /* ACE_LACKS_CONDATTR_PSHARED */ # if defined (ACE_HAS_PTHREAD_CONDATTR_SETKIND_NP) && ::pthread_condattr_setkind_np (&attributes, type) == 0 # endif /* ACE_HAS_PTHREAD_CONDATTR_SETKIND_NP */ - && ::pthread_cond_init (cv, &attributes) == 0 # endif /* ACE_HAS_PTHREADS_DRAFT4 */ ) result = 0; else result = -1; // ACE_ADAPT_RETVAL used it for intermediate status + + return result; +# elif defined (ACE_HAS_STHREADS) + attributes.type = type; + + return 0; +# endif /* ACE_HAS_PTHREADS && ACE_HAS_STHREADS */ + +# else + ACE_UNUSED_ARG (attributes); + ACE_UNUSED_ARG (type); + ACE_NOTSUP_RETURN (-1); +# endif /* ACE_HAS_THREADS */ +} + +ACE_INLINE int +ACE_OS::condattr_destroy (ACE_condattr_t &attributes) +{ +# if defined (ACE_HAS_THREADS) +# if defined (ACE_HAS_PTHREADS) + # if defined (ACE_HAS_PTHREADS_DRAFT4) ::pthread_condattr_delete (&attributes); # else ::pthread_condattr_destroy (&attributes); # endif /* ACE_HAS_PTHREADS_DRAFT4 */ +# elif defined (ACE_HAS_STHREADS) + attributes.type = 0; + return 0; +# endif /* ACE_HAS_PTHREADS && ACE_HAS_STHREADS */ + ACE_UNUSED_ARG (attributes); + return 0; +# endif /* ACE_HAS_THREADS */ +} + +ACE_INLINE int +ACE_OS::cond_init (ACE_cond_t *cv, + ACE_condattr_t &attributes, + LPCTSTR name, + void *arg) +{ + // ACE_TRACE ("ACE_OS::cond_init"); + ACE_UNUSED_ARG (name); + ACE_UNUSED_ARG (arg); +# if defined (ACE_HAS_THREADS) +# if defined (ACE_HAS_PTHREADS) + int result = -1; + + if ( +# if defined (ACE_HAS_PTHREADS_DRAFT4) + ::pthread_cond_init (cv, attributes) == 0 +# elif defined (ACE_HAS_PTHREADS_STD) || defined (ACE_HAS_PTHREADS_DRAFT7) + ACE_ADAPT_RETVAL(::pthread_cond_init (cv, &attributes), result) == 0 +# else /* this is draft 6 */ + ::pthread_cond_init (cv, &attributes) == 0 +# endif /* ACE_HAS_PTHREADS_DRAFT4 */ + ) + result = 0; + else + result = -1; // ACE_ADAPT_RETVAL used it for intermediate status + return result; # elif defined (ACE_HAS_STHREADS) - ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::cond_init (cv, type, arg), + ACE_OSCALL_RETURN (ACE_ADAPT_RETVAL (::cond_init (cv, + attributes.type, + arg), ace_result_), int, -1); # endif /* ACE_HAS_PTHREADS && ACE_HAS_STHREADS */ # else ACE_UNUSED_ARG (cv); - ACE_UNUSED_ARG (type); + ACE_UNUSED_ARG (attributes); ACE_UNUSED_ARG (name); ACE_UNUSED_ARG (arg); ACE_NOTSUP_RETURN (-1); @@ -2365,6 +2418,19 @@ ACE_OS::cond_init (ACE_cond_t *cv, int type, LPCTSTR name, void *arg) } ACE_INLINE int +ACE_OS::cond_init (ACE_cond_t *cv, int type, LPCTSTR name, void *arg) +{ + ACE_condattr_t attributes; + if (ACE_OS::condattr_init (attributes, type) == 0 + && ACE_OS::cond_init (cv, attributes, name, arg) == 0) + { + (void) ACE_OS::condattr_destroy (attributes); + return 0; + } + return -1; +} + +ACE_INLINE int ACE_OS::cond_signal (ACE_cond_t *cv) { ACE_TRACE ("ACE_OS::cond_signal"); diff --git a/ace/Synch.cpp b/ace/Synch.cpp index 0afd7125221..df0e3a27534 100644 --- a/ace/Synch.cpp +++ b/ace/Synch.cpp @@ -758,6 +758,28 @@ ACE_Condition_Thread_Mutex::ACE_Condition_Thread_Mutex (const ACE_Thread_Mutex & ASYS_TEXT ("ACE_Condition_Thread_Mutex::ACE_Condition_Thread_Mutex"))); } +ACE_Condition_Thread_Mutex:: +ACE_Condition_Thread_Mutex (const ACE_Thread_Mutex &m, + ACE_Condition_Attributes &attributes, + LPCTSTR name, + void *arg) + : mutex_ ((ACE_Thread_Mutex &) m), + removed_ (0) +{ +#if defined (ACE_HAS_FSU_PTHREADS) +// Initialize FSU pthreads package. +// If called more than once, pthread_init does nothing +// and so does no harm. + pthread_init (); +#endif /* ACE_HAS_FSU_PTHREADS */ + +// ACE_TRACE ("ACE_Condition_Thread_Mutex::ACE_Condition_Thread_Mutex"); + if (ACE_OS::cond_init (&this->cond_, attributes.attributes_, + name, arg) != 0) + ACE_ERROR ((LM_ERROR, ASYS_TEXT ("%p\n"), + ASYS_TEXT ("ACE_Condition_Thread_Mutex::ACE_Condition_Thread_Mutex"))); +} + ACE_Condition_Thread_Mutex::~ACE_Condition_Thread_Mutex (void) { // ACE_TRACE ("ACE_Condition_Thread_Mutex::~ACE_Condition_Thread_Mutex"); diff --git a/ace/Synch.h b/ace/Synch.h index 63bdd85b1d9..c03e3c2bce4 100644 --- a/ace/Synch.h +++ b/ace/Synch.h @@ -1187,6 +1187,27 @@ private: }; #endif /* ACE_USES_OBSOLETE_GUARD_CLASSES */ +class ACE_Export ACE_Condition_Attributes +{ +public: + ACE_Condition_Attributes (int type = ACE_DEFAULT_SYNCH_TYPE); + // Constructor + + ~ACE_Condition_Attributes (void); + // Destructor + +private: + friend class ACE_Condition_Thread_Mutex; + + ACE_condattr_t attributes_; + // The attributes + +private: + // = Prevent assignment and initialization. + void operator= (const ACE_Condition_Attributes &); + ACE_Condition_Attributes (const ACE_Condition_Attributes &); +}; + class ACE_Export ACE_Condition_Thread_Mutex { // = TITLE @@ -1214,6 +1235,12 @@ public: void *arg = 0); // Initialize the condition variable. + ACE_Condition_Thread_Mutex (const ACE_Thread_Mutex &m, + ACE_Condition_Attributes &attributes, + LPCTSTR name = 0, + void *arg = 0); + // Initialize the condition variable. + ~ACE_Condition_Thread_Mutex (void); // Implicitly destroy the condition variable. diff --git a/ace/Synch.i b/ace/Synch.i index 9c0338ee89e..f232df780ca 100644 --- a/ace/Synch.i +++ b/ace/Synch.i @@ -670,6 +670,18 @@ ACE_Thread_Mutex_Guard::remove (void) } #endif /* ACE_USES_OBSOLETE_GUARD_CLASSES */ +ACE_INLINE +ACE_Condition_Attributes::ACE_Condition_Attributes (int type) +{ + (void) ACE_OS::condattr_init (this->attributes_, type); +} + +ACE_INLINE +ACE_Condition_Attributes::~ACE_Condition_Attributes (void) +{ + ACE_OS::condattr_destroy (this->attributes_); +} + ACE_INLINE int ACE_Condition_Thread_Mutex::remove (void) { diff --git a/ace/Token.cpp b/ace/Token.cpp index d01102badc3..cc3973dccf0 100644 --- a/ace/Token.cpp +++ b/ace/Token.cpp @@ -55,6 +55,26 @@ ACE_Token::ACE_Token_Queue_Entry::ACE_Token_Queue_Entry (ACE_Thread_Mutex &m, ACE_TRACE ("ACE_Token::ACE_Token_Queue_Entry::ACE_Token_Queue_Entry"); } +ACE_Token::ACE_Token_Queue_Entry::ACE_Token_Queue_Entry (ACE_Thread_Mutex &m, + ACE_thread_t t_id, + ACE_Condition_Attributes &attributes) + : next_ (0), + thread_id_ (t_id), +#if defined (ACE_TOKEN_USES_SEMAPHORE) + cv_ (0), +#else + cv_ (m, attributes), +#endif /* ACE_TOKEN_USES_SEMAPHORE */ + runable_ (0) +{ +#if defined (ACE_TOKEN_USES_SEMAPHORE) + ACE_UNUSED_ARG (m); + ACE_UNUSED_ARG (attributes); +#endif /* ACE_TOKEN_USES_SEMAPHORE */ + + ACE_TRACE ("ACE_Token::ACE_Token_Queue_Entry::ACE_Token_Queue_Entry"); +} + ACE_Token::ACE_Token_Queue::ACE_Token_Queue (void) : head_ (0), tail_ (0) @@ -99,7 +119,8 @@ ACE_Token::ACE_Token (LPCTSTR name, void *any) in_use_ (0), waiters_ (0), nesting_level_ (0), - signal_all_threads_ (0) + signal_all_threads_ (0), + attributes_ (USYNC_THREAD) { // ACE_TRACE ("ACE_Token::ACE_Token"); } @@ -120,8 +141,8 @@ ACE_Token::shared_acquire (void (*sleep_hook_func)(void *), ACE_thread_t thr_id = ACE_Thread::self (); - ACE_Token_Queue *queue = (op_type == ACE_Token::READ_TOKEN - ? &this->readers_ + ACE_Token_Queue *queue = (op_type == ACE_Token::READ_TOKEN + ? &this->readers_ : &this->writers_); #if defined (DEBUGGING) @@ -151,7 +172,9 @@ ACE_Token::shared_acquire (void (*sleep_hook_func)(void *), // Allocate q entry on stack. This works since we don't // exit this method's activation record until we've got the // token. - ACE_Token::ACE_Token_Queue_Entry my_entry (this->lock_, thr_id); + ACE_Token::ACE_Token_Queue_Entry my_entry (this->lock_, + thr_id, + this->attributes_); int ret = 0; if (queue->head_ == 0) // I'm first and only waiter in line... diff --git a/ace/Token.h b/ace/Token.h index 18f7e9ac4d6..009cf53f1a7 100644 --- a/ace/Token.h +++ b/ace/Token.h @@ -176,7 +176,14 @@ public: struct ACE_Token_Queue_Entry { - ACE_Token_Queue_Entry (ACE_Thread_Mutex &m, ACE_thread_t t_id); + ACE_Token_Queue_Entry (ACE_Thread_Mutex &m, + ACE_thread_t t_id); + // Constructor + + ACE_Token_Queue_Entry (ACE_Thread_Mutex &m, + ACE_thread_t t_id, + ACE_Condition_Attributes &attributes); + // Constructor using a pre-allocated attributes int wait (ACE_Time_Value *timeout, ACE_Thread_Mutex &lock); // Entry blocks on the token. @@ -253,6 +260,9 @@ private: int signal_all_threads_; // Whether we are "signaling" all threads or not. + + ACE_Condition_Attributes attributes_; + // The attributes for the condition variables, optimizes lock time. }; #if defined (__ACE_INLINE__) |