<div dir="ltr">Is there a test case for this situation?</div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Thu, May 20, 2021 at 10:18 AM Sebastian Huber <<a href="mailto:sebastian.huber@embedded-brains.de">sebastian.huber@embedded-brains.de</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">The _Thread_Cancel() (in contrast to _Thread_Restart() which used a<br>
similar code block) may have produced ready threads with an active timer<br>
in case the thread to cancel had its thread life protection enabled. The<br>
problem was this code block:<br>
<br>
Priority_Control priority;<br>
<br>
_Thread_Add_life_change_request( the_thread );<br>
<br>
if ( _Thread_Is_life_change_allowed( previous ) ) {<br>
_Thread_State_release( the_thread, &lock_context );<br>
<br>
_Thread_queue_Extract_with_proxy( the_thread );<br>
_Thread_Timer_remove( the_thread );<br>
} else {<br>
_Thread_Clear_state_locked( the_thread, STATES_SUSPENDED );<br>
_Thread_State_release( the_thread, &lock_context );<br>
}<br>
<br>
priority = _Thread_Get_priority( executing );<br>
_Thread_Raise_real_priority( the_thread, priority );<br>
_Thread_Remove_life_change_request( the_thread );<br>
<br>
The life change request should only be added/removed if a life change is<br>
allowed (see _Thread_Restart()). Add<br>
_Thread_Consider_life_change_request() and use it in _Thread_Cancel()<br>
and _Thread_Restart().<br>
<br>
Close #4435.<br>
---<br>
cpukit/score/src/threadrestart.c | 50 ++++++++++++++++----------------<br>
1 file changed, 25 insertions(+), 25 deletions(-)<br>
<br>
diff --git a/cpukit/score/src/threadrestart.c b/cpukit/score/src/threadrestart.c<br>
index 933faee61b..58fcd89159 100644<br>
--- a/cpukit/score/src/threadrestart.c<br>
+++ b/cpukit/score/src/threadrestart.c<br>
@@ -403,6 +403,25 @@ static void _Thread_Set_exit_value(<br>
the_thread->Life.exit_value = exit_value;<br>
}<br>
<br>
+static void _Thread_Consider_life_change_request(<br>
+ Thread_Control *the_thread,<br>
+ Thread_Life_state previous,<br>
+ ISR_lock_Context *lock_context<br>
+)<br>
+{<br>
+ if ( _Thread_Is_life_change_allowed( previous ) ) {<br>
+ _Thread_Add_life_change_request( the_thread );<br>
+ _Thread_State_release( the_thread, lock_context );<br>
+<br>
+ _Thread_queue_Extract_with_proxy( the_thread );<br>
+ _Thread_Timer_remove( the_thread );<br>
+ _Thread_Remove_life_change_request( the_thread );<br>
+ } else {<br>
+ _Thread_Clear_state_locked( the_thread, STATES_SUSPENDED );<br>
+ _Thread_State_release( the_thread, lock_context );<br>
+ }<br>
+}<br>
+<br>
void _Thread_Cancel(<br>
Thread_Control *the_thread,<br>
Thread_Control *executing,<br>
@@ -433,21 +452,13 @@ void _Thread_Cancel(<br>
} else {<br>
Priority_Control priority;<br>
<br>
- _Thread_Add_life_change_request( the_thread );<br>
-<br>
- if ( _Thread_Is_life_change_allowed( previous ) ) {<br>
- _Thread_State_release( the_thread, &lock_context );<br>
-<br>
- _Thread_queue_Extract_with_proxy( the_thread );<br>
- _Thread_Timer_remove( the_thread );<br>
- } else {<br>
- _Thread_Clear_state_locked( the_thread, STATES_SUSPENDED );<br>
- _Thread_State_release( the_thread, &lock_context );<br>
- }<br>
-<br>
+ _Thread_Consider_life_change_request(<br>
+ the_thread,<br>
+ previous,<br>
+ &lock_context<br>
+ );<br>
priority = _Thread_Get_priority( executing );<br>
_Thread_Raise_real_priority( the_thread, priority );<br>
- _Thread_Remove_life_change_request( the_thread );<br>
}<br>
<br>
_Thread_Dispatch_enable( cpu_self );<br>
@@ -559,18 +570,7 @@ Status_Control _Thread_Restart(<br>
THREAD_LIFE_RESTARTING,<br>
ignored_life_states<br>
);<br>
-<br>
- if ( _Thread_Is_life_change_allowed( previous ) ) {<br>
- _Thread_Add_life_change_request( the_thread );<br>
- _Thread_State_release( the_thread, lock_context );<br>
-<br>
- _Thread_queue_Extract_with_proxy( the_thread );<br>
- _Thread_Timer_remove( the_thread );<br>
- _Thread_Remove_life_change_request( the_thread );<br>
- } else {<br>
- _Thread_Clear_state_locked( the_thread, STATES_SUSPENDED );<br>
- _Thread_State_release( the_thread, lock_context );<br>
- }<br>
+ _Thread_Consider_life_change_request( the_thread, previous, lock_context );<br>
<br>
_Thread_queue_Context_initialize( &queue_context );<br>
_Thread_queue_Context_clear_priority_updates( &queue_context );<br>
-- <br>
2.26.2<br>
<br>
_______________________________________________<br>
devel mailing list<br>
<a href="mailto:devel@rtems.org" target="_blank">devel@rtems.org</a><br>
<a href="http://lists.rtems.org/mailman/listinfo/devel" rel="noreferrer" target="_blank">http://lists.rtems.org/mailman/listinfo/devel</a><br>
</blockquote></div>