WPILibC++  2020.3.2-60-g3011ebe
priority_mutex.h
1 /*----------------------------------------------------------------------------*/
2 /* Copyright (c) 2016-2019 FIRST. All Rights Reserved. */
3 /* Open Source Software - may be modified and shared by FRC teams. The code */
4 /* must be accompanied by the FIRST BSD license file in the root directory of */
5 /* the project. */
6 /*----------------------------------------------------------------------------*/
7 
8 #pragma once
9 
10 // Allows usage with std::scoped_lock without including <mutex> separately
11 #ifdef __linux__
12 #include <pthread.h>
13 #endif
14 
15 #include <mutex>
16 
17 namespace wpi {
18 
19 #if defined(__FRC_ROBORIO__) && !defined(WPI_USE_PRIORITY_MUTEX)
20 #define WPI_USE_PRIORITY_MUTEX
21 #endif
22 
23 #if defined(WPI_USE_PRIORITY_MUTEX) && defined(__linux__)
24 
25 #define WPI_HAVE_PRIORITY_MUTEX 1
26 
27 class priority_recursive_mutex {
28  public:
29  using native_handle_type = pthread_mutex_t*;
30 
31  constexpr priority_recursive_mutex() noexcept = default;
32  priority_recursive_mutex(const priority_recursive_mutex&) = delete;
33  priority_recursive_mutex& operator=(const priority_recursive_mutex&) = delete;
34 
35  // Lock the mutex, blocking until it's available.
36  void lock() { pthread_mutex_lock(&m_mutex); }
37 
38  // Unlock the mutex.
39  void unlock() { pthread_mutex_unlock(&m_mutex); }
40 
41  // Tries to lock the mutex.
42  bool try_lock() noexcept { return !pthread_mutex_trylock(&m_mutex); }
43 
44  pthread_mutex_t* native_handle() { return &m_mutex; }
45 
46  private:
47 // Do the equivalent of setting PTHREAD_PRIO_INHERIT and
48 // PTHREAD_MUTEX_RECURSIVE_NP.
49 #ifdef __PTHREAD_MUTEX_HAVE_PREV
50  pthread_mutex_t m_mutex = {
51  {0, 0, 0, 0, 0x20 | PTHREAD_MUTEX_RECURSIVE_NP, __PTHREAD_SPINS, {0, 0}}};
52 #else
53  pthread_mutex_t m_mutex = {
54  {0, 0, 0, 0x20 | PTHREAD_MUTEX_RECURSIVE_NP, 0, {__PTHREAD_SPINS}}};
55 #endif
56 };
57 
58 class priority_mutex {
59  public:
60  using native_handle_type = pthread_mutex_t*;
61 
62  constexpr priority_mutex() noexcept = default;
63  priority_mutex(const priority_mutex&) = delete;
64  priority_mutex& operator=(const priority_mutex&) = delete;
65 
66  // Lock the mutex, blocking until it's available.
67  void lock() { pthread_mutex_lock(&m_mutex); }
68 
69  // Unlock the mutex.
70  void unlock() { pthread_mutex_unlock(&m_mutex); }
71 
72  // Tries to lock the mutex.
73  bool try_lock() noexcept { return !pthread_mutex_trylock(&m_mutex); }
74 
75  pthread_mutex_t* native_handle() { return &m_mutex; }
76 
77  private:
78 // Do the equivalent of setting PTHREAD_PRIO_INHERIT.
79 #ifdef __PTHREAD_MUTEX_HAVE_PREV
80  pthread_mutex_t m_mutex = {{0, 0, 0, 0, 0x20, __PTHREAD_SPINS, {0, 0}}};
81 #else
82  pthread_mutex_t m_mutex = {{0, 0, 0, 0x20, 0, {__PTHREAD_SPINS}}};
83 #endif
84 };
85 
86 #endif // defined(WPI_USE_PRIORITY_MUTEX) && defined(__linux__)
87 
88 } // namespace wpi
wpi
WPILib C++ utilities (wpiutil) namespace.
Definition: Endian.h:31