//Sample code file: var/ndk/webBuildengine/tmp/viewable_samples/7999585e-fdab-4e7b-b86c-67d55e862138/nks/CtxSwap.c

//Warning: This code has been marked up for HTML

/***************************************************************************
$name: CtxSwap.c 
$version: 1.0 
$date_modified: 082499 
$description: Demonstrates the swapping of context between two threads.
$owner: NKS Product Manager 
Copyright (c) 1999 Novell, Inc. All Rights Reserved.

THIS WORK IS SUBJECT TO U.S. AND INTERNATIONAL COPYRIGHT LAWS AND TREATIES.
USE AND REDISTRIBUTION OF THIS WORK IS SUBJECT TO THE LICENSE AGREEMENT
ACCOMPANYING THE SOFTWARE DEVELOPMENT KIT (SDK) THAT CONTAINS THIS WORK.
PURSUANT TO THE SDK LICENSE AGREEMENT, NOVELL HEREBY GRANTS TO DEVELOPER A
ROYALTY-FREE, NON-EXCLUSIVE LICENSE TO INCLUDE NOVELL'S SAMPLE CODE IN ITS
PRODUCT. NOVELL GRANTS DEVELOPER WORLDWIDE DISTRIBUTION RIGHTS TO MARKET,
DISTRIBUTE, OR SELL NOVELL'S SAMPLE CODE AS A COMPONENT OF DEVELOPER'S
PRODUCTS. NOVELL SHALL HAVE NO OBLIGATIONS TO DEVELOPER OR DEVELOPER'S
CUSTOMERS WITH RESPECT TO THIS CODE.
****************************************************************************/
#include <stdio.h>
#include <nks/thread.h>

NXContext_t   *gContextA, *gContextB, *gContextC;

void ThreadFuncA
(
   int   *arg
)
{
   NXContext_t   *tempContext;

   printf("Thread %d Beginning Func A\n", NXThreadGetId());

   // switch to another context to terminate so this one isn't reset...

   while (NXThreadSwapContext(gContextC, &tempContext))
      NXThreadYield();
   
   printf("Thread %d Finishing Func A\n", NXThreadGetId());
}

void ThreadFuncB
(
   int   *arg
)
{
   printf("Thread %d Beginning Func B\n", NXThreadGetId());

/*
** Switch to context A, this will return NX_EBUSY while another thread is
** bound to it.
*/
   while (NXThreadSwapContext(gContextA, NULL))
      NXThreadYield();

   printf("WE SHOULD NEVER EXECUTE THIS!\n");
}

void ThreadFuncC( int *arg )
{
/*
** This function is switched to for termination so the other context will
** not reset.
*/
}

void main
(
   int   argc,
   char   **argv
)
{
   int            err;
   NXThreadId_t   tIDA, tIDB;

   gContextA = NXContextAlloc(ThreadFuncA, &gContextA, NX_PRIO_MED, 0,
                                                         NX_CTX_NORMAL, &err);
   gContextB = NXContextAlloc(ThreadFuncB, &gContextB, NX_PRIO_MED, 0,
                                                         NX_CTX_NORMAL, &err);
   gContextC = NXContextAlloc(ThreadFuncC, &gContextC, NX_PRIO_MED, 0,
                                                         NX_CTX_NORMAL, &err);
   if (gContextA && gContextB && gContextC)
   {
      NXThreadCreate(gContextA, NX_THR_DETACHED, &tIDA);
      NXThreadCreate(gContextB, NX_THR_DETACHED, &tIDB);
   }
   else
   {
      if (gContextA)
         NXContextFree(gContextA);

      if (gContextB)
         NXContextFree(gContextB);

      if (gContextC)
         NXContextFree(gContextC);
   }
}