GCC Code Coverage Report


Directory: codebase/
File: codebase/system/include/private/sys.Thread.hpp
Date: 2023-03-16 04:37:09
Exec Total Coverage
Lines: 83 92 90.2%
Functions: 11 11 100.0%
Branches: 41 65 63.1%

Line Branch Exec Source
1 /**
2 * @file sys.Thread.hpp
3 * @author Sergey Baigudin, sergey@baigudin.software
4 * @copyright 2014-2022, Sergey Baigudin, Baigudin Software
5 */
6 #ifndef SYS_THREAD_HPP_
7 #define SYS_THREAD_HPP_
8
9 #include "sys.NonCopyable.hpp"
10 #include "api.Thread.hpp"
11 #include "api.Task.hpp"
12
13 namespace eoos
14 {
15 namespace sys
16 {
17
18 /**
19 * @class Thread
20 * @brief Thread class.
21 */
22 class Thread : public NonCopyable, public api::Thread
23 {
24 typedef NonCopyable Parent;
25
26 public:
27
28 /**
29 * @brief Constructor of not constructed object.
30 *
31 * @param task A task interface whose main method is invoked when this thread is started.
32 */
33 31 Thread(api::Task& task)
34 31 : NonCopyable()
35 , api::Thread()
36 31 , task_ (&task)
37 31 , status_ (STATUS_NEW)
38 31 , priority_ (PRIORITY_NORM)
39 31 , thread_ (0) {
40
1/2
✓ Branch 1 taken 31 times.
✗ Branch 2 not taken.
31 bool_t const isConstructed( construct() );
41 31 setConstructed( isConstructed );
42 31 }
43
44 /**
45 * @brief Destructor.
46 */
47 124 virtual ~Thread()
48 {
49
2/2
✓ Branch 0 taken 10 times.
✓ Branch 1 taken 21 times.
62 if( thread_ != 0U )
50 {
51 // @todo The thread detaching means the thread will still be executed by OS.
52 // Thus, to keep compatibility, common approach for all OSs shall be found
53 // for using pthread_cancel function to cancel the thread execution forcely.
54 20 static_cast<void>( ::pthread_detach(thread_) );
55 20 status_ = STATUS_DEAD;
56 }
57
2/3
✓ Branch 1 taken 31 times.
✓ Branch 2 taken 31 times.
✗ Branch 3 not taken.
124 }
58
59 /**
60 * @copydoc eoos::api::Object::isConstructed()
61 */
62 136 virtual bool_t isConstructed() const ///< SCA MISRA-C++:2008 Justified Rule 10-3-1
63 {
64 136 return Parent::isConstructed();
65 }
66
67 /**
68 * @copydoc eoos::api::Thread::execute()
69 */
70 11 virtual bool_t execute()
71 {
72 11 bool_t res( false );
73 do{
74
2/4
✓ Branch 1 taken 11 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 11 times.
11 if( !isConstructed() )
75 {
76 1 break;
77 }
78
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 10 times.
11 if( status_ != STATUS_NEW )
79 {
80 1 break;
81 }
82 10 int_t error( 0 );
83 10 PthreadAttr pthreadAttr; ///< SCA MISRA-C++:2008 Justified Rule 9-5-1
84
1/2
✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
10 size_t const stackSize( task_->getStackSize() );
85
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 9 times.
10 if(stackSize != 0U)
86 {
87 1 error = ::pthread_attr_setstacksize(&pthreadAttr.attr, stackSize);
88
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if(error != 0)
89 { ///< UT Justified Branch: OS dependency
90 break;
91 }
92 }
93 10 error = ::pthread_create(&thread_, &pthreadAttr.attr, &start, &task_);
94
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 10 times.
10 if(error != 0)
95 { ///< UT Justified Branch: OS dependency
96 break;
97 }
98 10 status_ = STATUS_RUNNABLE;
99 10 res = true;
100
1/2
✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
10 } while(false);
101 11 return res;
102 }
103
104 /**
105 * @copydoc eoos::api::Thread::join()
106 */
107 10 virtual bool_t join()
108 {
109 10 bool_t res( false );
110
3/6
✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 10 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 10 times.
✗ Branch 6 not taken.
10 if( isConstructed() && (status_ == STATUS_RUNNABLE) )
111 {
112 10 int_t const error( ::pthread_join(thread_, NULL) );
113 10 res = (error == 0) ? true : false;
114 10 status_ = STATUS_DEAD;
115 }
116 10 return res;
117
118 }
119
120 /**
121 * @copydoc eoos::api::Thread::getPriority()
122 */
123 14 virtual int32_t getPriority() const
124 {
125
1/2
✓ Branch 1 taken 14 times.
✗ Branch 2 not taken.
14 return isConstructed() ? priority_ : PRIORITY_WRONG;
126 }
127
128 /**
129 * @copydoc eoos::api::Thread::setPriority(int32_t)
130 */
131 13 virtual bool_t setPriority(int32_t priority)
132 {
133 13 bool_t res( false );
134
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
13 if( isConstructed() )
135 {
136
4/4
✓ Branch 0 taken 11 times.
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 10 times.
✓ Branch 3 taken 1 times.
13 if( (PRIORITY_MIN <= priority) && (priority <= PRIORITY_MAX) )
137 {
138 10 priority_ = priority;
139 10 res = true;
140 }
141
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 2 times.
3 else if (priority == PRIORITY_LOCK)
142 {
143 1 priority_ = priority;
144 1 res = true;
145 }
146 else
147 {
148 2 res = false;
149 }
150 }
151 // @todo Implemet setting priority on system level regarding common API rage
152 13 return res;
153 }
154
155 private:
156
157 /**
158 * @brief Constructor.
159 *
160 * @return True if object has been constructed successfully.
161 */
162 31 bool_t construct()
163 {
164 31 bool_t res( false );
165 do
166 {
167
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 31 times.
31 if( !isConstructed() )
168 { ///< UT Justified Branch: HW dependency
169 break;
170 }
171
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 31 times.
31 if( task_ == NULLPTR )
172 { ///< UT Justified Branch: SW dependency
173 break;
174 }
175
2/2
✓ Branch 1 taken 5 times.
✓ Branch 2 taken 26 times.
31 if( !task_->isConstructed() )
176 {
177 5 break;
178 }
179 26 status_ = STATUS_NEW;
180 26 res = true;
181 } while(false);
182
2/2
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 26 times.
31 if( res == false )
183 {
184 5 status_ = STATUS_DEAD;
185 }
186 31 return res;
187 }
188
189 /**
190 * @brief Starts a thread routine.
191 *
192 * @param argument Pointer to arguments passed by the POSIX pthread_create function.
193 */
194 10 static void* start(void* argument)
195 {
196
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 10 times.
10 if(argument == NULLPTR)
197 { ///< UT Justified Branch: SW dependency
198 return NULLPTR;
199 }
200 10 api::Task* const task( *reinterpret_cast<api::Task**>(argument) ); ///< SCA MISRA-C++:2008 Justified Rule 5-2-8
201
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 10 times.
10 if(task == NULLPTR)
202 { ///< UT Justified Branch: HW dependency
203 return NULLPTR;
204 }
205
2/4
✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 4 taken 10 times.
10 if( !task->isConstructed() )
206 { ///< UT Justified Branch: HW dependency
207 return NULLPTR;
208 }
209 int_t oldtype;
210 // The thread is cancelable. This is the default
211 // cancelability state in all new threads, including the
212 // initial thread. The thread's cancelability type
213 // determines when a cancelable thread will respond to a
214 // cancellation request.
215
1/2
✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
10 int_t error( ::pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &oldtype) );
216
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 10 times.
10 if(error != 0)
217 { ///< UT Justified Branch: OS dependency
218 return NULLPTR;
219 }
220 // The thread can be canceled at any time. Typically, it
221 // will be canceled immediately upon receiving a cancellation
222 // request, but the system doesn't guarantee this.
223
1/2
✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
10 error = ::pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &oldtype);
224
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 10 times.
10 if(error != 0)
225 { ///< UT Justified Branch: OS dependency
226 return NULLPTR;
227 }
228
1/2
✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
10 task->start();
229 10 return NULLPTR;
230 }
231
232 /**
233 * @struct The pthread attr container for the pthread_create function
234 * @brief The struct implements RAII approach on pthread_attr_t.
235 */
236 struct PthreadAttr
237 {
238 /**
239 * @brief Attributes of the pthread_create function.
240 */
241 ::pthread_attr_t attr; ///< SCA MISRA-C++:2008 Justified Rule 9-5-1 and Rule 11-0-1
242
243 /**
244 * @brief Constructor of not constructed object.
245 */
246 10 PthreadAttr()
247 10 {
248 10 static_cast<void>( ::pthread_attr_init(&attr) );
249 10 }
250
251 /**
252 * @brief Destructor.
253 */
254 10 ~PthreadAttr()
255 {
256 10 static_cast<void>( ::pthread_attr_destroy(&attr) );
257 10 }
258 };
259
260 /**
261 * @brief User executing runnable interface.
262 */
263 api::Task* task_;
264
265 /**
266 * @brief Current status.
267 */
268 Status status_;
269
270 /**
271 * @brief This thread priority.
272 */
273 int32_t priority_;
274
275 /**
276 * @brief The new thread resource identifier.
277 */
278 ::pthread_t thread_;
279
280 };
281
282 } // namespace sys
283 } // namespace eoos
284 #endif // SYS_THREAD_HPP_
285