Line | Branch | Exec | Source |
---|---|---|---|
1 | /** | ||
2 | * @file sys.Semaphore.hpp | ||
3 | * @author Sergey Baigudin, sergey@baigudin.software | ||
4 | * @copyright 2017-2022, Sergey Baigudin, Baigudin Software | ||
5 | */ | ||
6 | #ifndef SYS_SEMAPHORE_HPP_ | ||
7 | #define SYS_SEMAPHORE_HPP_ | ||
8 | |||
9 | #include "sys.NonCopyable.hpp" | ||
10 | #include "api.Semaphore.hpp" | ||
11 | |||
12 | namespace eoos | ||
13 | { | ||
14 | namespace sys | ||
15 | { | ||
16 | |||
17 | /** | ||
18 | * @class Semaphore | ||
19 | * @brief Semaphore class. | ||
20 | */ | ||
21 | class Semaphore : public NonCopyable, public api::Semaphore | ||
22 | { | ||
23 | typedef NonCopyable Parent; | ||
24 | |||
25 | public: | ||
26 | |||
27 | /** | ||
28 | * @brief Constructor. | ||
29 | * | ||
30 | * @param permits The initial number of permits available. | ||
31 | */ | ||
32 | 8 | explicit Semaphore(int32_t permits) | |
33 | 8 | : NonCopyable() | |
34 | , api::Semaphore() | ||
35 | 8 | , isFair_(false) | |
36 | 8 | , permits_(permits) | |
37 | 8 | , sem_(){ | |
38 |
1/2✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
|
8 | bool_t const isConstructed( construct() ); |
39 | 8 | setConstructed( isConstructed ); | |
40 | 8 | } | |
41 | |||
42 | /** | ||
43 | * @brief Destructor. | ||
44 | */ | ||
45 | 32 | virtual ~Semaphore() | |
46 | { | ||
47 | 16 | destruct(); | |
48 |
2/3✓ Branch 1 taken 8 times.
✓ Branch 2 taken 8 times.
✗ Branch 3 not taken.
|
32 | } |
49 | |||
50 | /** | ||
51 | * @copydoc eoos::api::Object::isConstructed() | ||
52 | */ | ||
53 | 26 | virtual bool_t isConstructed() const ///< SCA MISRA-C++:2008 Justified Rule 10-3-1 | |
54 | { | ||
55 | 26 | return Parent::isConstructed(); | |
56 | } | ||
57 | |||
58 | /** | ||
59 | * @copydoc eoos::api::Semaphore::acquire() | ||
60 | */ | ||
61 | 2 | virtual bool_t acquire() | |
62 | { | ||
63 | 2 | bool_t res( false ); | |
64 |
1/2✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
|
2 | if( isConstructed() ) |
65 | { | ||
66 | 2 | int_t const error( ::sem_wait(&sem_) ); | |
67 |
1/2✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
|
2 | if(error == 0) |
68 | { | ||
69 | 2 | res = true; | |
70 | } | ||
71 | } | ||
72 | 2 | return res; | |
73 | } | ||
74 | |||
75 | /** | ||
76 | * @copydoc eoos::api::Semaphore::release() | ||
77 | */ | ||
78 | 2 | virtual void release() | |
79 | { | ||
80 |
1/2✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
|
2 | if( isConstructed() ) |
81 | { | ||
82 | 2 | bool_t const isPosted( post() ); | |
83 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
|
2 | if ( !isPosted ) |
84 | { ///< UT Justified Branch: OS dependency | ||
85 | ✗ | setConstructed(false); | |
86 | } | ||
87 | } | ||
88 | 2 | } | |
89 | |||
90 | private: | ||
91 | |||
92 | /** | ||
93 | * @brief Constructs this object. | ||
94 | * | ||
95 | * @return true if object has been constructed successfully. | ||
96 | */ | ||
97 | 8 | bool_t construct() | |
98 | { | ||
99 | 8 | bool_t res( false ); | |
100 | do { | ||
101 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 8 times.
|
8 | if( !isConstructed() ) |
102 | { ///< UT Justified Branch: HW dependency | ||
103 | ✗ | break; | |
104 | } | ||
105 | 8 | int_t const error( ::sem_init(&sem_, 0, static_cast<uint_t >(permits_)) ); | |
106 |
2/2✓ Branch 0 taken 2 times.
✓ Branch 1 taken 6 times.
|
8 | if(error != 0) |
107 | { | ||
108 | 2 | break; | |
109 | } | ||
110 | 6 | isFair_ = isFair(); | |
111 | 6 | res = true; | |
112 | } while(false); | ||
113 | 8 | return res; | |
114 | } | ||
115 | |||
116 | /** | ||
117 | * @brief Destructs this object. | ||
118 | */ | ||
119 | 8 | void destruct() | |
120 | { | ||
121 | 8 | static_cast<void>( ::sem_destroy(&sem_) ); | |
122 | 8 | } | |
123 | |||
124 | /** | ||
125 | * @brief Test if semaphore is fair. | ||
126 | * | ||
127 | * @return Fairness flag. | ||
128 | */ | ||
129 | 6 | static bool_t isFair() | |
130 | { | ||
131 | 6 | int_t const priority( ::sched_getscheduler(0) ); | |
132 |
2/4✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 6 times.
|
6 | return ( (priority == SCHED_FIFO) || (priority == SCHED_RR) ) ? true : false; ///< SCA MISRA-C++:2008 Justified Rule 16-2-2 |
133 | } | ||
134 | |||
135 | /** | ||
136 | * @brief Releases one permit. | ||
137 | * | ||
138 | * @return True on success. | ||
139 | */ | ||
140 | 2 | bool_t post() | |
141 | { | ||
142 | 2 | bool_t res( true ); | |
143 | 2 | int_t const error( ::sem_post(&sem_) ); | |
144 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
|
2 | if (error != 0) |
145 | { ///< UT Justified Branch: OS dependency | ||
146 | ✗ | res = false; | |
147 | } | ||
148 | 2 | return res; | |
149 | } | ||
150 | |||
151 | /** | ||
152 | * @brief Fairness flag. | ||
153 | */ | ||
154 | bool_t isFair_; | ||
155 | |||
156 | /** | ||
157 | * @brief Number of permits available. | ||
158 | */ | ||
159 | int32_t permits_; | ||
160 | |||
161 | /** | ||
162 | * @brief Semaphore resource identifier. | ||
163 | */ | ||
164 | ::sem_t sem_; | ||
165 | |||
166 | }; | ||
167 | |||
168 | } // namespace sys | ||
169 | } // namespace eoos | ||
170 | #endif // SYS_SEMAPHORE_HPP_ | ||
171 |