Thread::detach() – new rare feature

Yesterday distortos got another feature which is hardly ever seen in other RTOSes – ability to detach dynamic threads. Two new functions that were added – Thread::detach() and ThisThread::detach() – are direct equivalents of std::thread::detach() from C++11 or pthread_detach() from POSIX.

When using threads you have to join the thread before the object that represents it goes out of scope, which usually looks like this:

#include "distortos/StaticThread.hpp"

void threadFunction()
{
  // ...
  // code that will be executed in separate thread
  // ...
}

int main()
{
  // ...

  {
    // low priority (1), 1024 bytes of stack, no support for signals,
    // round-robin scheduling policy
    auto thread = distortos::makeStaticThread<1024>(1, threadFunction);
    thread.start();
    // ...
    // do something else while threadFunction() is running in another context
    // ...
    thread.join();
  } // thread object goes out of scope

  // ...

  return 0;
}
#include "distortos/DynamicThread.hpp"

void threadFunction()
{
  // ...
  // code that will be executed in separate thread
  // ...
}

int main()
{
  // ...

  {
    // low priority (1), 1024 bytes of stack, no support for signals,
    // round-robin scheduling policy
    auto thread = distortos::makeDynamicThread({1024, 1}, threadFunction);
    thread.start();
    // ...
    // do something else while threadFunction() is running in another context
    // ...
    thread.join();
  } // thread object goes out of scope

  // ...

  return 0;
}

Before thread object goes out of scope in line 23, Thread::join() has to be called to wait for threadFunction() (and the thread executing in separate context) to finish. This is crucial, because otherwise you would delete resources (stack, control blocks, …) which are used by a thread that is still active – these resources are part of  thread object.

However, with dynamic threads (using DynamicThread class) another options is available. The thread of execution (along with all its resources) can be detached from the object that represents it:

#include "distortos/DynamicThread.hpp"

void threadFunction()
{
  // ...
  // code that will be executed in separate thread
  // ...
}

int main()
{
  // ...

  {
    // low priority (1), 1024 bytes of stack, no support for signals,
    // round-robin scheduling policy
    auto thread = distortos::makeDynamicThread({1024, 1}, threadFunction);
    thread.start();
    thread.detach();
  } // thread object goes out of scope

  // ...
  // do something else while threadFunction() is running in another context
  // ...

  return 0;
}

In this scenario thread object can go out of scope in line 20 while threadFunction() is still running. When the detached thread finishes its execution, it schedules itself for deferred deletion, which is done in idle thread.

Because this new feature slightly increases RAM requirements, it has to be explicitly enabled in the Kconfig configuration tool, in Scheduler configuration menu, which is presented on the screenshot below.

Kconfig, scheduler
Kconfig, scheduler