ChorusOS 5.0 Application Developer's Guide

Deleting a Thread

A thread may be deleted dynamically by itself, or by another thread using the following service:

#include <chorus.h>
int threadDelete(KnCap* actorCap, KnThreadLid thLi);

This call enables one thread to delete another inside the same actor. The actorCap parameter is set to K_MYACTOR and the thread identifier of the thread to be deleted has been identified. The call also enables one thread to delete another inside a different actor (provided they are both running on the same machine), as long as it provides both the actor capability and the target thread identifier. The predefined thread identifier K_MYSELF enables a thread to name itself without knowing its actual thread identifier.

Example 7-2 is a slightly different version of the previous example. The subroutine childCreate() is unchanged, however in this example, the created thread kills itself instead of going idle forever.


Note -

This strategy does not solve the synchronization problem that occurred in the previous example -- the main thread still does not know exacty when to terminate the actor.


For more information, refer to the threadDelete(2K) man page.


Example 7-2 Deleting a Thread

(file: progov/thDelete.c)
#include <stdio.h>
#include <stdlib.h>
#include <chorus.h>
#define USER_STACK_SIZE (1024 * sizeof(long))
    int
childCreate(KnPc entry)
{
  KnActorPrivilege      actorP;
  KnDefaultStartInfo_f  startInfo;
  char*                 userStack;
  int                   childLid = -1;
  int                   res;
  startInfo.dsType            = K_DEFAULT_START_INFO;
  startInfo.dsSystemStackSize = K_DEFAULT_STACK_SIZE;
  res = actorPrivilege(K_MYACTOR, &actorP, NULL);
  if (res != K_OK) {
    printf("Cannot get the privilege of the actor, error %d\n", res);
    exit(1);
  }
  if (actorP == K_SUPACTOR) {
    startInfo.dsPrivilege = K_SUPTHREAD;
  } else {
    startInfo.dsPrivilege = K_USERTHREAD;
  }
  if (actorP != K_SUPACTOR) {
    userStack = malloc(USER_STACK_SIZE);
    if (userStack == NULL) {
      printf("Cannot allocate user stack\n");
      exit(1);
    }
    startInfo.dsUserStackPointer = userStack + USER_STACK_SIZE;
  } 
  startInfo.dsEntry = entry;
  res = threadCreate(K_MYACTOR, &childLid, K_ACTIVE, NULL, &startInfo);
  if (res != K_OK) {
    printf("Cannot create the thread, error %d\n", res);
    exit(1);
  }
  return childLid;
}
    void
sampleThread()
{
  int myThreadLi;
  myThreadLi = threadSelf();
  printf("I am the new thread. My thread identifier is: %d\n", myThreadLi);
      /* Suicide */
  (void) threadDelete(K_MYACTOR, K_MYSELF);
      /* Should never reach this point! */
}
int main(int argc, char** argv, char**envp)
{
  int        myThreadLi;
  int        newThreadLi;
  int        res;            
  KnTimeVal  wait;
  newThreadLi = childCreate((KnPc)sampleThread);
  myThreadLi = threadSelf();
      /* Initialize KnTimeVal structure */
  K_MILLI_TO_TIMEVAL(&wait, 10);
      /*
       * Suspend myself for 10 milliseconds to give the newly
       * created thread the opportunity to run before
       * the actor terminates.
       */
  (void) threadDelay(&wait);
  printf("Parent thread identifier = %d, Child thread identifier = %d\n",
      myThreadLi, newThreadLi);
  return 0;
}

The exit(3STDC) function is used instead of the threadDelete(2K) function in the main thread. Using threadDelete(2K) would leave the actor in a passive situation, with no thread running within it. This implies that resources used by an actor are not freed when the last thread is deleted.

In the case of a user thread, deleting a thread does not imply that the stack of the thread will also be freed. If the user stack was allocated through a call to malloc(3STDC), it must be freed through a call to free(3STDC). This cannot be done by the thread itself and must be done by a separate thread. In the previous example, the actor is going to terminate so there is no real need to free the stack because all resources used by the actor will be returned to the system. In the case of a supervisor thread, the ChorusOS operating system frees the system stack it allocated at threadCreate(2K)time.