ChorusOS 4.0 Introduction

Deleting a Thread

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

#include <chorus.h>

int threadDelete(KnCap* actorCap,
                 KnThreadLid thLi);

This call enables a thread to delete another one inside the same actor, when actorCap is set to K_MYACTOR, by knowing the thread identifier of the thread to be deleted. It also enables a thread to delete another one inside another 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 6-2 is a slightly different version of the previous program. The subroutine childCreate() is unchanged, but now the created thread kills itself, instead of going idle forever.


Note -

This does not solve the synchronization problem occurring in the previous example: the main thread still does not know exactly when to terminate the actor.


Refer to the threadDelete(2K) man page.


Example 6-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, 0, &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 */
  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.
       */
  res = threadDelay(&wait);

  printf("Parent thread identifier = %d, Child thread identifier = %d\n",
	 myThreadLi, newThreadLi);

  return 0;
}