summaryrefslogtreecommitdiff
path: root/lib/cpp
diff options
context:
space:
mode:
authorDavid Reiss <dreiss@apache.org>2008-06-10 22:55:13 +0000
committerDavid Reiss <dreiss@apache.org>2008-06-10 22:55:13 +0000
commitc6dab613003c704f072542f39214f7af64fc0412 (patch)
tree6cf0c32408e229af01a44f79023d29747ba6fde7 /lib/cpp
parente3a64923e9620ebf99ff51ed5bfcb366e503c79e (diff)
downloadthrift-c6dab613003c704f072542f39214f7af64fc0412.tar.gz
Thrift: Allow for alternative Mutex initializers.
Summary: Add an argument to the Mutex constructor. It takes a pointer to a function that initializes the internal pthread_mutex_t. We provide initializers for default pthread_mutex_t (which is our default), adaptive mutexes, and recursive mutexes. Reviewed By: hzhao, psaab, mcslee Test Plan: Built libthrift. git-svn-id: https://svn.apache.org/repos/asf/incubator/thrift/trunk@666362 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'lib/cpp')
-rw-r--r--lib/cpp/src/concurrency/Mutex.cpp50
-rw-r--r--lib/cpp/src/concurrency/Mutex.h12
2 files changed, 57 insertions, 5 deletions
diff --git a/lib/cpp/src/concurrency/Mutex.cpp b/lib/cpp/src/concurrency/Mutex.cpp
index 87bfd354c..b160b670e 100644
--- a/lib/cpp/src/concurrency/Mutex.cpp
+++ b/lib/cpp/src/concurrency/Mutex.cpp
@@ -21,9 +21,8 @@ namespace facebook { namespace thrift { namespace concurrency {
*/
class Mutex::impl {
public:
- impl() : initialized_(false) {
- int ret = pthread_mutex_init(&pthread_mutex_, NULL);
- assert(ret == 0);
+ impl(Initializer init) : initialized_(false) {
+ init(&pthread_mutex_);
initialized_ = true;
}
@@ -46,7 +45,7 @@ class Mutex::impl {
mutable bool initialized_;
};
-Mutex::Mutex() : impl_(new Mutex::impl()) {}
+Mutex::Mutex(Initializer init) : impl_(new Mutex::impl(init)) {}
void Mutex::lock() const { impl_->lock(); }
@@ -54,6 +53,49 @@ bool Mutex::trylock() const { return impl_->trylock(); }
void Mutex::unlock() const { impl_->unlock(); }
+void Mutex::DEFAULT_INITIALIZER(void* arg) {
+ pthread_mutex_t* pthread_mutex = (pthread_mutex_t*)arg;
+ int ret = pthread_mutex_init(pthread_mutex, NULL);
+ assert(ret == 0);
+}
+
+static void init_with_kind(pthread_mutex_t* mutex, int kind) {
+ pthread_mutexattr_t mutexattr;
+ int ret = pthread_mutexattr_init(&mutexattr);
+ assert(ret == 0);
+
+ // Apparently, this can fail. Should we really be aborting?
+ ret = pthread_mutexattr_settype(&mutexattr, kind);
+ assert(ret == 0);
+
+ ret = pthread_mutex_init(mutex, &mutexattr);
+ assert(ret == 0);
+
+ ret = pthread_mutexattr_destroy(&mutexattr);
+ assert(ret == 0);
+}
+
+#ifdef PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP
+void Mutex::ADAPTIVE_INITIALIZER(void* arg) {
+ // From mysql source: mysys/my_thr_init.c
+ // Set mutex type to "fast" a.k.a "adaptive"
+ //
+ // In this case the thread may steal the mutex from some other thread
+ // that is waiting for the same mutex. This will save us some
+ // context switches but may cause a thread to 'starve forever' while
+ // waiting for the mutex (not likely if the code within the mutex is
+ // short).
+ init_with_kind((pthread_mutex_t*)arg, PTHREAD_MUTEX_ADAPTIVE_NP);
+}
+#endif
+
+#ifdef PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP
+void Mutex::RECURSIVE_INITIALIZER(void* arg) {
+ init_with_kind((pthread_mutex_t*)arg, PTHREAD_MUTEX_RECURSIVE_NP);
+}
+#endif
+
+
/**
* Implementation of ReadWriteMutex class using POSIX rw lock
*
diff --git a/lib/cpp/src/concurrency/Mutex.h b/lib/cpp/src/concurrency/Mutex.h
index e176628a7..7830d6867 100644
--- a/lib/cpp/src/concurrency/Mutex.h
+++ b/lib/cpp/src/concurrency/Mutex.h
@@ -19,12 +19,22 @@ namespace facebook { namespace thrift { namespace concurrency {
*/
class Mutex {
public:
- Mutex();
+ typedef void (*Initializer)(void*);
+
+ Mutex(Initializer init = DEFAULT_INITIALIZER);
virtual ~Mutex() {}
virtual void lock() const;
virtual bool trylock() const;
virtual void unlock() const;
+ static void DEFAULT_INITIALIZER(void*);
+#ifdef PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP
+ static void ADAPTIVE_INITIALIZER(void*);
+#endif
+#ifdef PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP
+ static void RECURSIVE_INITIALIZER(void*);
+#endif
+
private:
class impl;