@@ -88,26 +88,30 @@ TEST(test_mutex, pimutex_lockthread) {
8888 test_mutex.lock ();
8989 result = 1 ; // this line should not be reached as long as the mutex is locked
9090 });
91- std::this_thread::sleep_for (20ms );
91+ std::this_thread::sleep_for (10ms );
9292 EXPECT_EQ (0 , result);
9393
9494 test_mutex.unlock ();
9595 test_thread.join ();
9696}
9797
98- TEST (test_mutex, pimutex_priority_inversion) {
99- rcpputils::PIMutex test_mutex;
98+ template <class MutexClass >
99+ void priority_inheritance_test () {
100+ MutexClass test_mutex;
100101 std::atomic<bool > end_low_prio_thread {false };
101102 std::atomic<bool > end_medium_prio_thread {false };
102103 const unsigned int cpu_bitmask = 1 ; // allow only one cpu core to be used!
103104
104105 // create low prio thread & take mutex
105106 std::thread low_prio_thread ([&test_mutex, &end_low_prio_thread]() {
107+ std::cout << " Low prio thread starts.\n " << std::flush;
106108 test_mutex.lock ();
109+ std::cout << " Low prio thread locked.\n " << std::flush;
107110 while (!end_low_prio_thread) {
108111 std::this_thread::sleep_for (1ms);
109112 }
110113 test_mutex.unlock ();
114+ std::cout << " Low prio thread unlocked and ends.\n " << std::flush;
111115 });
112116 if (rcpputils::configure_realtime_thread (
113117 low_prio_thread, THREAD_PRIORITY_LOW,
@@ -125,11 +129,15 @@ TEST(test_mutex, pimutex_priority_inversion) {
125129 test_mutex.unlock ();
126130 std::this_thread::sleep_for (1ms);
127131 }
132+ std::cout << " Test thread try_lock failed as expected.\n " << std::flush;
128133
129134 // create high prio thread & take mutex
130135 std::thread high_prio_thread ([&test_mutex]() {
136+ std::cout << " High prio thread starts.\n " << std::flush;
131137 test_mutex.lock (); // this call will block initially
138+ std::cout << " High prio thread locked.\n " << std::flush;
132139 test_mutex.unlock ();
140+ std::cout << " High prio thread unlocked and ends.\n " << std::flush;
133141 });
134142 EXPECT_TRUE (
135143 rcpputils::configure_realtime_thread (
@@ -138,30 +146,55 @@ TEST(test_mutex, pimutex_priority_inversion) {
138146
139147 // create medium priority thread that would block the low prio thread
140148 // if there is no priority inheritance
141- std::thread medium_prio_thread ([&end_medium_prio_thread]() {
149+ std::atomic<bool > medium_thread_started {false };
150+ std::thread medium_prio_thread ([&end_medium_prio_thread, &medium_thread_started]() {
151+ std::cout << " Medium prio thread starts.\n " << std::flush;
152+ medium_thread_started = true ;
142153 // create 100% workload on assigned cpu core
143154 while (!end_medium_prio_thread) {}
155+ std::cout << " Medium prio thread ends.\n " << std::flush;
144156 });
145157 EXPECT_TRUE (
146158 rcpputils::configure_realtime_thread (
147159 medium_prio_thread,
148160 THREAD_PRIORITY_MEDIUM,
149161 cpu_bitmask)) << " THREAD_PRIORITY_MEDIUM could not be set." ;
162+ while (medium_thread_started == false ) {
163+ std::this_thread::sleep_for (1ms);
164+ }
150165
151166 // do the actual test: see if the low prio thread gets unblocked (through priority inheritance)
167+ std::cout << " Signalling end low prio thread.\n " << std::flush;
152168 end_low_prio_thread = true ;
153- std::this_thread::sleep_for (20ms);
154169
155170 // if priority inheritance worked the mutex should not be locked anymore
156- bool try_lock_result = test_mutex.try_lock ();
157- EXPECT_TRUE (try_lock_result) << " Mutex should not be locked anymore." ;
171+ bool try_lock_result;
172+ int count = 0 ;
173+ while ((try_lock_result = test_mutex.try_lock ()) == false )
174+ {
175+ std::this_thread::sleep_for (1ms);
176+ if (count++ >= 20 )
177+ {
178+ EXPECT_TRUE (try_lock_result) << " Mutex should not be locked anymore." ;
179+ break ;
180+ }
181+ }
158182 if (try_lock_result) {
159183 test_mutex.unlock ();
160184 }
161185
162186 // cleanup
163- low_prio_thread.detach ();
164- high_prio_thread.detach ();
187+ std::cout << " Signalling end medium prio thread.\n " << std::flush;
165188 end_medium_prio_thread = true ;
166189 medium_prio_thread.join ();
190+ high_prio_thread.join ();
191+ low_prio_thread.join ();
192+ }
193+
194+ TEST (test_mutex, pimutex_priority_inversion) {
195+ priority_inheritance_test<rcpputils::PIMutex>();
196+ }
197+
198+ TEST (test_mutex, rpimutex_priority_inversion) {
199+ priority_inheritance_test<rcpputils::RecursivePIMutex>();
167200}
0 commit comments