Embedded Multicore Building Blocks V1.0.0
mutex.h
1 /*
2  * Copyright (c) 2014-2017, Siemens AG. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are met:
6  *
7  * 1. Redistributions of source code must retain the above copyright notice,
8  * this list of conditions and the following disclaimer.
9  *
10  * 2. 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 EMBB_BASE_MUTEX_H_
28 #define EMBB_BASE_MUTEX_H_
29 
30 #include <embb/base/internal/platform.h>
31 #include <embb/base/exceptions.h>
32 #include <embb/base/c/mutex.h>
33 
34 namespace embb {
35 namespace base {
100 class ConditionVariable;
101 
102 namespace internal {
106 class MutexBase {
107  public:
113  explicit MutexBase(
114  int mutex_type
116  );
117 
121  virtual ~MutexBase() = 0;
122 
132  void Lock();
133 
142  bool TryLock();
143 
153  void Unlock();
154 
155  private:
159  internal::MutexType mutex_;
160 
164  friend class embb::base::ConditionVariable;
165 };
166 } // namespace internal
167 
175 class Spinlock {
176  public:
182  Spinlock();
183 
189  ~Spinlock();
190 
202  void Lock();
203 
213  bool TryLock(
214  unsigned int number_spins = 1
219  );
220 
229  void Unlock();
230 
231  private:
235  Spinlock(const Spinlock&);
236  Spinlock& operator=(const Spinlock&);
237 
241  embb_spinlock_t spinlock_;
242 };
243 
256 class Mutex : public internal::MutexBase {
257  public:
264  Mutex();
265 
266 #ifdef DOXYGEN
267 
276  void Lock();
277 
287  bool TryLock();
288 
297  void Unlock();
298 
299 #endif // DOXYGEN
300 
301  private:
305  Mutex(const Mutex&);
306  Mutex& operator=(const Mutex&);
307 
311  friend class ConditionVariable;
312 };
313 
327 class RecursiveMutex : public internal::MutexBase {
328  public:
335  RecursiveMutex();
336 
337 #ifdef DOXYGEN
338 
346  void Lock();
347 
356  bool TryLock();
357 
367  void Unlock();
368 
369 #endif // DOXYGEN
370 
371  private:
376  RecursiveMutex& operator=(const RecursiveMutex&);
377 };
378 
391 template<typename Mutex = embb::base::Mutex>
392 class LockGuard {
393  public:
400  explicit LockGuard(
401  Mutex& mutex
403  ) : mutex_(mutex) {
404  mutex_.Lock();
405  }
406 
411  mutex_.Unlock();
412  }
413 
414  private:
418  Mutex& mutex_;
419 
423  LockGuard(const LockGuard<Mutex>&);
424  LockGuard<Mutex>& operator=(const LockGuard<Mutex>&);
425 };
426 
437 struct DeferLockTag {};
438 
445 
451 struct TryLockTag {};
452 
459 
465 struct AdoptLockTag {};
466 
473 
490 template<typename Mutex = embb::base::Mutex>
491 class UniqueLock {
492  public:
498  UniqueLock();
499 
505  explicit UniqueLock(
506  Mutex& mutex
508  );
509 
515  UniqueLock(
516  Mutex& mutex,
520  );
521 
527  UniqueLock(
528  Mutex& mutex,
530  TryLockTag
532  );
533 
539  UniqueLock(
540  Mutex& mutex,
544  );
545 
549  ~UniqueLock();
550 
556  void Lock();
557 
564  bool TryLock();
565 
571  void Unlock();
572 
576  void Swap(
577  UniqueLock<Mutex>& other
579  );
580 
586  Mutex* Release();
587 
593  bool OwnsLock() const;
594 
595  private:
599  Mutex* mutex_;
600 
604  bool locked_;
605 
610  UniqueLock<Mutex>& operator=(const UniqueLock<Mutex>&);
611 
616 };
617 } // namespace base
618 } // namespace embb
619 
620 #include <embb/base/internal/mutex-inl.h>
621 
622 #endif // EMBB_BASE_MUTEX_H_
Definition: lock_free_mpmc_queue.h:40
Scoped lock (according to the RAII principle) using a mutex.
Definition: mutex.h:392
opaque_type embb_spinlock_t
Opaque type representing a spinlock.
Definition: mutex.h:60
const DeferLockTag defer_lock
Tag variable for deferred UniqueLock construction.
Definition: mutex.h:444
Tag type for try-lock UniqueLock construction.
Definition: mutex.h:451
Tag type for deferred UniqueLock construction.
Definition: mutex.h:437
~LockGuard()
Unlocks the mutex.
Definition: mutex.h:410
LockGuard(Mutex &mutex)
Creates the lock and locks the mutex.
Definition: mutex.h:400
const TryLockTag try_lock
Tag variable for try-lock UniqueLock construction.
Definition: mutex.h:458
Tag type for adopt UniqueLock constructor.
Definition: mutex.h:465
Represents a condition variable for thread synchronization.
Definition: condition_variable.h:56
const AdoptLockTag adopt_lock
Tag variable for adopt UniqueLock construction.
Definition: mutex.h:472
Spinlock.
Definition: mutex.h:175
Non-recursive, exclusive mutex.
Definition: mutex.h:256
Recursive, exclusive mutex.
Definition: mutex.h:327
Flexible ownership wrapper for a mutex.
Definition: mutex.h:491