µOS++ IIIe Reference  v6.3.15
“Perfekt ist nicht gut genug”
The third edition of µOS++, a POSIX inspired open source system, written in C++.
os-mutex.h
Go to the documentation of this file.
1 /*
2  * This file is part of the µOS++ distribution.
3  * (https://github.com/micro-os-plus)
4  * Copyright (c) 2016 Liviu Ionescu.
5  *
6  * Permission is hereby granted, free of charge, to any person
7  * obtaining a copy of this software and associated documentation
8  * files (the "Software"), to deal in the Software without
9  * restriction, including without limitation the rights to use,
10  * copy, modify, merge, publish, distribute, sublicense, and/or
11  * sell copies of the Software, and to permit persons to whom
12  * the Software is furnished to do so, subject to the following
13  * conditions:
14  *
15  * The above copyright notice and this permission notice shall be
16  * included in all copies or substantial portions of the Software.
17  *
18  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
20  * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
21  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
22  * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
23  * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
24  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
25  * OTHER DEALINGS IN THE SOFTWARE.
26  */
27 
28 #ifndef CMSIS_PLUS_RTOS_OS_MUTEX_H_
29 #define CMSIS_PLUS_RTOS_OS_MUTEX_H_
30 
31 // ----------------------------------------------------------------------------
32 
33 #if defined(__cplusplus)
34 
36 
37 // ----------------------------------------------------------------------------
38 
39 namespace os
40 {
41  namespace rtos
42  {
43  // ========================================================================
44 
45 #pragma GCC diagnostic push
46 #pragma GCC diagnostic ignored "-Wpadded"
47 
54  {
55  public:
56 
61  using protocol_t = uint8_t;
62 
68  struct protocol
69  {
73  enum
74  : protocol_t
75  {
79  none = 0,
80 
84  inherit = 1,
85 
89  protect = 2,
90 
95 
100  };
101  };
102 
107  using robustness_t = uint8_t;
108 
114  struct robustness
115  {
119  enum
120  : robustness_t
121  {
125  stalled = 0,
126 
130  robust = 1,
131 
135  default_ = stalled,
136 
140  max_ = robust,
141  };
142  };
143 
148  using type_t = uint8_t;
149 
155  struct type
156  {
160  enum
161  : type_t
162  {
166  normal = 0,
170  errorcheck = 1,
174  recursive = 2,
175 
179  default_ = normal,
180 
184  max_ = recursive,
185  };
186  };
187 
192  using count_t = uint16_t;
193 
198  static constexpr count_t max_count = 0xFFFF;
199 
200  // ======================================================================
201 
208  {
209  public:
210 
221  constexpr
222  attributes ();
223 
224  protected:
225 
230  constexpr
231  attributes (type_t type);
232 
237  public:
238 
239  // The rule of five.
240  attributes (const attributes&) = default;
241  attributes (attributes&&) = default;
242  attributes&
243  operator= (const attributes&) = default;
244  attributes&
245  operator= (attributes&&) = default;
246 
250  ~attributes () = default;
251 
256  public:
257 
263  // Public members; no accessors and mutators required.
264  // Warning: must match the type & order of the C file header.
269 
274 
279 
284 
288  count_t mx_max_count = max_count;
289 
290  // Add more attributes here.
291 
296  }; /* class attributes */
297 
303 
304  // ======================================================================
305 
312  {
313  public:
314 
325  constexpr
327 
328  // The rule of five.
329  attributes_recursive (const attributes_recursive&) = default;
330  attributes_recursive (attributes_recursive&&) = default;
331  attributes_recursive&
332  operator= (const attributes_recursive&) = default;
333  attributes_recursive&
334  operator= (attributes_recursive&&) = default;
335 
339  ~attributes_recursive () = default;
340 
345  }; /* class attributes_recursive */
346 
352 
362  mutex (const attributes& attr = initializer_normal);
363 
369  mutex (const char* name, const attributes& attr = initializer_normal);
370 
375  // The rule of five.
376  mutex (const mutex&) = delete;
377  mutex (mutex&&) = delete;
378  mutex&
379  operator= (const mutex&) = delete;
380  mutex&
381  operator= (mutex&&) = delete;
382 
390  ~mutex ();
391 
406  bool
407  operator== (const mutex& rhs) const;
408 
413  public:
414 
441  result_t
442  lock (void);
443 
467  result_t
468  try_lock (void);
469 
491  result_t
492  timed_lock (clock::duration_t timeout);
493 
506  result_t
507  unlock (void);
508 
516  prio_ceiling (void) const;
517 
540  result_t
542  thread::priority_t* old_prio_ceiling = nullptr);
543 
553  result_t
554  consistent (void);
555 
562  thread*
563  owner (void);
564 
569  type_t
570  type (void);
571 
576  protocol_t
577  protocol (void);
578 
584  robustness (void);
585 
592  result_t
593  reset (void);
594 
599  protected:
600 
601  friend class thread;
602 
617  void
618  internal_init_ (void);
619 
626  result_t
627  internal_try_lock_ (thread* th);
628 
634  result_t
635  internal_unlock_ (thread* th);
636 
637  void
638  internal_mark_owner_dead_ (void);
639 
648  protected:
649 
659  // Can be updated in different thread contexts.
660  thread* volatile owner_ = nullptr;
661 
662 #if !defined(OS_USE_RTOS_PORT_MUTEX)
664  clock* clock_ = nullptr;
665 #endif
666 
667  public:
668 
669  // Intrusive node used to link this mutex to the owning thread.
670  // This is used for priority inheritance and robustness.
671  utils::double_list_links owner_links_;
672 
673  protected:
674 
675 #if defined(OS_USE_RTOS_PORT_MUTEX)
676  friend class port::mutex;
677  os_mutex_port_data_t port_;
678 #endif
679 
680  // Can be updated in different thread contexts.
681  volatile count_t count_ = 0;
682 
683  // Can be updated in different thread contexts.
684  volatile thread::priority_t initial_prio_ceiling_ =
686  volatile thread::priority_t prio_ceiling_ = thread::priority::highest;
687  volatile thread::priority_t boosted_prio_ = thread::priority::none;
688 
689  bool owner_dead_ = false;
690  bool consistent_ = true;
691  bool recoverable_ = true;
692 
693  // Constants set during construction.
694  const type_t type_; // normal, errorcheck, recursive
695  const protocol_t protocol_; // none, inherit, protect
696  const robustness_t robustness_; // stalled, robust
697  const count_t max_count_;
698 
699  // Add more internal data.
700 
709  };
710 
716  class mutex_recursive : public mutex
717  {
718  public:
719 
729 
733  mutex_recursive (const char* name, const attributes& attr =
735 
740  // The rule of five.
741  mutex_recursive (const mutex_recursive&) = delete;
742  mutex_recursive (mutex_recursive&&) = delete;
744  operator= (const mutex_recursive&) = delete;
746  operator= (mutex_recursive&&) = delete;
747 
755  ~mutex_recursive ();
756 
771  bool
772  operator== (const mutex_recursive& rhs) const;
773 
778  };
779 
780 #pragma GCC diagnostic pop
781 
782  // ==========================================================================
783 
784  } /* namespace rtos */
785 } /* namespace os */
786 
787 // ===== Inline & template implementations ====================================
788 
789 namespace os
790 {
791  namespace rtos
792  {
793 
794  // ========================================================================
795 
796  constexpr
798  {
799  ;
800  }
801 
806  constexpr
808  mx_type (type)
809  {
810  ;
811  }
812 
817  // ========================================================================
818  constexpr
820  attributes
821  { type::recursive } // Use the protected constructor.
822  {
823  ;
824  }
825 
826  // ========================================================================
827 
832  inline bool
833  mutex::operator== (const mutex& rhs) const
834  {
835  return this == &rhs;
836  }
837 
843  inline thread*
845  {
846  return owner_;
847  }
848 
854  inline mutex::type_t
855  mutex::type (void)
856  {
857  return type_;
858  }
859 
865  inline mutex::protocol_t
867  {
868  return protocol_;
869  }
870 
876  inline mutex::robustness_t
878  {
879  return robustness_;
880  }
881 
882  // ========================================================================
883 
884  inline
886  mutex
887  { attr }
888  {
889  ;
890  }
891 
892  inline
893  mutex_recursive::mutex_recursive (const char* name, const attributes& attr) :
894  mutex
895  { name, attr }
896  {
897  ;
898  }
899 
900  inline
902  {
903  ;
904  }
905 
910  inline bool
912  {
913  return this == &rhs;
914  }
915 
916  } /* namespace rtos */
917 } /* namespace os */
918 
919 // ----------------------------------------------------------------------------
920 
921 #endif /* __cplusplus */
922 
923 #endif /* CMSIS_PLUS_RTOS_OS_MUTEX_H_ */
result_t reset(void)
Reset the mutex.
Definition: os-mutex.cpp:1454
type_t type(void)
Get the mutex type.
Definition: os-mutex.h:855
Default value. Differs from POSIX, which uses none.
Definition: os-mutex.h:94
static const attributes initializer_normal
Default normal mutex initialiser.
Definition: os-mutex.h:302
uint8_t protocol_t
Type of variables holding mutex protocols.
Definition: os-mutex.h:61
Priority ordered list of threads.
Definition: os-lists.h:536
POSIX compliant mutex.
Definition: os-mutex.h:53
thread::priority_t prio_ceiling(void) const
Get the priority ceiling of a mutex.
Definition: os-mutex.cpp:1310
result_t timed_lock(clock::duration_t timeout)
Timed attempt to lock/acquire the mutex.
Definition: os-mutex.cpp:1115
uint8_t type_t
Type of variables holding mutex behaviours.
Definition: os-mutex.h:148
bool operator==(const mutex_recursive &rhs) const
Compare mutexes.
Definition: os-mutex.h:911
mutex(const attributes &attr=initializer_normal)
Construct a mutex object instance.
Definition: os-mutex.cpp:431
Base class for attributes.
Definition: os-decls.h:562
uint8_t robustness_t
Type of variables holding mutex robustness.
Definition: os-mutex.h:107
System namespace.
uint16_t count_t
Type of variables holding mutex recursion counters.
Definition: os-mutex.h:192
static constexpr count_t max_count
Constant with the maximum value for the recursion counter.
Definition: os-mutex.h:198
robustness_t robustness(void)
Get the mutex robustness.
Definition: os-mutex.h:877
result_t unlock(void)
Unlock/release the mutex.
Definition: os-mutex.cpp:1275
const char * name(void) const
Get object name.
Definition: os-decls.h:760
Inherit priority from highest priority thread.
Definition: os-mutex.h:84
Base class for named system objects.
Definition: os-decls.h:444
uint8_t priority_t
Type of variables holding thread priorities.
Definition: os-thread.h:252
protocol_t protocol(void)
Get the mutex protocol.
Definition: os-mutex.h:866
bool operator==(const mutex &rhs) const
Compare mutexes.
Definition: os-mutex.h:833
POSIX compliant thread, using the default RTOS allocator.
Definition: os-thread.h:230
port::clock::duration_t duration_t
Type of variables holding clock durations.
Definition: os-clocks.h:72
thread * owner(void)
Get the thread that owns the mutex.
Definition: os-mutex.h:844
Maximum value, for validation purposes.
Definition: os-mutex.h:99
constexpr attributes()
Construct a mutex attributes object instance.
Definition: os-mutex.h:797
~mutex()
Destruct the mutex object instance.
Definition: os-mutex.cpp:525
Mutex robustness.
Definition: os-mutex.h:114
~mutex_recursive()
Destruct the recursive mutex object instance.
Definition: os-mutex.h:901
static const attributes_recursive initializer_recursive
Default recursive mutex initialiser.
Definition: os-mutex.h:351
result_t consistent(void)
Mark mutex as consistent.
Definition: os-mutex.cpp:1417
Recursive mutex attributes.
Definition: os-mutex.h:311
result_t try_lock(void)
Try to lock/acquire the mutex.
Definition: os-mutex.cpp:1039
Mutex protocols.
Definition: os-mutex.h:68
result_t lock(void)
Lock/acquire the mutex.
Definition: os-mutex.cpp:918
Generic clock.
Definition: os-clocks.h:54
POSIX compliant recursive mutex.
Definition: os-mutex.h:716
uint32_t result_t
Type of values returned by RTOS functions.
Definition: os-decls.h:96
constexpr attributes_recursive()
Construct a recursive mutex attributes object instance.
Definition: os-mutex.h:819
Recursive mutex behaviour.
Definition: os-mutex.h:174
Priority and scheduling not affected by mutex ownership.
Definition: os-mutex.h:79
Mutex types.
Definition: os-mutex.h:155
Execute at the highest priority.
Definition: os-mutex.h:89
Mutex attributes.
Definition: os-mutex.h:207
mutex_recursive(const attributes &attr=initializer_recursive)
Construct a recursive mutex object instance.
Definition: os-mutex.h:885