libfoedus-core
FOEDUS Core Library
shared_mutex.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2014-2015, Hewlett-Packard Development Company, LP.
3  * This program is free software; you can redistribute it and/or modify it
4  * under the terms of the GNU General Public License as published by the Free
5  * Software Foundation; either version 2 of the License, or (at your option)
6  * any later version.
7  *
8  * This program is distributed in the hope that it will be useful, but WITHOUT
9  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
11  * more details. You should have received a copy of the GNU General Public
12  * License along with this program; if not, write to the Free Software
13  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
14  *
15  * HP designates this particular file as subject to the "Classpath" exception
16  * as provided by HP in the LICENSE.txt file that accompanied this code.
17  */
19 
20 #include <errno.h>
21 #include <time.h>
22 #include <sys/time.h>
23 
24 #include "foedus/assert_nd.hpp"
25 
26 namespace foedus {
27 namespace soc {
28 
29 void SharedMutex::initialize(bool recursive) {
30  uninitialize();
31  int attr_ret = ::pthread_mutexattr_init(&attr_);
32  ASSERT_ND(attr_ret == 0);
33 
34  int shared_ret = ::pthread_mutexattr_setpshared(&attr_, PTHREAD_PROCESS_SHARED);
35  ASSERT_ND(shared_ret == 0);
36 
37  int type_ret = ::pthread_mutexattr_settype(
38  &attr_,
39  recursive ? PTHREAD_MUTEX_RECURSIVE_NP : PTHREAD_MUTEX_FAST_NP);
40  ASSERT_ND(type_ret == 0);
41 
42  int mutex_ret = ::pthread_mutex_init(&mutex_, &attr_);
43  ASSERT_ND(mutex_ret == 0);
44 
45  recursive_ = recursive;
46  initialized_ = true;
47 }
48 
50  if (!initialized_) {
51  return;
52  }
53 
54  int mutex_ret = ::pthread_mutex_destroy(&mutex_);
55  ASSERT_ND(mutex_ret == 0);
56 
57  int attr_ret = ::pthread_mutexattr_destroy(&attr_);
58  ASSERT_ND(attr_ret == 0);
59 
60  initialized_ = false;
61 }
62 
64  ASSERT_ND(initialized_);
65  int ret = ::pthread_mutex_lock(&mutex_);
66  ASSERT_ND(ret == 0);
67 }
68 
69 bool SharedMutex::timedlock(uint64_t timeout_nanosec) {
70  if (timeout_nanosec == 0) {
71  return trylock();
72  }
73 
74  ASSERT_ND(initialized_);
75  struct timespec timeout;
76  struct timeval now;
77  ::gettimeofday(&now, CXX11_NULLPTR);
78  timeout.tv_sec = now.tv_sec + (timeout_nanosec / 1000000000ULL);
79  timeout.tv_nsec = now.tv_usec * 1000ULL + timeout_nanosec % 1000000000ULL;
80  timeout.tv_sec += (timeout.tv_nsec) / 1000000000ULL;
81  timeout.tv_nsec %= 1000000000ULL;
82  int ret = ::pthread_mutex_timedlock(&mutex_, &timeout);
83  ASSERT_ND(ret == 0 || ret == ETIMEDOUT);
84  return ret == 0;
85 }
86 
88  ASSERT_ND(initialized_);
89  int ret = ::pthread_mutex_trylock(&mutex_);
90  return ret == 0;
91 }
92 
94  ASSERT_ND(initialized_);
95  int ret = ::pthread_mutex_unlock(&mutex_);
96  ASSERT_ND(ret == 0);
97 }
98 
100  if (locked_by_me_) {
101  return;
102  }
103 
104  mutex_->lock();
105  locked_by_me_ = true;
106 }
107 
109  if (!locked_by_me_) {
110  return;
111  }
112 
113  mutex_->unlock();
114  locked_by_me_ = false;
115 }
116 
117 } // namespace soc
118 } // namespace foedus
bool timedlock(uint64_t timeout_nanosec)
Try lock up to the given timeout.
#define CXX11_NULLPTR
Used in public headers in place of "nullptr" of C++11.
Definition: cxx11.hpp:132
void initialize(bool recursive=false)
Root package of FOEDUS (Fast Optimistic Engine for Data Unification Services).
Definition: assert_nd.hpp:44
bool trylock()
Instantaneously try the lock.
void lock()
Unconditionally lock.
#define ASSERT_ND(x)
A warning-free wrapper macro of assert() that has no performance effect in release mode even when 'x'...
Definition: assert_nd.hpp:72
void unlock()
Unlock it.