Terminating a thread from another thread - is it possible?

ChibiOS public support forum for all topics not covered by a specific support forum.

Moderators: RoccoMarco, lbednarz, utzig, tfAteba, barthess

ibabatov
Posts: 2
Joined: Mon Feb 18, 2013 8:20 am

Terminating a thread from another thread - is it possible?

Postby ibabatov » Mon Feb 18, 2013 8:58 am

Hi, I am developing a system that needs to start a thread at runtime (on external command) and to be able to terminate it regardless of its current state (on another external command or other event - a fault signal from a monitoring thread for example). The thread being spawned must be strictly linear in nature and is incapable of periodically calling chThdShouldTerminate(). It is considered safe to 'kill' the thread at any point of its execution. The thread that spawns the linear thread must continue operation (i.e. must not block to wait for the spawned thread to finish).
It should be possible to spawn the linear thread again from its beginning.
Is there a clean way to implement this functionality (without changing the kernel code)? If not, what would be the proper way to do it? I guess performing the operations in chThdExitS() on the spawned thread from the 'monitoring' thread, followed by a call to chThdWait() would do the job, but there might be a better way.

Any help would be highly appreciated!

Thank you in advance!

User avatar
Giovanni
Site Admin
Posts: 14444
Joined: Wed May 27, 2009 8:48 am
Location: Salerno, Italy
Has thanked: 1074 times
Been thanked: 921 times
Contact:

Re: Terminating a thread from another thread - is it possibl

Postby Giovanni » Mon Feb 18, 2013 9:15 am

Hi,

Killing a thread is not possible, it is a design choice because it would be inherently not safe in all possible situations.

What you can do is to atomically set the termination flag and reset any "wait" primitive used by the thread. For example, assuming the thread uses a semaphore you can do:

From the monitor thread:

Code: Select all

  chSysLock;
  tp->p_flags |= THD_TERMINATE;
  chSemResetI(sp);
  chSchRescheduleS();
  chSysUnlock();
 
  chThdWait(tp);


From the linear thread, replace the call to the semaphore wait with:

Code: Select all

  msg_t msg;

  chSysLock();
  if (chThdShouldTerminate())
    chThdExitS(RDY_RESET);
  msg = chSemWaitS(sp);
  if (msg == RDY_RESET)
    chThdExitS(msg);
  chSysUnlock();


If you use messages or mailboxes then you could use a kill message instead of chSemResetI();

Using this method the thread would make a termination check each time it attempts to go in a wait state.

Giovanni

ibabatov
Posts: 2
Joined: Mon Feb 18, 2013 8:20 am

Re: Terminating a thread from another thread - is it possibl

Postby ibabatov » Mon Feb 18, 2013 9:33 am

I got it.

Thank you so much for the great job you've done with ChibiOS!

Wish you all the best,

Ivan

rolanddixon
Posts: 26
Joined: Wed Feb 25, 2015 9:45 pm
Has thanked: 1 time
Been thanked: 2 times

Re: Terminating a thread from another thread - is it possible?

Postby rolanddixon » Tue Nov 02, 2021 8:06 am

Hi,

I know this is an old thread, and chibios has moved on a bit since, but I was wondering how one could reuse the stack of a thread that has exited.

Is the code below code safe to use?

monitoring thread:

Code: Select all

chSysLock();
pThd->flags |= CH_FLAG_TERMINATE;
chSemResetI(pSemaphore, 0);
chSysUnlock();
while(!chThdTerminatedX(pThd))
{
    chThdYield();
}
/* So that the stack can be reused by another thread */
pThd->wabase = nullptr;


Thread to be terminated:

Code: Select all

msg_t msg;
chSysLock();
if (chThdShouldTerminateX())
    chThdExitS(MSG_RESET);
msg = chSemWaitS(pSemaphore);
if (msg == MSG_RESET)
    chThdExitS(msg);
chSysUnlock();

User avatar
Giovanni
Site Admin
Posts: 14444
Joined: Wed May 27, 2009 8:48 am
Location: Salerno, Italy
Has thanked: 1074 times
Been thanked: 921 times
Contact:

Re: Terminating a thread from another thread - is it possible?

Postby Giovanni » Tue Nov 02, 2021 9:03 am

Hi,

Stacks can be reused, follow this pattern for termination:

Thread (threadp is the pointer to this thread):

Code: Select all

  while (!chThdShouldTerminateX()) {
    /* Waiting for something.*/
    msg = chSemWait(&sem);
    if (msg != MSG_RESET) {
      /* Do things */
    }
  }
  return;


Other thread:

Code: Select all

  chSemReset(&sem);
  chThdWait(threadp);
  /* Now stack can be reused.*/


Note, performing chThdWait() is important or the thread would be stuck in the registry, reusing the stack would corrupt it.

Giovanni

rolanddixon
Posts: 26
Joined: Wed Feb 25, 2015 9:45 pm
Has thanked: 1 time
Been thanked: 2 times

Re: Terminating a thread from another thread - is it possible?

Postby rolanddixon » Tue Nov 02, 2021 9:24 am

Great, thank you.


Return to “General Support”

Who is online

Users browsing this forum: No registered users and 22 guests