Line | Branch | Exec | Source |
---|---|---|---|
1 | /** | ||
2 | * @file lib.Thread.hpp | ||
3 | * @author Sergey Baigudin, sergey@baigudin.software | ||
4 | * @copyright 2014-2022, Sergey Baigudin, Baigudin Software | ||
5 | */ | ||
6 | #ifndef LIB_THREAD_HPP_ | ||
7 | #define LIB_THREAD_HPP_ | ||
8 | |||
9 | #include "lib.NonCopyable.hpp" | ||
10 | #include "api.Thread.hpp" | ||
11 | #include "sys.Call.hpp" | ||
12 | |||
13 | namespace eoos | ||
14 | { | ||
15 | namespace lib | ||
16 | { | ||
17 | |||
18 | /** | ||
19 | * @class Thread<A> | ||
20 | * @brief Thread class. | ||
21 | * | ||
22 | * @tparam A Heap memory allocator class. | ||
23 | */ | ||
24 | template <class A = Allocator> | ||
25 | class Thread : public NonCopyable<A>, public api::Thread | ||
26 | { | ||
27 | typedef NonCopyable<A> Parent; | ||
28 | |||
29 | public: | ||
30 | |||
31 | /** | ||
32 | * @brief Constructor. | ||
33 | * | ||
34 | * @param task A task interface whose start function is invoked when this thread is started. | ||
35 | */ | ||
36 | 28 | Thread(api::Task& task) | |
37 | : NonCopyable<A>() | ||
38 | , api::Thread() | ||
39 | 28 | , thread_(NULLPTR) { | |
40 |
1/2✓ Branch 1 taken 28 times.
✗ Branch 2 not taken.
|
28 | bool_t const isConstructed( construct(&task) ); |
41 | 28 | setConstructed( isConstructed ); | |
42 | 28 | } | |
43 | |||
44 | /** | ||
45 | * @brief Destructor. | ||
46 | */ | ||
47 | 62 | virtual ~Thread() | |
48 | { | ||
49 | 62 | if( thread_ != NULLPTR ) | |
50 | { | ||
51 |
1/2✓ Branch 0 taken 26 times.
✗ Branch 1 not taken.
|
52 | delete thread_; |
52 | } | ||
53 | } | ||
54 | |||
55 | /** | ||
56 | * @copydoc eoos::api::Object::isConstructed() | ||
57 | */ | ||
58 | 103 | virtual bool_t isConstructed() const | |
59 | { | ||
60 | 103 | return Parent::isConstructed(); | |
61 | } | ||
62 | |||
63 | /** | ||
64 | * @copydoc eoos::api::Thread::execute() | ||
65 | */ | ||
66 | 13 | virtual bool_t execute() | |
67 | { | ||
68 | 13 | bool_t res( false ); | |
69 |
5/6✓ Branch 1 taken 11 times.
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 11 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 11 times.
✓ Branch 6 taken 2 times.
|
13 | if( isConstructed() && (thread_ != NULLPTR) ) |
70 | { | ||
71 | 11 | res = thread_->execute(); | |
72 | } | ||
73 | 13 | return res; | |
74 | } | ||
75 | |||
76 | /** | ||
77 | * @copydoc eoos::api::Thread::join() | ||
78 | */ | ||
79 | 12 | virtual bool_t join() | |
80 | { | ||
81 | 12 | bool_t res( false ); | |
82 |
5/6✓ Branch 1 taken 10 times.
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 10 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 10 times.
✓ Branch 6 taken 2 times.
|
12 | if( isConstructed() && (thread_ != NULLPTR) ) |
83 | { | ||
84 | 10 | res = thread_->join(); | |
85 | } | ||
86 | 12 | return res; | |
87 | } | ||
88 | |||
89 | /** | ||
90 | * @copydoc eoos::api::Thread::getPriority() | ||
91 | */ | ||
92 | 16 | virtual int32_t getPriority() const | |
93 | { | ||
94 | 16 | int32_t priority( PRIORITY_WRONG ); | |
95 |
5/6✓ Branch 1 taken 14 times.
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 14 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 14 times.
✓ Branch 6 taken 2 times.
|
16 | if( isConstructed() && (thread_ != NULLPTR) ) |
96 | { | ||
97 | 14 | priority = thread_->getPriority(); | |
98 | } | ||
99 | 16 | return priority; | |
100 | } | ||
101 | |||
102 | /** | ||
103 | * @copydoc eoos::api::Thread::setPriority(int32_t) | ||
104 | */ | ||
105 | 14 | virtual bool_t setPriority(int32_t const priority) | |
106 | { | ||
107 |
7/8✓ Branch 1 taken 13 times.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 13 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 13 times.
✓ Branch 6 taken 1 times.
✓ Branch 8 taken 11 times.
✓ Branch 9 taken 2 times.
|
14 | return ( isConstructed() && (thread_ != NULLPTR) ) ? thread_->setPriority(priority) : false; |
108 | } | ||
109 | |||
110 | /** | ||
111 | * @copydoc eoos::api::Scheduler::sleep(int32_t) | ||
112 | */ | ||
113 | 3 | static bool_t sleep(int32_t const ms) | |
114 | { | ||
115 | 3 | return getScheduler().sleep(ms); | |
116 | } | ||
117 | |||
118 | /** | ||
119 | * @copydoc eoos::api::Scheduler::yield() | ||
120 | */ | ||
121 | 4 | static void yield() | |
122 | { | ||
123 | 4 | getScheduler().yield(); | |
124 | 4 | } | |
125 | |||
126 | protected: | ||
127 | |||
128 | using Parent::setConstructed; | ||
129 | |||
130 | /** | ||
131 | * @brief Constructor. | ||
132 | * | ||
133 | * @param task A task interface whose start function is invoked when this thread is started. | ||
134 | */ | ||
135 | 3 | Thread() | |
136 | : NonCopyable<A>() | ||
137 | , api::Thread() | ||
138 | 3 | , thread_(NULLPTR){ | |
139 |
1/2✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
|
3 | bool_t const isConstructed( construct(NULLPTR) ); |
140 | 3 | setConstructed( isConstructed ); | |
141 | 3 | } | |
142 | |||
143 | /** | ||
144 | * @brief Sets a task. | ||
145 | * | ||
146 | * @param task An task interface whose start function is invoked when this thread is started. | ||
147 | * @return True if the task has been set successfully. | ||
148 | */ | ||
149 | 31 | bool_t setTask(api::Task& task) | |
150 | { | ||
151 | 31 | bool_t res( false ); | |
152 |
1/2✓ Branch 0 taken 31 times.
✗ Branch 1 not taken.
|
31 | if( thread_ == NULLPTR ) |
153 | { | ||
154 | 31 | api::Scheduler& scheduler( getScheduler() ); | |
155 | 31 | thread_ = scheduler.createThread(task); | |
156 |
5/6✓ Branch 0 taken 26 times.
✓ Branch 1 taken 5 times.
✓ Branch 3 taken 26 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 26 times.
✓ Branch 6 taken 5 times.
|
31 | if( (thread_ != NULLPTR) && thread_->isConstructed() ) |
157 | { | ||
158 | 26 | res = true; | |
159 | } | ||
160 | } | ||
161 | 31 | return res; | |
162 | } | ||
163 | |||
164 | private: | ||
165 | |||
166 | /** | ||
167 | * @brief Constructor. | ||
168 | * | ||
169 | * @param task An task interface whose start function is invoked when this thread is started. | ||
170 | * @return True if object has been constructed successfully. | ||
171 | */ | ||
172 | 31 | bool_t construct(api::Task* const task) | |
173 | { | ||
174 | 31 | bool_t res( isConstructed() ); | |
175 |
1/2✓ Branch 0 taken 31 times.
✗ Branch 1 not taken.
|
31 | if( res == true ) |
176 | { | ||
177 |
2/2✓ Branch 0 taken 28 times.
✓ Branch 1 taken 3 times.
|
31 | if(task != NULLPTR) |
178 | { | ||
179 | 28 | res = setTask(*task); | |
180 | } | ||
181 | } | ||
182 | 31 | return res; | |
183 | } | ||
184 | |||
185 | /** | ||
186 | * @brief Returns the OS scheduler. | ||
187 | * | ||
188 | * @return The OS scheduler. | ||
189 | */ | ||
190 | 38 | static api::Scheduler& getScheduler() | |
191 | { | ||
192 | // @note Visual Studio 16 2019. The CXX compiler identification is MSVC 19.28.29335.0 | ||
193 | // Saving result of sys::Call::get().getScheduler() to local static variable is a cause of error | ||
194 | // SEH exception with code 0xc0000005 thrown in the test body. | ||
195 | // Exception thrown: read access violation. scheduler. was 0xFFFFFFFFFFFFFFEF. | ||
196 | // Therefore, each time of calling this getScheduler() return the system call getScheduler() function result | ||
197 | 38 | return sys::Call::get().getScheduler(); | |
198 | } | ||
199 | |||
200 | /** | ||
201 | * @brief A system scheduler thread. | ||
202 | */ | ||
203 | api::Thread* thread_; | ||
204 | |||
205 | }; | ||
206 | |||
207 | } // namespace lib | ||
208 | } // namespace eoos | ||
209 | #endif // LIB_THREAD_HPP_ | ||
210 |