Robotics Library  0.7.0
mutex.h
Go to the documentation of this file.
1 //
2 // Copyright (c) 2009, Markus Rickert
3 // All rights reserved.
4 //
5 // Redistribution and use in source and binary forms, with or without
6 // modification, are permitted provided that the following conditions are met:
7 //
8 // * Redistributions of source code must retain the above copyright notice,
9 // this list of conditions and the following disclaimer.
10 // * Redistributions in binary form must reproduce the above copyright notice,
11 // this list of conditions and the following disclaimer in the documentation
12 // and/or other materials provided with the distribution.
13 //
14 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
15 // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
18 // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
19 // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
20 // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
21 // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
22 // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
23 // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
24 // POSSIBILITY OF SUCH DAMAGE.
25 //
26 
27 #ifndef RL_UTIL_XENOMAI_MUTEX_H
28 #define RL_UTIL_XENOMAI_MUTEX_H
29 
30 #include <chrono>
31 #include <system_error>
32 #include <native/mutex.h>
33 
34 #include "chrono.h"
35 
36 namespace rl
37 {
38  namespace util
39  {
40  namespace xenomai
41  {
43  {
44  public:
45 
46  protected:
47  typedef RT_MUTEX native_type;
48 
50  M_mutex()
51  {
52  int e = ::rt_mutex_create(&this->M_mutex, nullptr);
53 
54  if (e)
55  {
56  throw ::std::system_error(::std::error_code(-e, ::std::generic_category()));
57  }
58  }
59 
61 
63 
65  {
66  int e = ::rt_mutex_delete(&this->M_mutex);
67 
68  if (e)
69  {
70  throw ::std::system_error(::std::error_code(-e, ::std::generic_category()));
71  }
72  }
73 
75 
76  private:
77 
78  };
79 
81  {
82  public:
84 
85  recursive_mutex() = default;
86 
87  recursive_mutex(const recursive_mutex&) = delete;
88 
90 
91  ~recursive_mutex() = default;
92 
93  void lock()
94  {
95  int e = ::rt_mutex_acquire(&this->M_mutex, TM_INFINITE);
96 
97  if (e)
98  {
99  throw ::std::system_error(::std::error_code(-e, ::std::generic_category()));
100  }
101  }
102 
104  {
105  return &this->M_mutex;
106  }
107 
108  bool try_lock()
109  {
110  int e = ::rt_mutex_acquire(&this->M_mutex, TM_NONBLOCK);
111 
112  switch (e)
113  {
114  case 0:
115  return true;
116  break;
117  case -EWOULDBLOCK:
118  return false;
119  break;
120  default:
121  throw ::std::system_error(::std::error_code(-e, ::std::generic_category()));
122  break;
123  }
124  }
125 
126  void unlock()
127  {
128  int e = ::rt_mutex_release(&this->M_mutex);
129 
130  if (e)
131  {
132  throw ::std::system_error(::std::error_code(-e, ::std::generic_category()));
133  }
134  }
135 
136  protected:
137 
138  private:
139 
140  };
141 
142  template<typename Derived>
144  {
145  public:
146 
147  protected:
149 
150  template<typename Rep, typename Period>
151  bool M_try_lock_for(const ::std::chrono::duration< Rep, Period>& rtime)
152  {
153  clock_t::duration rt = ::std::chrono::duration_cast<clock_t::duration>(rtime);
154 
155  if (::std::ratio_greater<clock_t::period, Period>())
156  {
157  ++rt;
158  }
159 
160  ::std::chrono::nanoseconds ns = ::std::chrono::duration_cast< ::std::chrono::nanoseconds>(rt);
161  int e = ::rt_mutex_acquire(static_cast<Derived*>(this)->native_handle(), ::rt_timer_ns2ticks(ns.count()));
162 
163  switch (e)
164  {
165  case 0:
166  return true;
167  break;
168  case -ETIMEDOUT:
169  return false;
170  break;
171  default:
172  throw ::std::system_error(::std::error_code(-e, ::std::generic_category()));
173  break;
174  }
175  }
176 
177  template<typename Duration>
178  bool M_try_lock_until(const ::std::chrono::time_point<clock_t, Duration>& atime)
179  {
180  ::std::chrono::time_point<clock_t, ::std::chrono::nanoseconds> ns = ::std::chrono::time_point_cast< ::std::chrono::nanoseconds>(atime);
181  int e = ::rt_mutex_acquire_until(static_cast<Derived*>(this)->native_handle(), ::rt_timer_ns2ticks(ns.time_since_epoch().count()));
182 
183  switch (e)
184  {
185  case 0:
186  return true;
187  break;
188  case -ETIMEDOUT:
189  return false;
190  break;
191  default:
192  throw ::std::system_error(::std::error_code(-e, ::std::generic_category()));
193  break;
194  }
195  }
196 
197  template<typename Clock, typename Duration>
198  bool M_try_lock_until(const ::std::chrono::time_point<Clock, Duration>& atime)
199  {
200  Duration rtime = atime - Clock::now();
201  return this->M_try_lock_until(clock_t::now() + rtime);
202  }
203 
204  private:
205 
206  };
207 
208  class recursive_timed_mutex : private recursive_mutex_base, public timed_mutex_impl<recursive_timed_mutex>
209  {
210  public:
212 
214 
216 
218 
220 
221  void lock()
222  {
223  int e = ::rt_mutex_acquire(&this->M_mutex, TM_INFINITE);
224 
225  if (e)
226  {
227  throw ::std::system_error(::std::error_code(-e, ::std::generic_category()));
228  }
229  }
230 
232  {
233  return &this->M_mutex;
234  }
235 
236  bool try_lock()
237  {
238  int e = ::rt_mutex_acquire(&this->M_mutex, TM_NONBLOCK);
239 
240  switch (e)
241  {
242  case 0:
243  return true;
244  break;
245  case -EWOULDBLOCK:
246  return false;
247  break;
248  default:
249  throw ::std::system_error(::std::error_code(-e, ::std::generic_category()));
250  break;
251  }
252  }
253 
254  template <class Rep, class Period>
255  bool try_lock_for(const ::std::chrono::duration<Rep, Period>& rtime)
256  {
257  return this->M_try_lock_for(rtime);
258  }
259 
260  template <class Clock, class Duration>
261  bool try_lock_until(const ::std::chrono::time_point<Clock, Duration>& atime)
262  {
263  return this->M_try_lock_until(atime);
264  }
265 
266  void unlock()
267  {
268  int e = ::rt_mutex_release(&this->M_mutex);
269 
270  if (e)
271  {
272  throw ::std::system_error(::std::error_code(-e, ::std::generic_category()));
273  }
274  }
275 
276  protected:
277 
278  private:
279 
280  };
281  }
282  }
283 }
284 
285 #endif // RL_UTIL_XENOMAI_MUTEX_H
rl::util::xenomai::recursive_mutex
Definition: mutex.h:81
rl::util::xenomai::recursive_mutex_base::operator=
recursive_mutex_base & operator=(const recursive_mutex_base &)=delete
rl::util::xenomai::recursive_mutex_base::native_type
RT_MUTEX native_type
Definition: mutex.h:47
rl::util::xenomai::recursive_timed_mutex::native_handle
native_handle_type native_handle()
Definition: mutex.h:231
rl::util::xenomai::chrono::system_clock
Definition: chrono.h:62
rl::util::xenomai::recursive_timed_mutex
Definition: mutex.h:209
rl::util::xenomai::recursive_mutex::lock
void lock()
Definition: mutex.h:93
rl::util::xenomai::recursive_mutex::unlock
void unlock()
Definition: mutex.h:126
rl::util::xenomai::recursive_mutex::recursive_mutex
recursive_mutex()=default
rl::util::xenomai::chrono::system_clock::duration
::std::chrono::nanoseconds duration
Definition: chrono.h:63
rl::util::xenomai::recursive_timed_mutex::native_handle_type
native_type * native_handle_type
Definition: mutex.h:211
rl::util::xenomai::recursive_mutex::native_handle_type
native_type * native_handle_type
Definition: mutex.h:83
rl::util::xenomai::timed_mutex_impl::M_try_lock_until
bool M_try_lock_until(const ::std::chrono::time_point< Clock, Duration > &atime)
Definition: mutex.h:198
rl::util::xenomai::recursive_mutex_base::M_mutex
native_type M_mutex
Definition: mutex.h:74
rl::util::xenomai::recursive_mutex::recursive_mutex
recursive_mutex(const recursive_mutex &)=delete
rl::util::xenomai::recursive_timed_mutex::try_lock
bool try_lock()
Definition: mutex.h:236
rl::util::xenomai::recursive_timed_mutex::unlock
void unlock()
Definition: mutex.h:266
rl::util::xenomai::recursive_mutex::try_lock
bool try_lock()
Definition: mutex.h:108
rl::util::xenomai::timed_mutex_impl
Definition: mutex.h:144
rl::util::xenomai::recursive_mutex_base::recursive_mutex_base
recursive_mutex_base()
Definition: mutex.h:49
chrono.h
rl::util::xenomai::recursive_mutex::~recursive_mutex
~recursive_mutex()=default
rl::util::xenomai::recursive_timed_mutex::try_lock_for
bool try_lock_for(const ::std::chrono::duration< Rep, Period > &rtime)
Definition: mutex.h:255
rl::util::xenomai::timed_mutex_impl::M_try_lock_for
bool M_try_lock_for(const ::std::chrono::duration< Rep, Period > &rtime)
Definition: mutex.h:151
rl::util::xenomai::recursive_mutex_base
Definition: mutex.h:43
rl::util::xenomai::recursive_timed_mutex::lock
void lock()
Definition: mutex.h:221
rl::util::xenomai::recursive_timed_mutex::recursive_timed_mutex
recursive_timed_mutex()=default
rl::util::xenomai::timed_mutex_impl::clock_t
chrono::system_clock clock_t
Definition: mutex.h:148
rl::util::xenomai::timed_mutex_impl::M_try_lock_until
bool M_try_lock_until(const ::std::chrono::time_point< clock_t, Duration > &atime)
Definition: mutex.h:178
rl::util::xenomai::recursive_timed_mutex::operator=
recursive_timed_mutex & operator=(const recursive_timed_mutex &)=delete
rl::util::xenomai::recursive_mutex_base::~recursive_mutex_base
~recursive_mutex_base()
Definition: mutex.h:64
rl::util::xenomai::recursive_timed_mutex::recursive_timed_mutex
recursive_timed_mutex(const recursive_timed_mutex &)=delete
rl::util::xenomai::recursive_mutex::operator=
recursive_mutex & operator=(const recursive_mutex &)=delete
rl::util::xenomai::recursive_timed_mutex::try_lock_until
bool try_lock_until(const ::std::chrono::time_point< Clock, Duration > &atime)
Definition: mutex.h:261
rl::util::xenomai::recursive_mutex_base::recursive_mutex_base
recursive_mutex_base(const recursive_mutex_base &)=delete
rl::util::xenomai::recursive_timed_mutex::~recursive_timed_mutex
~recursive_timed_mutex()=default
rl::util::xenomai::recursive_mutex::native_handle
native_handle_type native_handle()
Definition: mutex.h:103
rl::util::xenomai::chrono::system_clock::now
static time_point now()
Definition: chrono.h:75
rl
Robotics Library.
Definition: AnalogInput.cpp:30