/*******************************************************************************
Copyright by Telesoft Europe AB 1990, 1991.
Copyright by Telelogic Malmoe AB 1991, 1992, 1993, 1994.
Copyright by Telelogic AB 1994 - 2002.
This Program is owned by Telelogic and is protected by national
copyright laws and international copyright treaties. Telelogic
grants you the right to use this Program on one computer or in
one local computer network at any one time.
Under this License you may only modify the source code for the purpose
of adapting it to your environment. You must reproduce and include
any copyright and trademark notices on all copies of the source code.
You may not use, copy, merge, modify or transfer the Program except as
provided in this License.
Telelogic does not warrant that the Program will meet your
requirements or that the operation of the Program will be
uninterrupted and error free. You are solely responsible that the
selection of the Program and the modification of the source code
will achieve your intended results and that the results are actually
obtained.
*******************************************************************************/

/*
# clearcase sctsdl.c@@/main/71 : 2002/04/18 lr
*/

/****+***************************************************************
01   Include Files
********************************************************************/

#include "scttypes.h"

#include "sctlocal.h"

/****+***************************************************************
02   Global macro and variables
********************************************************************/

#if !defined(XNOUSEOFREAL) && defined(XEFIXOF)
SDL_Integer  xMax_SDL_Integer;
#endif
SDL_Time     xMaxTime;

SDL_PId      xEnv;
xPrsIdNode   xEnvId;
SDL_PId      SDL_NULL;
                  /* = { 0, (xLocalPIdNode)0 }; */
#ifndef XOPTCHAN
SDL_PId      xNotDefPId;
                  /* = { -1, (xLocalPIdNode)0 }; */
#endif

XCONST struct xIdStruct xSymbolTableIdRec = {xSystemEC
  xSymbTLink((xIdNode)0, (xIdNode)0), (xIdNode)0 xIdNames("SymbolTableRoot")};

static XPRSNODE yEnvA_env = (XPRSNODE)0;
static XPRSNODE yEnvB_env = (XPRSNODE)0;
XCONST struct xPrsIdStruct yEnvR_env = {xProcessEC xSymbTLink((xIdNode)0,
  (xIdNode)0), (xIdNode)&xSymbolTableIdRec xIdNames("env") XCOMMON_EXTRAS,
  0, 0 xService(0) xOptChan(yEnvO_env), 1 xNrInst(1) xNrInst(1), &yEnvB_env,
  (xptrint)sizeof(xPrsRec) xPrsPrioPar(xDefaultPrioProcess), &yEnvA_env
  xTrace(-1) xGRTrace(-1) xBreakB(0) xBreakB(-1) xBreakB(0) xMSCETrace(-1)
  xCoverage(0) xCoverage(0) xCoverage(0), 0, 0, (xPrsIdNode)0, (xPrdIdNode *)0,
  (xBlockIdNode)0 xBreakB("") XPRS_EXTRAS(env)};
#ifndef XNOSTARTUPIDNODE
static xSignalNode ySigA_env = (xSignalNode)0;
static XCONST struct xSignalIdStruct ySigR_Env = {xStartUpSignalEC
  xSymbTLink((xIdNode)0, (xIdNode)0), (xIdNode)&xSymbolTableIdRec
  xIdNames("-") XCOMMON_EXTRAS, (xptrint)sizeof(XSIGNALHEADERTYPE), &ySigA_env,
  0 xFreS(0) SIGCODE(STARTUPSIGNAL) xBreakB("") xSigPrioPar(xDefaultPrioSignal)
  XSIG_EXTRAS};
#endif

XCONST struct xStateIdStruct xStartStateIdRec = {xStateEC
  xSymbTLink((xIdNode)0, (xIdNode)0), (xIdNode)0
  xIdNames("start state") XCOMMON_EXTRAS,
  START_STATE, 0, 0, 0, 0, 0 xCoverage(0), (xStateIdNode)0 xBreakB("")};

XCONST struct xStateIdStruct xRPCWaitStateIdRec = {xStateEC
  xSymbTLink((xIdNode)0, (xIdNode)0), (xIdNode)0
  xIdNames("pWAIT_rpc") XCOMMON_EXTRAS,
  XRPC_WAIT_STATE, 0, 0, 0, 0, 0 xCoverage(0), (xStateIdNode)0 xBreakB("")};

XCONST struct xSignalIdStruct xContSigIdRec = {xSignalEC xSymbTLink((xIdNode)0,
  (xIdNode)0), (xIdNode)0 xIdNames("cont signal") XCOMMON_EXTRAS,
  (xptrint)sizeof(XSIGNALHEADERTYPE), 0, 0 xFreS(0) SIGCODE(CONTSIGNAL)
  xBreakB("") xSigPrioPar(xDefaultPrioSignal) XSIG_EXTRAS};

XCONST struct xSignalIdStruct xNoneSigIdRec = {xSignalEC xSymbTLink((xIdNode)0,
  (xIdNode)0), (xIdNode)0 xIdNames("NONE") XCOMMON_EXTRAS,
  (xptrint)sizeof(XSIGNALHEADERTYPE), 0, 0 xFreS(0) SIGCODE(NONESIGNAL)
  xBreakB("") xSigPrioPar(xDefaultPrioSignal) XSIG_EXTRAS};

#ifdef XERRORSTATE
static XCONST struct xStateIdStruct ErrorStateId = {xStateEC
  xSymbTLink((xIdNode)0, (xIdNode)0), (xIdNode)0
  xIdNames("decision error state") XCOMMON_EXTRAS,
  ERROR_STATE, 0, 0, 0, 0, 0 xCoverage(0), (xStateIdNode)0 xBreakB("")};
#endif

#ifdef XREADANDWRITEF
XCONST struct xPrsIdStruct xNullIdRec =
   {xProcessEC xSymbTLink((xIdNode)0, (xIdNode)0), (xIdNode)0
    xIdNames("null") XCOMMON_EXTRAS,
    0, 0 xService(0) xOptChan(0), 1 xNrInst(1) xNrInst(1),
    (xPrsNode *)0, (xptrint)sizeof(xPrsRec) xPrsPrioPar(xDefaultPrioProcess),
    (xPrsNode *)0 xTrace(-1) xGRTrace(-1) xBreakB(0) xBreakB(-1) xBreakB(0)
    xMSCETrace(-1) xCoverage(0) xCoverage(0) xCoverage(0), 0, 0,
    (xPrsIdNode)0, (xPrdIdNode *)0, (xBlockIdNode)0 xBreakB("")
    XPRS_EXTRAS(null)};
#endif

#define XTEMPDATA_SIZE  8
static char xData[XTEMPDATA_SIZE];
  /* Used as return value in SDL_Error, xGetExportAddr, SDL_View */

#ifdef THREADED
  THREADED_GLOBAL_VARS
#endif

xSignalNode  xAvailSignal;
xSignalNode  xAvailTimer;


/****+***************************************************************
03   C++ specific
********************************************************************/
#ifdef __cplusplus
void * operator new (size_t pp, xSpecial vv) {
  return (void *)vv;
}
#endif

/****+***************************************************************
04   Error Handling
********************************************************************/

#if defined(XEOUTPUT) || defined(XOPERRORF) || defined(XERANGE) || defined(XEEXPORT) || defined(XEINDEX) || defined(XEDECISION) || defined(XEEROR) || defined(XASSERT) || defined(XEUNION) || defined(XEOPTIONAL) || defined(XECHOICE) || defined(XEREF) || defined (XECODER)
/*---+---------------------------------------------------------------
     xSDLDynamicErrorInfo
-------------------------------------------------------------------*/
static void xSDLDynamicErrorInfo (xPrsNode  P)
{
  xIdNode  UnitP;
  char     Temp[256];
  
  xPrintString("TRANSITION\n");
  (void)sprintf(Temp, "  Process        : %s\n", xWri_SDL_PId(&P->Self));
  xPrintString(Temp);
  if ( P == (xPrsNode)0 ) return;
  if ( P == xEnv.LocalPId->PrsP ) return;
  if ( P->Self.GlobalNodeNr != xGlobalNodeNumber() ) return;

#ifdef XIDNAMES
#ifndef XNOUSEOFSERVICE
  if (P->ActiveSrv != (xSrvNode)0) {
    (void)sprintf(Temp, "  Service        : %s\n",
                  P->ActiveSrv->NameNode->Name);
    if ( P->ActiveSrv->ActivePrd != (xPrdNode)0 ) {
      (void)sprintf(Temp, "  Procedure      : %s\n",
                    P->ActiveSrv->ActivePrd->NameNode->Name);
      xPrintString(Temp);
    }
    if (P->ActiveSrv->State == START_STATE)
      (void)sprintf(Temp, "  State          : start state\n");
    else if (P->ActiveSrv->State == ERROR_STATE)
      (void)sprintf(Temp, "  State          : decision error state\n");
    else
      (void)sprintf(Temp, "  State          : %s\n",
                  P->ActiveSrv->NameNode->StateList[P->ActiveSrv->State]->Name);
    xPrintString(Temp);
    if ( P->ActiveSrv->ActivePrd != (xPrdNode)0  ) {
      if (P->ActiveSrv->ActivePrd->State == START_STATE)
        (void)sprintf(Temp, "  Procedure state: start state\n");
      else if (P->ActiveSrv->ActivePrd->State == ERROR_STATE)
        (void)sprintf(Temp, "  Procedure state: decision error state\n");
      else
        (void)sprintf(Temp, "  Procedure state: %s\n",
                      P->ActiveSrv->ActivePrd->NameNode->StateList[
                                    P->ActiveSrv->ActivePrd->State]->Name);
      xPrintString(Temp);
    }
  } else {
#endif
    if ( P->ActivePrd != (xPrdNode)0 ) {
      (void)sprintf(Temp, "  Procedure      : %s\n",
                    P->ActivePrd->NameNode->Name);
      xPrintString(Temp);
    }
    if (P->State == START_STATE)
      (void)sprintf(Temp, "  State          : start state\n");
    else if (P->State == ERROR_STATE)
      (void)sprintf(Temp, "  State          : decision error state\n");
    else
      (void)sprintf(Temp, "  State          : %s\n",
                    P->NameNode->StateList[P->State]->Name);
    xPrintString(Temp);
    if ( P->ActivePrd != (xPrdNode)0  ) {
      if (P->ActivePrd->State == START_STATE)
        (void)sprintf(Temp, "  Procedure state: start state\n");
      else if (P->ActivePrd->State == ERROR_STATE)
        (void)sprintf(Temp, "  Procedure state: decision error state\n");
      else
        (void)sprintf(Temp, "  Procedure state: %s\n",
                  P->ActivePrd->NameNode->StateList[P->ActivePrd->State]->Name);
      xPrintString(Temp);
    }
#ifndef XNOUSEOFSERVICE
  }
#endif

  if ( P->Signal != (xSignalNode)0 ) {
    (void)sprintf(Temp, "  Input          : %s\n", P->Signal->NameNode->Name);
    xPrintString(Temp);
  }
#if defined(XGRTRACE) || defined(XMONITOR)
  if (strlen(xSysD.xCurrentSymbolRef) > (unsigned)2) {
    (void)sprintf(Temp, "  Symbol         : %s\n", xSysD.xCurrentSymbolRef);
    xPrintString(Temp);
  }
#endif
  xPrintString("TRACE BACK\n");
  for (UnitP = (xIdNode)P->NameNode; UnitP != (xIdNode)0; 
       UnitP = UnitP->Parent) {
    if ( UnitP->EC == xSystemEC ) {
      (void)sprintf(Temp, "  System         : %s\n", UnitP->Name);
      xPrintString(Temp);
      break;
    }
    if ( UnitP->EC == xSystemTypeEC ) {
      (void)sprintf(Temp, "  System type    : %s\n", UnitP->Name);
      xPrintString(Temp);
    }
    if ( UnitP->EC == xPackageEC ) {
      (void)sprintf(Temp, "  Package        : %s\n", UnitP->Name);
      xPrintString(Temp);
      break;
    }
    if ( UnitP->EC == xBlockEC ) {
      (void)sprintf(Temp, "  Block          : %s\n", UnitP->Name);
      xPrintString(Temp);
    }
    if ( UnitP->EC == xBlockTypeEC ) {
      (void)sprintf(Temp, "  Block type     : %s\n", UnitP->Name);
      xPrintString(Temp);
    }
    else if ( UnitP->EC == xBlocksubstEC ) {
      (void)sprintf(Temp, "  Blocksubst     : %s\n", UnitP->Name);
      xPrintString(Temp);
    }
    else if ( UnitP->EC == xProcessEC ) {
      (void)sprintf(Temp, "  Process        : %s\n", UnitP->Name);
      xPrintString(Temp);
    }
    else if ( UnitP->EC == xProcessTypeEC ) {
      (void)sprintf(Temp, "  Process type   : %s\n", UnitP->Name);
      xPrintString(Temp);
    }
    else if ( UnitP->EC == xServiceEC ) {
      (void)sprintf(Temp, "  Service        : %s\n", UnitP->Name);
      xPrintString(Temp);
    }
    else if ( UnitP->EC == xServiceTypeEC ) {
      (void)sprintf(Temp, "  Service type   : %s\n", UnitP->Name);
      xPrintString(Temp);
    }
    else if ( UnitP->EC == xProcedureEC ) {
      (void)sprintf(Temp, "  Procedure      : %s\n", UnitP->Name);
      xPrintString(Temp);
    }
    else if ( UnitP->EC == xOperatorEC ) {
      (void)sprintf(Temp, "  Operator       : %s\n", UnitP->Name);
      xPrintString(Temp);
    }
  }
#endif
       /* XIDNAMES */
  xPrintString("************************************************************\n");
}
#endif
       /* XEOUTPUT || XOPERRORF || XERANGE || XEEXPORT ||
          XEINDEX || XEDECISION || XASSERT */


#ifdef XEOUTPUT
/*---+---------------------------------------------------------------
     xSDLOutputError
-------------------------------------------------------------------*/
void xSDLOutputError(
  int          ErrorNumber,
  xSignalNode  S,
  int          NrReceivers )
{
  char  Temp[256];
#ifdef XIDNAMES
  xPrintString("\n************************** WARNING *************************");
  (void)sprintf(Temp, "\nWarning in SDL Output of signal %s\n",
                S->NameNode->Name);
  xPrintString(Temp);
#else
  xPrintString("\nWarning in SDL Output\n");
#endif
  if (ErrorNumber == 1) {
    if (NrReceivers == -1)
      xPrintString("No path to receiver, signal discarded\n");
    else if (NrReceivers == 0)
      xPrintString("No possible receiver found, signal discarded\n");
  } else if (ErrorNumber == 2) {
    xPrintString("Signal sent to environment, signal discarded\n");
  } else if (ErrorNumber == 3) {
    xPrintString("Signal sent to stopped process instance. Signal discarded\n");
  } else if (ErrorNumber == 4) {
    xPrintString("Signal sent to NULL, signal discarded\n");
  } else if (ErrorNumber == 5) {
    xPrintString("Illegal signal type in output TRANSFER. Signal discarded\n");
  }

#ifdef XIDNAMES
  (void)sprintf(Temp, "Sender: %s\n", xWri_SDL_PId(&S->Sender));
  xPrintString(Temp);
  if ( !xEq_SDL_PId_NULL(S->Receiver) ) {
    (void)sprintf(Temp, "Receiver: %s\n", xWri_SDL_PId(&S->Receiver));
    xPrintString(Temp);
  }
#endif
  if ( (S->Sender.GlobalNodeNr == xGlobalNodeNumber()) &&
       (S->Sender.LocalPId != (xLocalPIdNode)0) )
    xSDLDynamicErrorInfo(S->Sender.LocalPId->PrsP);
#ifdef XMONITOR
  xSysD.xDynamicError = (xbool)1;
#endif
}
#endif
       /* XEOUTPUT */


#ifdef XOPERRORF
/*---+---------------------------------------------------------------
     xSDLOpError
-------------------------------------------------------------------*/
void xSDLOpError(
  char  *OpName,
  char  *ErrText )
{
  char  Temp[256];
#ifdef XMONITOR
  if (! xSysD.xDynamicError) {
#endif
    xPrintString("\n*************************** ERROR **************************");
    (void)sprintf(Temp, "\nError in SDL Operator:\n  %s\n  %s\n",
                  OpName, ErrText);
    xPrintString(Temp);
    xSDLDynamicErrorInfo(xSysD.xReadyQueue->Suc);
#ifdef XMONITOR
    xSysD.xDynamicError = (xbool)1;
  }
#endif
}
#endif
       /* XOPERRORF */


#ifdef XERANGE
/*---+---------------------------------------------------------------
     xErrorSubrange
-------------------------------------------------------------------*/
void xErrorSubrange(
  tSDLTypeInfo *SortNode,
  void         *Value)
{
#ifdef XMONITOR
  if (! xSysD.xDynamicError) {
#endif
    xPrintString("\n*************************** ERROR **************************");
#ifdef T_SDL_NAMES
    xWriteBuf_Fmt("\nError in assignment in sort %s:\n  ", SortNode->Name);
    xxWriteSort(Value, SortNode);
    xPrintString(" out of range\n");
#else
    xPrintString("\nError in assignment: Value out of range\n");
#endif
    xSDLDynamicErrorInfo(xSysD.xReadyQueue->Suc);
#ifdef XMONITOR
    xSysD.xDynamicError = (xbool)1;
  }
#endif
}
#endif
       /* XERANGE */


#ifdef XEINDEX
/*---+---------------------------------------------------------------
     xErrorIndex
-------------------------------------------------------------------*/
void xErrorIndex(
  tSDLTypeInfo *SortNode,
  void         *Value)
{
#ifdef XMONITOR
  if (! xSysD.xDynamicError) {
#endif
    xPrintString("\n*************************** ERROR **************************");
#ifdef T_SDL_NAMES
    xWriteBuf_Fmt("\nError in SDL array index in sort %s:\n  ", SortNode->Name);
    xxWriteSort(Value, SortNode);
    xPrintString(" out of range\n");
#else
    xPrintString("\nError in SDL array index: Index out of range\n");
#endif
    xSDLDynamicErrorInfo(xSysD.xReadyQueue->Suc);
#ifdef XMONITOR
    xSysD.xDynamicError = (xbool)1;
  }
#endif
}
#endif
       /* XEINDEX */


#ifdef XEDECISION
/*---+---------------------------------------------------------------
     xErrorDecision
-------------------------------------------------------------------*/
void xErrorDecision (tSDLTypeInfo *SortNode, void *Value )
{
  xPrintString("\n*************************** ERROR **************************");
  xPrintString("\nError in SDL Decision: Value is ");
  xxWriteSort(Value, SortNode);
  xPrintString(":\n\nEntering decision error state\n");
  xSDLDynamicErrorInfo(xSysD.xReadyQueue->Suc);
#ifdef XTRACE
  xSysD.xSilent++;
#endif
#ifdef XMSCE
  xSysD.xSilentMSCE++;
#endif
  SDL_NextState(xSysD.xReadyQueue->Suc, ERROR_STATE);
#ifdef XTRACE
  xSysD.xSilent--;
#endif
#ifdef XMSCE
  xSysD.xSilentMSCE--;
#endif
#ifdef XMONITOR
  xSysD.xDynamicError = (xbool)1;
#endif
}
#endif
       /* XEDECISION */


#ifdef XECREATE
/*---+---------------------------------------------------------------
     xSDLCreateError
-------------------------------------------------------------------*/
static void xSDLCreateError (xPrsIdNode PrsId )
{
#ifdef XIDNAMES
  char  Temp[256];

  xPrintString("\n*************************** ERROR **************************");
  (void)sprintf(Temp, "\nError in SDL Create: Process %s\n", PrsId->Name);
  xPrintString(Temp);
#else
  xPrintString("\nError in SDL Create\n");
#endif
  xPrintString("More static instances then maximum number of instances.\n");
}
#endif
       /* XECREATE */


#ifdef XEEXPORT
/*---+---------------------------------------------------------------
     xSDLExportError
-------------------------------------------------------------------*/
static void xSDLExportError(
  char            *Mess,
  SDL_PId          P,
  xRemoteVarIdNode RemoteVarNode )
{
  char  Temp[2 * 256];
  xPrintString("\n*************************** ERROR **************************");
#if defined(XIDNAMES)
  (void)sprintf(Temp, "\nError in SDL Import: %s\nRemote variable: %s\n",
                Mess, RemoteVarNode->Name);
  xPrintString(Temp);
  if ( !xEq_SDL_PId_NULL(P) ) {
    (void)sprintf(Temp, "Importing from process: %s\n", xWri_SDL_PId(&P));
    xPrintString(Temp);
  }
#else
  (void)sprintf(Temp, "\nError in SDL Import: %s\n", Mess);
  xPrintString(Temp);
#endif
  xSDLDynamicErrorInfo(xSysD.xReadyQueue->Suc);
#ifdef XMONITOR
  xSysD.xDynamicError = (xbool)1;
#endif
}
#endif
       /* XEEXPORT */


#ifdef XEVIEW
/*---+---------------------------------------------------------------
     xSDLViewError
-------------------------------------------------------------------*/
static void xSDLViewError(
  char     *Mess,
  SDL_PId   P,
  char     *VarName )
{
  char  Temp[2 * 256];
  xPrintString("\n*************************** ERROR **************************");
  (void)sprintf(Temp, "\nError in SDL View: %s\nViewed variable: %s\n",
                Mess, VarName);
  xPrintString(Temp);
#if defined(XIDNAMES)
  if ( !xEq_SDL_PId_NULL(P) ) {
    (void)sprintf(Temp, "Viewing from process: %s\n", xWri_SDL_PId(&P));
    xPrintString(Temp);
  }
#endif
  xSDLDynamicErrorInfo(xSysD.xReadyQueue->Suc);
#ifdef XMONITOR
  xSysD.xDynamicError = (xbool)1;
#endif
}
#endif
       /* XEEXPORT */


/*---+---------------------------------------------------------------
     SDL_Error
-------------------------------------------------------------------*/
void * SDL_Error (int Size)
{
  void * LargeData;

#ifdef XEERROR
  xPrintString("\n*************************** ERROR **************************");
  xPrintString("\nUser specified error: SDL error expression found\n\n");
  xSDLDynamicErrorInfo(xSysD.xReadyQueue->Suc);
#ifdef XMONITOR
  xSysD.xDynamicError = (xbool)1;
#endif
#endif
  if (Size <= XTEMPDATA_SIZE) {
    (void)memset((void *)xData, 0, Size);
    return (void *)xData;
  } else {
    LargeData = xAlloc(Size);   /* NOTE! memory leak */
    (void)memset(LargeData, 0, Size);
    return LargeData;
  }
}


#ifdef XASSERT
/*---+---------------------------------------------------------------
     xAssertError
-------------------------------------------------------------------*/
void xAssertError (char *Descr)
{
  xPrintString("\n************************* ASSERTION ************************");
  xPrintString("\nAssertion is false:\n");
  xPrintString(Descr);
  xPrintString("\n");
  xSDLDynamicErrorInfo(xSysD.xReadyQueue->Suc);
#ifdef XMONITOR
  xSysD.xDynamicError = (xbool)1;
#endif
}
#endif
       /* XASSERT */


#ifdef XEUNION
/*---+---------------------------------------------------------------
     xUnionTagError
-------------------------------------------------------------------*/
void xUnionTagError (
   char *CompName,
   void *Value,
   tSDLTypeInfo *Sort,
   xbool IsAssign )
{
  xPrintString("\n*************************** ERROR **************************");
  if (IsAssign)
    xPrintString("\nIllegal #UNION tag value for assignment to component ");
  else
    xPrintString("\nIllegal #UNION tag value for access to component ");
  xPrintString(CompName);
  xPrintString(".\nTag value is ");
  xxWriteSort(Value, Sort);
  xPrintString("\n");
  xSDLDynamicErrorInfo(xSysD.xReadyQueue->Suc);
#ifdef XMONITOR
  xSysD.xDynamicError = (xbool)1;
#endif
}
#endif
       /* XEUNION */


#ifdef XEOPTIONAL
/*---+---------------------------------------------------------------
     xOptionalError
-------------------------------------------------------------------*/
void xOptionalError (char *CompName)
{
  xPrintString("\n*************************** ERROR **************************");
  xPrintString("\nError when accessing component ");
  xPrintString(CompName);
  xPrintString(". Component is not Present.\n");
  xSDLDynamicErrorInfo(xSysD.xReadyQueue->Suc);
#ifdef XMONITOR
  xSysD.xDynamicError = (xbool)1;
#endif
}
#endif
       /* XEOPTIONAL */


#ifdef XECODER
/*---+---------------------------------------------------------------
     xCoderError (Called from coder library only)
-------------------------------------------------------------------*/
void xCoderError (
   char *messageType,
   char *messageInfo)
{
  xPrintString("\n*************************** ERROR **************************");
  xPrintString("\nError when encoding or decoding ");
  xPrintString(messageType);
  xPrintString(messageInfo);
  xPrintString("\n");
  xSDLDynamicErrorInfo(xSysD.xReadyQueue->Suc);
#ifdef XMONITOR
  xSysD.xDynamicError = (xbool)1;
#endif
}
#endif
       /* XECODER */

#ifdef XECHOICE
/*---+---------------------------------------------------------------
     xChoiceError
-------------------------------------------------------------------*/
void xChoiceError (
   char *CompName,
   void *Value,
   tSDLTypeInfo *Sort )
{
  xPrintString("\n*************************** ERROR **************************");
  xPrintString("\nComponent ");
  xPrintString(CompName);
  xPrintString(" is not active.\nPresent is ");
  xxWriteSort(Value, Sort);
  xPrintString("\n");
  xSDLDynamicErrorInfo(xSysD.xReadyQueue->Suc);
#ifdef XMONITOR
  xSysD.xDynamicError = (xbool)1;
#endif
}
#endif
       /* XECHOICE */


#ifdef XEREF
/*---+---------------------------------------------------------------
     xRefError
-------------------------------------------------------------------*/
void xRefError (
   void        *NewData,
   tSDLGenInfo *RefTypeInfo)
{
  xbool tmp;
  tmp = XNEWREF_SYNTAX;
  XNEWREF_SYNTAX = (xbool)0;
  xPrintString("\n*************************** ERROR **************************");
  xPrintString("\nDereferencing of NULL pointer.");
  xPrintString("\nPointer assigned new data area at address ");
  /*xPrintString(xWriteSort(NewData, RefTypeInfo));  */         /*JK*/
  xPrintString(".\n");
  XNEWREF_SYNTAX = tmp;
  xSDLDynamicErrorInfo(xSysD.xReadyQueue->Suc);
#ifdef XMONITOR
  xSysD.xDynamicError = (xbool)1;
#endif
}
#endif
       /* XEREF */



/****+***************************************************************
05   Other routines used by generated code
********************************************************************/

/****+***************************************************************
06   Get and Release of IdNode
********************************************************************/

#if defined(XSYMBTLINK) || defined(XCOVERAGE)  || defined(XMONITOR)
/*---+---------------------------------------------------------------
     xInsertIdNode
-------------------------------------------------------------------*/
void xInsertIdNode (xIdNode Node)
{
  xIdNode  TempId;
#ifdef XCOVERAGE
  int      i;
#endif

#ifdef XSYMBTLINK
  Node->First = (xIdNode)0;
  Node->Suc   = (xIdNode)0;
  if (Node->Parent != (xIdNode)0) {
    TempId = Node->Parent->First;
    if (TempId == (xIdNode)0) {
      Node->Parent->First = Node;
    } else {
      while (TempId->Suc != (xIdNode)0) {
        TempId = TempId->Suc;
      }
      TempId->Suc = Node;
    }
  }
#endif

#ifdef XCOVERAGE
  switch (Node->EC) {

  case xProcessEC :
  case xProcessTypeEC :
    if (Node->EC == xProcessTypeEC ||
        ((xPrsIdNode)Node)->Super == (xPrsIdNode)0) {
      for (i=0; i <= ((xPrsIdNode)Node)->MaxSymbolNumber; i++)
        ((xPrsIdNode)Node)->CoverageArray[i] = 0;
      ((xPrsIdNode)Node)->NoOfStartTransitions = 0;
      ((xPrsIdNode)Node)->MaxQueueLength = 0;
    }
    break;

#ifndef XNOUSEOFSERVICE
  case xServiceEC :
  case xServiceTypeEC :
    if (Node->EC == xServiceTypeEC ||
        ((xSrvIdNode)Node)->Super == (xSrvIdNode)0) {
      for (i=0; i <= ((xSrvIdNode)Node)->MaxSymbolNumber; i++)
        ((xSrvIdNode)Node)->CoverageArray[i] = 0;
      ((xSrvIdNode)Node)->NoOfStartTransitions = 0;
    }
    break;
#endif

  case xProcedureEC :
  case xOperatorEC :
    for (i=0; i <= ((xPrdIdNode)Node)->MaxSymbolNumber; i++)
      ((xPrdIdNode)Node)->CoverageArray[i] = 0;
    break;

  case xStateEC :
    TempId = Node->Parent;
    if (TempId->EC == xProcedureEC || TempId->EC == xOperatorEC) {
      for (i=0; i <= ((xPrdIdNode)TempId)->SignalSetLength; i++)
        ((xStateIdNode)Node)->CoverageArray[i] = 0;
#ifndef XNOUSEOFSERVICE
    } else if (TempId->EC == xServiceEC || TempId->EC == xServiceTypeEC) {
      for (i=0; i <= ((xSrvIdNode)TempId)->SignalSetLength; i++)
        ((xStateIdNode)Node)->CoverageArray[i] = 0;
#endif
    } else {
      for (i=0; i <= ((xPrsIdNode)TempId)->SignalSetLength; i++)
        ((xStateIdNode)Node)->CoverageArray[i] = 0;
    }
    break;

  default :
    break;
  }
#endif


#ifdef XMONITOR
  switch (Node->EC) {
  case xProcessEC :
    ((xPrsIdNode)Node)->NextNr = 1;
    break;

  default :
    break;
  }
#endif


}
#endif
      /* XSYMBTLINK or XCOVERAGE or XMONITOR */


/*---+---------------------------------------------------------------
     xInsertExportedVar
-------------------------------------------------------------------*/
void xInsertExportedVar (
  xRemoteVarListNode  ExportedVarNode,
  xRemoteVarIdNode    RemoteVarNode )
{
  ExportedVarNode->Next = RemoteVarNode->RemoteList;
  RemoteVarNode->RemoteList = ExportedVarNode;
}


/*---+---------------------------------------------------------------
     xInsertExportedPrd
-------------------------------------------------------------------*/
void xInsertExportedPrd (
  xRemotePrdListNode  ExportedPrdNode,
  xRemotePrdIdNode    RemotePrdNode )
{
  ExportedPrdNode->Next = RemotePrdNode->RemoteList;
  RemotePrdNode->RemoteList = ExportedPrdNode;
}


/****+***************************************************************
08   Lists of xIdNode routines
********************************************************************/

/*---+---------------------------------------------------------------
     xInList
-------------------------------------------------------------------*/ 
xbool xInList(
  XSIGTYPE   Id,
  XSIGTYPE  *IdList )
{
  int  I;

  if ( IdList==(XSIGTYPE *)0 )
    return (xbool)0;
  for ( I=0; (IdList[I]!=(XSIGTYPE)0) && (IdList[I]!=Id); I++ ) ;
  return (xbool)(IdList[I]==Id);
}


/****+***************************************************************
09  Get and Release PId, Service, Signal, Prd
********************************************************************/

/*---+---------------------------------------------------------------
     xGetPId
-------------------------------------------------------------------*/
SDL_PId xGetPId(
  xPrsIdNode  PType,
  SDL_PId     Parent )
{
  SDL_PId   R;

  R.GlobalNodeNr = xGlobalNodeNumber();
  THREADED_LISTWRITE_START
  if ( *PType->AvailPrsList != (xPrsNode)0 ) {
    R.LocalPId = (*PType->AvailPrsList)->Self.LocalPId;
    *PType->AvailPrsList = R.LocalPId->PrsP->NextPrs;
    THREADED_LISTACCESS_END
    memset((void *)R.LocalPId->PrsP, 0, (xptrint)PType->VarSize);
#if defined(XPRSOPT) && !defined(XNRINST)
    R.LocalPId->InAvailList = (xbool)0;
#endif
  } else {
    THREADED_LISTACCESS_END
    R.LocalPId = (xLocalPIdNode)xAlloc((xptrint)sizeof(xLocalPIdRec));
    R.LocalPId->PrsP = (xPrsNode)xAlloc((xptrint)PType->VarSize);
  }
  R.LocalPId->PrsP->Self = R;
  R.LocalPId->PrsP->NameNode = PType;
  R.LocalPId->PrsP->InputPort.Pre =
    (xSignalNode)&R.LocalPId->PrsP->InputPort; 
  R.LocalPId->PrsP->InputPort.Suc = 
    (xSignalNode)&R.LocalPId->PrsP->InputPort; 
#ifdef XNRINST
  R.LocalPId->InstNr = PType->NextNr++;
#endif
  R.LocalPId->PrsP->State = START_STATE;
  if (PType->Super)
    R.LocalPId->PrsP->RestartPAD = PType->Super->PAD_Function;
  else
    R.LocalPId->PrsP->RestartPAD = PType->PAD_Function;
  R.LocalPId->PrsP->Offspring = SDL_NULL;
  R.LocalPId->PrsP->Parent = Parent;
  if ( Parent.LocalPId != (xLocalPIdNode)0 )
    Parent.LocalPId->PrsP->Offspring = R;
#ifdef XPRSSENDER
  R.LocalPId->PrsP->Sender = SDL_NULL;
#endif
#ifdef XTRACE
  R.LocalPId->PrsP->Trace_Default = -1;
#endif
#ifdef XGRTRACE
  R.LocalPId->PrsP->GRTrace = -1;
#endif
#ifdef XMSCE
  R.LocalPId->PrsP->MSCETrace = -1;
#endif
  R.LocalPId->PrsP->NextPrs = *PType->ActivePrsList;
  *PType->ActivePrsList = R.LocalPId->PrsP;

  /* the remaining elements should be 0, which is already true
     due to memset or xAlloc
  */
  return R;
}


/*---+---------------------------------------------------------------
     xReleasePId
-------------------------------------------------------------------*/
void xReleasePId (SDL_PId  *P)
{
  SDL_PId   NewP;
  xPrsNode *Temp;
  xPrsNode  PrsNode;

  PrsNode = (*P).LocalPId->PrsP;

  THREADED_LISTWRITE_START
  /* Remove P from Active List.*/
  Temp = PrsNode->NameNode->ActivePrsList;
  if ((*Temp) == PrsNode)
    (*Temp) = (*Temp)->NextPrs;
  else {
    while ((*Temp)->NextPrs != PrsNode)
      Temp = &(*Temp)->NextPrs;
    (*Temp)->NextPrs = (*Temp)->NextPrs->NextPrs;
  }
  /* Into avail list.*/
  PrsNode->NextPrs = *PrsNode->NameNode->AvailPrsList;
  *PrsNode->NameNode->AvailPrsList = PrsNode;
  THREADED_LISTACCESS_END

  /* Free local variables */
  if (PrsNode->NameNode->Free_Vars != 0)
    PrsNode->NameNode->Free_Vars((void *)PrsNode);
  else if (PrsNode->NameNode->Super!= 0 && PrsNode->NameNode->Super->Free_Vars != 0)
    PrsNode->NameNode->Super->Free_Vars((void *)PrsNode);

#ifndef XPRSOPT
  /*Create new xLocalPIdRec.*/
  NewP.GlobalNodeNr = xGlobalNodeNumber();
  NewP.LocalPId = (xLocalPIdNode)xAlloc((xptrint)sizeof(xLocalPIdRec));
  NewP.LocalPId->PrsP = PrsNode;
  PrsNode->Self = NewP;
#else
  NewP = *P;
#endif
#ifdef XNRINST
  if (NewP.LocalPId != (xLocalPIdNode)0)
    NewP.LocalPId->InstNr = 0;
#endif
#if defined(XPRSOPT) && !defined(XNRINST)
  if (NewP.LocalPId != (xLocalPIdNode)0)
    NewP.LocalPId->InAvailList = (xbool)1;
#endif
}


#ifndef XNOUSEOFSERVICE
/*---+---------------------------------------------------------------
     xGetService
-------------------------------------------------------------------*/
xSrvNode xGetService (xSrvIdNode SrvId, xPrsNode Process)
{
  xSrvNode Result;

  THREADED_LISTWRITE_START
  if ( *SrvId->AvailSrvList != (xSrvNode)0 ) {
    Result = *SrvId->AvailSrvList;
    *SrvId->AvailSrvList = Result->NextSrv;
    memset(Result, 0, (xptrint)SrvId->VarSize);
  } else {
    Result = (xSrvNode)xAlloc((xptrint)SrvId->VarSize);
  }
  THREADED_LISTACCESS_END
  Result->NextSrv = Process->SrvList;
  Process->SrvList = Result;
  Process->ActiveSrv = Result;
  Result->ContainerPrs = Process;
  if (SrvId->Super)
    Result->RestartPAD = SrvId->Super->PAD_Function;
  else
    Result->RestartPAD = SrvId->PAD_Function;
  Result->NameNode = SrvId;
  Result->State = START_STATE;

  /* the remaining elements should be 0, which is already true
     due to memset or xAlloc
  */
  return Result;
}


/*---+---------------------------------------------------------------
     xReleaseService
-------------------------------------------------------------------*/
void xReleaseService (xSrvNode  *S)
{
  xSrvNode Temp;

  if (*S != (xSrvNode)0) {
    THREADED_LISTWRITE_START
      /* Remove *S from Active List.*/
    Temp = (*S)->ContainerPrs->SrvList;
    if (Temp == (*S))
      Temp->ContainerPrs->SrvList = Temp->NextSrv;
    else {
      while (Temp->NextSrv != (*S))
        Temp = Temp->NextSrv;
      Temp->NextSrv = Temp->NextSrv->NextSrv;
    }
    /* Into avail list.*/
    (*S)->NextSrv = *(*S)->NameNode->AvailSrvList;
    *(*S)->NameNode->AvailSrvList = (*S);
    THREADED_LISTACCESS_END

    /* Free local variables */
    if ((*S)->NameNode->Free_Vars != 0)
      (*S)->NameNode->Free_Vars((void *)(*S));
    else if ((*S)->NameNode->Super!= 0 && (*S)->NameNode->Super->Free_Vars != 0)
      (*S)->NameNode->Super->Free_Vars((void *)(*S));

    *S = (xSrvNode)0;
  }
}
#endif

/*---+---------------------------------------------------------------
     xGetSignal
-------------------------------------------------------------------*/
xSignalNode xGetSignal( 
  XSIGTYPE  SType,
  SDL_PId   Receiver,
  SDL_PId   Sender )
{
  xSignalNode Result;

  THREADED_LISTWRITE_START
  if ((SType->EC == xSignalEC || SType->EC == xRPCSignalEC) &&
      SType->VarSize == (xptrint)sizeof(XSIGNALHEADERTYPE)) {
        /* Signal without parameters. Get from global avail list or perform alloc */
    if (xAvailSignal != (xSignalNode)0) {
      Result = xAvailSignal;
      xAvailSignal = Result->Suc;
      memset((void *)Result, 0, (xptrint)SType->VarSize);
    } else {
      Result = (xSignalNode)xAlloc((xptrint)SType->VarSize);
    }
  } else if (SType->EC == xTimerEC &&
      SType->VarSize == (xptrint)sizeof(XTIMERHEADERTYPE)) {
        /* Timer without parameters. Get from global avail list or perform alloc */
    if (xAvailTimer != (xSignalNode)0) {
      Result = xAvailTimer;
      xAvailTimer = Result->Suc;
      memset((void *)Result, 0, (xptrint)SType->VarSize);
    } else {
      Result = (xSignalNode)xAlloc((xptrint)SType->VarSize);
    }
  } else if (*SType->AvailSignalList != (xSignalNode)0) {
       /* Signal/timer with parameters. Get from avail list for signal/timer type
          or perform alloc */
    Result = *SType->AvailSignalList;
    *SType->AvailSignalList = Result->Suc;
    memset((void *)Result, 0, (xptrint)SType->VarSize);
  } else {
    Result = (xSignalNode)xAlloc((xptrint)SType->VarSize);
  }
  THREADED_LISTACCESS_END
  Result->Sender = Sender;
  Result->Receiver = Receiver;
  Result->NameNode = SType;
#if defined(XSIGPRIO) || defined(XSIGPRSPRIO) || defined(XPRSSIGPRIO)
  Result->Prio = xDefaultPrioSignal;
#endif
#ifdef XENV_CONFORM_2_3
  Result->VarP = (void *)Result;
#endif

  /* the remaining elements should be 0, which is already true
     due to memset or xAlloc
  */
  return Result;
}


/*---+---------------------------------------------------------------
     xReleaseSignalNotPara
-------------------------------------------------------------------*/
void xReleaseSignalNotPara (xSignalNode  *S)
{
  if (*S != (xSignalNode)0) {
    THREADED_LISTWRITE_START
       /* Signal without parameters into global avail list */
    if (((*S)->NameNode->EC == xSignalEC || (*S)->NameNode->EC == xRPCSignalEC)&&
        (*S)->NameNode->VarSize == (xptrint)sizeof(XSIGNALHEADERTYPE)) {
      (*S)->Suc = xAvailSignal;
      xAvailSignal = *S;

       /* Timer without parameters into global avail list */
    } else if ((*S)->NameNode->EC == xTimerEC &&
        (*S)->NameNode->VarSize == (xptrint)sizeof(XTIMERHEADERTYPE)) {
      (*S)->Suc = xAvailTimer;
      xAvailTimer = *S;

       /* Signal/Timer with parameters into avail list for signal/timer type */
    } else {
      (*S)->Suc = *(*S)->NameNode->AvailSignalList;
      *(*S)->NameNode->AvailSignalList = *S;
    }
    *S = (xSignalNode)0;
    THREADED_LISTACCESS_END
  }
}


/*---+---------------------------------------------------------------
     xReleaseSignal
-------------------------------------------------------------------*/
void xReleaseSignal (xSignalNode  *S)
{
  if (*S != (xSignalNode)0) {
    if ((*S)->NameNode->Free_Signal != 0)
      (*S)->NameNode->Free_Signal((void *)(*S));
    xReleaseSignalNotPara(S);
  }
}


/*---+---------------------------------------------------------------
     xGetPrd
-------------------------------------------------------------------*/
xPrdNode xGetPrd (xPrdIdNode  PrdId)
{
  xPrdNode R;

  THREADED_LISTWRITE_START
  if (*PrdId->AvailPrdList != (xPrdNode)0) {
    R = *PrdId->AvailPrdList;
    *PrdId->AvailPrdList = R->DynamicFather;
    memset(R, 0, PrdId->VarSize);
  } else {
    R = (xPrdNode)xAlloc((xptrint)PrdId->VarSize);
  }
  R->NameNode = PrdId;
  THREADED_LISTACCESS_END
  R->State = START_STATE_PRD;
  R->RestartPRD = PrdId->Assoc_Function;

  /* the remaining elements should be 0, which is already true
     due to memset or xAlloc
  */
  return R;
}


/*---+---------------------------------------------------------------
     xReleasePrd
-------------------------------------------------------------------*/
void xReleasePrd (xPrsNode VarP)
{
  xPrdNode ActivePrd;

  THREADED_LISTWRITE_START
#ifndef XNOUSEOFSERVICE
  if (VarP->ActiveSrv != (xSrvNode)0) {
    ActivePrd = VarP->ActiveSrv->ActivePrd;
    VarP->ActiveSrv->ActivePrd = ActivePrd->DynamicFather;
  } else {
#endif
    ActivePrd = VarP->ActivePrd;
    VarP->ActivePrd = ActivePrd->DynamicFather;
#ifndef XNOUSEOFSERVICE
  }
#endif
  THREADED_LISTACCESS_END
#if defined (XTRACE) || defined (THREADED_XTRACE)
  xTraceProcedureReturn(ActivePrd);
#endif
#ifdef XMSCE
  xMSCEProcedureReturn(VarP, ActivePrd);
#endif

  /* Free local variables */
  if (ActivePrd->NameNode->Free_Vars != 0)
    ActivePrd->NameNode->Free_Vars((void *)ActivePrd);

  ActivePrd->DynamicFather = *ActivePrd->NameNode->AvailPrdList;
  *ActivePrd->NameNode->AvailPrdList = ActivePrd;
}


/****+***************************************************************
13   Prd call function
********************************************************************/

/*---+---------------------------------------------------------------
     xAddPrdCall
-------------------------------------------------------------------*/
void xAddPrdCall(
  xPrdNode   R,
  xPrsNode   VarP,
  int        StaticFatherLevel,
  int        RestartAddress )
{
  xPrdNode  TempStaticFather;
  int       i;

#if defined (XTRACE) || defined (THREADED_XTRACE)
  xTraceProcedureStart(R);
#endif
#ifdef XMSCE
  xMSCEProcedureStart(VarP, R);
#endif
#ifndef XNOUSEOFSERVICE
  if ( VarP->ActiveSrv != (xSrvNode)0 ) {
    if ( VarP->ActiveSrv->ActivePrd == (xPrdNode)0 ) {
      R->DynamicFather = (xPrdNode)0;
      R->StaticFather = (xPrdNode)0;
      VarP->ActiveSrv->ActivePrd = R;
      VarP->ActiveSrv->RestartAddress = RestartAddress;
#ifdef XMONITOR
      VarP->ActiveSrv->CallAddress = xSysD.xCurrentSymbolNumber;
#endif
    } else {
      R->DynamicFather = VarP->ActiveSrv->ActivePrd;
      VarP->ActiveSrv->ActivePrd = R;
      if (StaticFatherLevel >= 0) {
        TempStaticFather = R->DynamicFather;
        for (i = 1; i<=StaticFatherLevel; i++)
          TempStaticFather = TempStaticFather->StaticFather;
        R->StaticFather = TempStaticFather;
      }
      R->DynamicFather->RestartAddress = RestartAddress;
#ifdef XMONITOR
      R->DynamicFather->CallAddress = xSysD.xCurrentSymbolNumber;
#endif
    }
  } else {
#endif
    if ( VarP->ActivePrd == (xPrdNode)0 ) {
      R->DynamicFather = (xPrdNode)0;
      R->StaticFather = (xPrdNode)0;
      VarP->ActivePrd = R;
      VarP->RestartAddress = RestartAddress;
#ifdef XMONITOR
      VarP->CallAddress = xSysD.xCurrentSymbolNumber;
#endif
    } else {
      R->DynamicFather = VarP->ActivePrd;
      VarP->ActivePrd = R;
      if (StaticFatherLevel >= 0) {
        TempStaticFather = R->DynamicFather;
        for (i = 1; i<=StaticFatherLevel; i++)
          TempStaticFather = TempStaticFather->StaticFather;
        R->StaticFather = TempStaticFather;
      }
      R->DynamicFather->RestartAddress = RestartAddress;
#ifdef XMONITOR
      R->DynamicFather->CallAddress = xSysD.xCurrentSymbolNumber;
#endif
    }
#ifndef XNOUSEOFSERVICE
  }
#endif
}


/****+***************************************************************
16   Queue routines and CheckList routines
********************************************************************/

/*---+---------------------------------------------------------------
     xNoOfActivePrs
-------------------------------------------------------------------*/
static int xNoOfActivePrs(
  xPrsIdNode  PrsType,
  int         BlockInstNumber )
{
  int      Result = 0;
  xPrsNode Temp;

  THREADED_LISTREAD_START
  for (Temp = *PrsType->ActivePrsList;
       Temp != (xPrsNode)0;
       Temp = Temp->NextPrs)
    if (Temp->BlockInstNumber == BlockInstNumber) Result++;
  THREADED_LISTACCESS_END
  return Result;
}


/*---+---------------------------------------------------------------
     xFindInst
-------------------------------------------------------------------*/
static xPrsNode xFindInst(
  xPrsIdNode  InPrsType,
  SDL_PId     InSameBlockInstAs )
{
  xPrsNode Temp, Result;
  if (InPrsType->InBlockInst != (xBlockIdNode)0 &&
      InSameBlockInstAs.LocalPId != 0 &&
      XPID_TO_PRS(InSameBlockInstAs)->NameNode->InBlockInst == 
        InPrsType->InBlockInst) {
    Result = (xPrsNode)0;
    THREADED_LISTREAD_START
    for (Temp = *InPrsType->ActivePrsList;
         Temp != (xPrsNode)0 && Result == (xPrsNode)0;
         Temp = Temp->NextPrs) {
      if (Temp->BlockInstNumber ==
          XPID_TO_PRS(InSameBlockInstAs)->BlockInstNumber)
        Result = Temp;
    }
    THREADED_LISTACCESS_END
    return Result;
  }
  THREADED_LISTREAD_START
  Result = *InPrsType->ActivePrsList;
  THREADED_LISTACCESS_END
  return Result;
}


/*---+---------------------------------------------------------------
     xInsertPrsIntoQueue
-------------------------------------------------------------------*/
/* This routine inserts NewPrsP immediately after PrsP in the same list
   as PrsP is member of. If NewPrsP is already is member of a list it
   is first removed from that list. */

static void xInsertPrsIntoQueue(
  xPrsNode  NewPrsP,
  xPrsNode  PrsP )
{
#if defined(XSIGPRIO) || defined(XSIGPRSPRIO) || defined(XPRSSIGPRIO)
  if (NewPrsP == PrsP)
    return;
#endif
  if ( NewPrsP->Suc != (xPrsNode)0 ) {
    NewPrsP->Suc->Pre = NewPrsP->Pre;
    NewPrsP->Pre->Suc = NewPrsP->Suc;
  }
  NewPrsP->Pre = PrsP;
  NewPrsP->Suc = PrsP->Suc;
  PrsP->Suc->Pre = NewPrsP;
  PrsP->Suc = NewPrsP;
}


/*---+---------------------------------------------------------------
     xCheckCheckList
-------------------------------------------------------------------*/
static void xCheckCheckList (xPrsNode CheckList)
{
  xPrsNode PrsP, NextPrsP;

#ifdef XTRACE
  xSysD.xSilent++;
#endif
#ifdef XMSCE
  xSysD.xSilentMSCE++;
#endif
  PrsP = CheckList->Suc;
  while ( PrsP != CheckList ) {
    NextPrsP = PrsP->Suc;
    SDL_NextState(PrsP, xFindState(PrsP));
    PrsP = NextPrsP;
  }
#ifdef XTRACE
  xSysD.xSilent--;
#endif
#ifdef XMSCE
  xSysD.xSilentMSCE--;
#endif
}


/*---+---------------------------------------------------------------
     xContentsInstNode
-------------------------------------------------------------------*/
/* Given the IdNode for the currently executing unit (process,
   service, procedure), and the IdNode for a container type 
   (block type for example), this function returns the IdNode
   for the container instance. */

xIdNode xContentsInstNode (
  xIdNode  CurrentInst,
  xIdNode  TypeToFindInstOf )
{
  xIdNode TypeNode;
  TypeNode = CurrentInst;
  while (TypeNode != TypeToFindInstOf) {
    if (TypeNode->EC == xSystemTypeEC || TypeNode->EC == xSystemEC)
      TypeNode = (xIdNode)((xSystemIdNode)TypeNode)->Super;
    else if (TypeNode->EC == xBlockTypeEC || TypeNode->EC == xBlockEC)
      TypeNode = (xIdNode)((xBlockIdNode)TypeNode)->Super;
    else if (TypeNode->EC == xProcessTypeEC || TypeNode->EC == xProcessEC)
      TypeNode = (xIdNode)((xPrsIdNode)TypeNode)->Super;
#ifndef XNOUSEOFSERVICE
    else if (TypeNode->EC == xServiceTypeEC || TypeNode->EC == xServiceEC)
      TypeNode = (xIdNode)((xSrvIdNode)TypeNode)->Super;
#endif
    else if (TypeNode->EC == xProcedureEC)
      TypeNode = (xIdNode)((xPrdIdNode)TypeNode)->Super;
    else
      TypeNode = (xIdNode)0;
    if (TypeNode == (xIdNode)0) {
      CurrentInst = CurrentInst->Parent;
      TypeNode = CurrentInst;
    }
  }
  return CurrentInst;
}


/*---+---------------------------------------------------------------
     xPrsInst
-------------------------------------------------------------------*/
/* Given the IdNode for the currently executing process and the IdNode
   for a container type (block type for example), this function finds
   the container instance and returns the xPrsIdNode and index Index
   in the containers Contents array. */

xPrsIdNode xPrsInst(
  xIdNode  CurrentInst,
  xIdNode  TypeToFindInstOf,
  int      Index)
{
  xIdNode  ScopeInst;
  ScopeInst = xContentsInstNode(CurrentInst, TypeToFindInstOf);
  if (ScopeInst->EC == xSystemEC)
    return (xPrsIdNode)((xSystemIdNode)ScopeInst)->Contents[Index];
  return (xPrsIdNode)((xBlockIdNode)ScopeInst)->Contents[Index];
}


#ifdef THREADED
/*---+---------------------------------------------------------------
     
-------------------------------------------------------------------*/
SDL_PId SDL_TO_Process (xPrsIdNode PrsId)
{
  SDL_PId Rec;
  THREADED_LISTREAD_START
  Rec =
#ifdef XMULTIPLESYSTEMS
    PrsId == xEnvId
    ? xNotDefPId
    :
#endif
      ( *PrsId->ActivePrsList != (xPrsNode)0
         ? (*PrsId->ActivePrsList)->Self
         : SDL_NULL
      )
    ;
  THREADED_LISTACCESS_END
  return Rec;
}
#endif


/****+***************************************************************
14   Path routines
********************************************************************/

#if defined(XEOUTPUT) || defined(XMONITOR)
        /* function only used for error checks ! */
/*---+---------------------------------------------------------------
     xIsPath
-------------------------------------------------------------------*/
int xIsPath(
  XSIGTYPE     SignalId,
  xIdNode      SenderId,
  xPrsIdNode   ReceiverId,
  xIdNode     *ViaList
#ifdef XSIGPATH
                      ,
  xIdNode      Path[],
  int         *PathLength
#endif
  )
{
#ifndef XSIGPATH
  xIdNode  Path[xSizeOfPathStack];
#endif
  int      PathLen;
  int      Index[xSizeOfPathStack];
  xIdNode  TempId;

  if ( SenderId == (xIdNode)ReceiverId )
    return 1;
#ifndef XNOUSEOFSERVICE
  if ( SenderId->EC == xServiceEC &&
       SenderId->Parent == (xIdNode)ReceiverId &&
       xInList(SignalId, ((xSrvIdNode)SenderId)->SignalSet) )
    return 1;
#endif
  Path[0] = SenderId;
  PathLen = 1;
  Index[1] = -1;
  while ( PathLen > 0 ){
    Index[PathLen]++;
    if (PathLen==1) {
      if ( ViaList!=(xIdNode *)0 ) {
        TempId = ViaList[Index[1]];
        while ( (TempId != (xIdNode)0) && 
                !xInList(SignalId, ((xChannelIdNode)TempId)->SignalSet) ) {
          Index[1]++;
          TempId = ViaList[Index[1]];
        }
      } else {
#ifndef XNOUSEOFSERVICE
        TempId = (SenderId->EC == xProcessEC
                  ? ((xPrsIdNode)SenderId)->ToId[Index[1]]
                  : ((xSrvIdNode)SenderId)->ToId[Index[1]]);
        while ( (TempId != (xIdNode)0) &&
                !xInList(SignalId, ( TempId->EC==xProcessEC
                                     ? ((xPrsIdNode)TempId)->SignalSet
                                     : ( TempId->EC==xServiceEC
                                         ? ((xSrvIdNode)TempId)->SignalSet
					 : ((xChannelIdNode)TempId)->SignalSet
                                       )
                                   )
                        )
              ) {
          Index[1]++;
          TempId = (SenderId->EC == xProcessEC
                    ? ((xPrsIdNode)SenderId)->ToId[Index[1]]
                    : ((xSrvIdNode)SenderId)->ToId[Index[1]]);
        }
#else
        TempId = ((xPrsIdNode)SenderId)->ToId[Index[1]];
        while ( (TempId != (xIdNode)0) && 
                !xInList(SignalId, (TempId->EC==xProcessEC
                                    ? ((xPrsIdNode)TempId)->SignalSet
                                    : ((xChannelIdNode)TempId)->SignalSet)) ) {
          Index[1]++;
          TempId = ((xPrsIdNode)SenderId)->ToId[Index[1]];
        }
#endif
      }
    } else
      TempId = ((xChannelIdNode)Path[PathLen-1])->ToId[Index[PathLen]];
    Path[PathLen] = TempId;
    if ( TempId == (xIdNode)0 )
      PathLen--;
    else if ( TempId->EC == xProcessEC ){
      if ( TempId == (xIdNode)ReceiverId ){
        if ( TempId == (xIdNode)xEnvId ||
             Path[PathLen-1]->EC == xSignalrouteEC ||
             ( Path[PathLen-1]->EC == xGateEC &&
               Path[PathLen-1]->Parent->EC == xProcessEC ) ||
             xInList(SignalId, ((xPrsIdNode)TempId)->SignalSet)
           ){
#ifdef XSIGPATH
          *PathLength = PathLen;
#endif
          return 1;
        } else {
          return -1;
        }
      }
#ifndef XNOUSEOFSERVICE
    } else if ( TempId->EC == xServiceEC ){
      if ( TempId->Parent == (xIdNode)ReceiverId &&
           xInList(SignalId, ((xSrvIdNode)TempId)->SignalSet) ){
#ifdef XSIGPATH
        *PathLength = PathLen;
#endif
        return 1;
      }
#endif
    } else if ( xInList(SignalId, ((xChannelIdNode)TempId)->SignalSet) ) {
      PathLen++;
      Index[PathLen] = -1;
    }
  }      /* while PathLen */
  return -1;
}
#endif
       /* XEOUTPUT || XMONITOR */


#ifndef XOPTCHAN
/*---+---------------------------------------------------------------
     xFindReceiver
-------------------------------------------------------------------*/
#ifdef XSIGPATH
SDL_PId xFindReceiver(
  XSIGTYPE     SignalId,   /* Signal identification */
  SDL_PId      SenderPId,  /* xIdNode for sender */
  xIdNode     *ViaList,    /* The via list, i.e. list of xIdNodes */
  int         *NrOfRec,    /* OUT: Number of possible receivers */
  xIdNode     *Path,       /* OUT: The path array */
  int         *PathLength) /* OUT: Length of Path */
#else
SDL_PId xFindReceiver(
  XSIGTYPE     SignalId,   /* Signal identification */
  SDL_PId      SenderPId,  /* xIdNode for sender */
  xIdNode     *ViaList,    /* The via list, i.e. list of xIdNodes */
  int         *NrOfRec,    /* OUT: Number of possible receivers */
  xIdNode     *ChannelId)  /* OUT: xIdNode for signal to env */
#endif
{
  xIdNode    CPath[xSizeOfPathStack];
  int        CPathLength;
  int        CIndex[xSizeOfPathStack];
  xIdNode    SenderId;
  xIdNode    TempId = (xIdNode)0;
#ifdef XSIGPATH
  int        TempNr;
#endif
  xPrsNode   Prs;

#ifndef XSIGPATH
  *ChannelId = (xIdNode)0;
#endif

  *NrOfRec = 0;
  if ( XIS_PID_IN_SYSTEM(SenderPId) ) {
#ifndef XNOUSEOFSERVICE
    if (XPID_TO_PRS(SenderPId)->ActiveSrv != (xSrvNode)0)
      SenderId = (xIdNode)XPID_TO_PRS(SenderPId)->ActiveSrv->NameNode;
    else
#endif
      SenderId = (xIdNode)XPID_TO_PRS(SenderPId)->NameNode;
    if ( ViaList == (xIdNode *)0 &&
         SenderId != (xIdNode)xEnvId &&
#ifndef XNOUSEOFSERVICE
         xInList(SignalId, ( SenderId->EC==xProcessEC
                             ?((xPrsIdNode)SenderId)->SignalSet
                             :((xSrvIdNode)SenderId)->SignalSet )
                )
#else
         xInList(SignalId, ((xPrsIdNode)SenderId)->SignalSet)
#endif
       ) {
      *NrOfRec = 1;
      return SenderPId;
    }
  } else {
    SenderId = (xIdNode)xEnvId;
  }

  CPath[0] = SenderId;
  CPathLength = 1;
  CIndex[1] = -1;
  while ( CPathLength > 0 ) {
    CIndex[CPathLength]++;
    if ( CPathLength == 1 ) {
      /* CPathLength == 1 means that we start from the sending process */
      if ( ViaList != (xIdNode *)0 ) {
        /* If VIA list then try the items in the list */
        TempId = ViaList[CIndex[1]];
        if (TempId != (xIdNode)0 &&
            ((xChannelIdNode)TempId)->ToId[0] == SenderId)
          TempId = (xIdNode)((xChannelIdNode)TempId)->Reverse;
        while ( (TempId != (xIdNode)0) && 
                !xInList(SignalId, ((xChannelIdNode)TempId)->SignalSet) ) {
          CIndex[1]++;
          TempId = ViaList[CIndex[1]];
          if (TempId != (xIdNode)0 &&
              ((xChannelIdNode)TempId)->ToId[0] == SenderId)
            TempId = (xIdNode)((xChannelIdNode)TempId)->Reverse;
        }
      } else {
      /* If not VIA list try all outgoing paths from sending process/service */
#ifndef XNOUSEOFSERVICE
        TempId = (SenderId->EC == xProcessEC
                  ? ((xPrsIdNode)SenderId)->ToId[CIndex[1]]
                  : ((xSrvIdNode)SenderId)->ToId[CIndex[1]]);
        while ( (TempId != (xIdNode)0) &&
                !xInList(SignalId, ( TempId->EC==xProcessEC
                                     ? ((xPrsIdNode)TempId)->SignalSet
                                     : ( TempId->EC==xServiceEC
                                         ? ((xSrvIdNode)TempId)->SignalSet
					 : ((xChannelIdNode)TempId)->SignalSet
                                       )
                                   )
                        )
              ) {
          CIndex[1]++;
          TempId = (SenderId->EC == xProcessEC
                    ? ((xPrsIdNode)SenderId)->ToId[CIndex[1]]
                    : ((xSrvIdNode)SenderId)->ToId[CIndex[1]]);
        }
#else
        TempId = ((xPrsIdNode)SenderId)->ToId[CIndex[1]];
        while ( (TempId != (xIdNode)0) &&
                !xInList(SignalId, (TempId->EC==xProcessEC
                                    ? ((xPrsIdNode)TempId)->SignalSet
                                    : ((xChannelIdNode)TempId)->SignalSet))
              ) {
          CIndex[1]++;
          TempId = ((xPrsIdNode)SenderId)->ToId[CIndex[1]];
        }
#endif
      }
    } else {
      /* CPathLength != 1 means that we are handling a channel
         a signal route, or a gate */
      TempId = ((xChannelIdNode)CPath[CPathLength-1])->ToId[CIndex[CPathLength]];
    }

    CPath[CPathLength] = TempId;
    if ( TempId == (xIdNode)0 )
      CPathLength--;
    else if (TempId->EC == xProcessEC
#ifndef XNOUSEOFSERVICE
             ||
             TempId->EC == xServiceEC
#endif
            ) {
      if ( ( TempId->EC == xProcessEC &&
                ( TempId == (xIdNode)xEnvId ||
                  CPath[CPathLength-1]->EC == xSignalrouteEC ||
                  ( CPath[CPathLength-1]->EC == xGateEC &&
                    CPath[CPathLength-1]->Parent->EC == xProcessEC ) ||
                  xInList(SignalId, ((xPrsIdNode)TempId)->SignalSet)
                )
              )
#ifndef XNOUSEOFSERVICE
              ||
              ( TempId->EC == xServiceEC &&
                xInList(SignalId, ((xSrvIdNode)TempId)->SignalSet)
              )
#endif
           ) {
                   /* If implicit signal route check only process
                      with signal in SignalSet!!! */
        /* Handle the given process */
#ifndef XNOUSEOFSERVICE
        if (TempId->EC == xServiceEC)
          Prs = xFindInst((xPrsIdNode)((xSrvIdNode)TempId)->Parent, SenderPId);
        else
#endif
          Prs = xFindInst((xPrsIdNode)TempId, SenderPId);
        if ( Prs != (xPrsNode)0 ) *NrOfRec = 1;
#ifdef XSIGPATH
        /* Save stack */
        *PathLength = CPathLength;
        for ( TempNr=0; TempNr<=CPathLength; TempNr++ )
          Path[TempNr] = CPath[TempNr];
#else
        /* Save last channel if to env */
        if (TempId == (xIdNode)xEnvId)
          *ChannelId = CPath[CPathLength-1];
#endif
        if (*NrOfRec > 0)
          return Prs->Self;
        else
          return SDL_NULL;
      }

    } else if ( xInList(SignalId, ((xChannelIdNode)TempId)->SignalSet) ) {
      /* Channel, Signal route, or Gate */
      CPathLength++;
      CIndex[CPathLength] = -1;
    }
  }
  return SDL_NULL;
}
#endif
       /* ! XOPTCHAN */


/****+***************************************************************
15   Input Port Handling
********************************************************************/

/*---+---------------------------------------------------------------
     xFindInputAction
-------------------------------------------------------------------*/

/* Given two identifier nodes representing a signal and a process, this
   function returns how the signal should be treated in the actual
   state (input, save, discard, not in signalset), taking possible
   enabling conditions into concideration. */

xInputAction xFindInputAction(
  XSIGTYPE     SignalId,
  xPrsNode     VarP,
  xbool        CheckPrioInput )
{
  int           Pos;
  int           StateNumber;
  xIdNode       PrsId;
  xStateIdNode  StateId;
  xInputAction  Result = xDiscard;

#ifndef XNOUSEOFSERVICE
  if ( VarP->ActiveSrv != (xSrvNode)0 ) {
    if (! XIS_NONEID_SIGNAL(SignalId) ) {
      /* Compute service that can handle this signal */
      VarP->ActiveSrv = VarP->SrvList;
      while (VarP->ActiveSrv != (xSrvNode)0) {
        if ( SignalId == VarP->ActiveSrv->pREPLY_Waited_For )
          return xInput;
        if (xInList(SignalId, VarP->ActiveSrv->NameNode->SignalSet)) {
          if (VarP->ActiveSrv->pREPLY_Waited_For != (XSIGTYPE)0)
            return xSave;
          break;
        }
        VarP->ActiveSrv = VarP->ActiveSrv->NextSrv;
      }
      if (VarP->ActiveSrv == (xSrvNode)0 ) {
        VarP->ActiveSrv = VarP->SrvList;
        return xDiscard;
      }
    }
    if ( VarP->ActiveSrv->ActivePrd == (xPrdNode)0 )
      StateNumber = VarP->ActiveSrv->State;
    else
      StateNumber = VarP->ActiveSrv->ActivePrd->State;
  } else {
#endif
    /* In RPC wait state: xInput for pREPLY, xSave for everything else */
    if ( VarP->pREPLY_Waited_For != (XSIGTYPE)0 ) {
      if ( SignalId == VarP->pREPLY_Waited_For ) return xInput;
      return xSave;
    }

    if ( VarP->ActivePrd == (xPrdNode)0 )
      StateNumber = VarP->State;
    else
      StateNumber = VarP->ActivePrd->State;
#ifndef XNOUSEOFSERVICE
  }
#endif

  /* If start state then save all signals except start up signal.
     Save all signals in decision error state. */
  if ( StateNumber == START_STATE
#ifdef XEDECISION
       || StateNumber == ERROR_STATE
#endif
       ) {
    if (SignalId->EC == xStartUpSignalEC)
      return xInput;
    else
      return xSave;
  }

#ifndef XNOUSEOFSERVICE
  if ( VarP->ActiveSrv != (xSrvNode)0 ) {
    if ( VarP->ActiveSrv->ActivePrd == (xPrdNode)0 )
      StateId = VarP->ActiveSrv->NameNode->StateList[StateNumber];
    else
      StateId = VarP->ActiveSrv->ActivePrd->NameNode->StateList[StateNumber];
  } else {
#endif
    if ( VarP->ActivePrd == (xPrdNode)0 )
      StateId = VarP->NameNode->StateList[StateNumber];
    else
      StateId = VarP->ActivePrd->NameNode->StateList[StateNumber];
#ifndef XNOUSEOFSERVICE
  }
#endif


  /* Locate the position of the signal in the signal set array for
     the actual process. Note that the last position in this array
     holds the value 0. */

  while (StateId != (xStateIdNode)0) {
    PrsId = StateId->Parent;

#ifdef XMONITOR
    /* Handle INPUT NONE -- always take first !!! TO BE UPDATED */
    if ( !CheckPrioInput && XIS_NONEID_SIGNAL(SignalId) && 
         (HASINPUTNONE(StateId) || HASVIRTINPUTNONE(StateId))
       ) {
#ifndef XNOUSEOFSERVICE
      if ( VarP->ActiveSrv != (xSrvNode)0 ) {
        if ( VarP->ActiveSrv->ActivePrd == (xPrdNode)0 ) {
          VarP->ActiveSrv->RestartPAD = ((xSrvIdNode)PrsId)->PAD_Function;
          VarP->ActiveSrv->RestartAddress =
            (StateId->InputRef)[((xSrvIdNode)PrsId)->SignalSetLength + 1];
        } else {
          VarP->ActiveSrv->ActivePrd->RestartPRD =
            ((xPrdIdNode)PrsId)->Assoc_Function;
          VarP->ActiveSrv->ActivePrd->RestartAddress =
            (StateId->InputRef)[((xPrdIdNode)PrsId)->SignalSetLength + 1];
        }
      } else {
#endif
        if (VarP->ActivePrd == (xPrdNode)0) {
          VarP->RestartPAD = ((xPrsIdNode)PrsId)->PAD_Function;
          VarP->RestartAddress =
            (StateId->InputRef)[((xPrsIdNode)PrsId)->SignalSetLength + 1];
        } else {
          VarP->ActivePrd->RestartPRD = ((xPrdIdNode)PrsId)->Assoc_Function;
          VarP->ActivePrd->RestartAddress =
            (StateId->InputRef)[((xPrdIdNode)PrsId)->SignalSetLength + 1];
        }
#ifndef XNOUSEOFSERVICE
      }
#endif
      return xInput;
    }
#endif

    Pos = 0;
#ifndef XNOUSEOFSERVICE
    if ( VarP->ActiveSrv != (xSrvNode)0 ) {
      if (VarP->ActiveSrv->ActivePrd == (xPrdNode)0) {
        while ( ((xSrvIdNode)PrsId)->SignalSet[Pos] != (XSIGTYPE)0 &&
                ((xSrvIdNode)PrsId)->SignalSet[Pos] != SignalId )
          Pos++;
      } else {
        while ( ((xPrdIdNode)PrsId)->SignalSet[Pos] != (XSIGTYPE)0 &&
                ((xPrdIdNode)PrsId)->SignalSet[Pos] != SignalId )
          Pos++;
      }
    } else {
#endif
      if (VarP->ActivePrd == (xPrdNode)0) {
        while ( ((xPrsIdNode)PrsId)->SignalSet[Pos] != (XSIGTYPE)0 &&
                ((xPrsIdNode)PrsId)->SignalSet[Pos] != SignalId )
          Pos++;
      } else {
        while ( ((xPrdIdNode)PrsId)->SignalSet[Pos] != (XSIGTYPE)0 &&
                ((xPrdIdNode)PrsId)->SignalSet[Pos] != SignalId )
          Pos++;
      }
#ifndef XNOUSEOFSERVICE
    }
#endif

    /* Use the computed position to find the signal handling in the
       signal handling array in the state identifier node. If this
       array position contains xEnablCond call the Enabling condition
       function to compute the result. The last position in this array,
       which coinside with the 0 value in the signal set array, holds
       the value xNotInSignalSet. */
    if ( (StateId->SignalHandlArray)[Pos] == xEnablCond )
      Result = (*StateId->EnablCond_Function)(SignalId, (void *)VarP);
    else
      Result = (StateId->SignalHandlArray)[Pos];
    if (Result != xDiscard) {
      /* If INPUT then save RestartPAD and RestartAddress in xPrsNode */
      if ( (Result == xInput && !CheckPrioInput) || Result == xPrioInput ) {
#ifndef XNOUSEOFSERVICE
        if ( VarP->ActiveSrv != (xSrvNode)0 ) {
          if (VarP->ActiveSrv->ActivePrd == (xPrdNode)0) {
            VarP->ActiveSrv->RestartPAD = ((xSrvIdNode)PrsId)->PAD_Function;
            VarP->ActiveSrv->RestartAddress = (StateId->InputRef)[Pos];
          } else {
            VarP->ActiveSrv->ActivePrd->RestartPRD =
                  ((xPrdIdNode)PrsId)->Assoc_Function;
            VarP->ActiveSrv->ActivePrd->RestartAddress =
                  (StateId->InputRef)[Pos];
          }
        } else {
#endif
          if (VarP->ActivePrd == (xPrdNode)0) {
            VarP->RestartPAD = ((xPrsIdNode)PrsId)->PAD_Function;
            VarP->RestartAddress = (StateId->InputRef)[Pos];
          } else {
            VarP->ActivePrd->RestartPRD = ((xPrdIdNode)PrsId)->Assoc_Function;
            VarP->ActivePrd->RestartAddress = (StateId->InputRef)[Pos];
          }
#ifndef XNOUSEOFSERVICE
        }
#endif
      }
      return Result;
    }
    StateId = StateId->Super;
  }
  return Result;
}


/*---+---------------------------------------------------------------
     xInsertIntoInputPort
-------------------------------------------------------------------*/

/* This routine inserts the signal referred to by S into the input
   port of the process instance referred to by P. The input port is
   kept sorted first according to signal priority (highest priority,
   i.e. lowest value of Prio, first) and secondly according to the
   order of arrival. */

static void xInsertIntoInputPort(
  xPrsNode     P,
  xSignalNode  S )
{
  xSignalNode  ToInsertAfter;
#ifdef XCOVERAGE
  long int     QueueLength;
#endif

  ToInsertAfter = P->InputPort.Pre;

#if defined(XSIGPRIO) || defined(XSIGPRSPRIO) || defined(XPRSSIGPRIO)
  /* Search backwards to find first signal with lower or equal
     priority. Note that list head (InputPort) has Prio == 0. */
  while ( S->Prio <  ToInsertAfter->Prio )
    ToInsertAfter = ToInsertAfter->Pre;
#endif

  /* Link S into the input port immediately after ToInsertAfter */
  S->Pre = ToInsertAfter;
  S->Suc = ToInsertAfter->Suc;
  ToInsertAfter->Suc->Pre = S;
  ToInsertAfter->Suc = S;
#ifdef XCOVERAGE
  QueueLength = 0;
  S = P->InputPort.Suc;
  while (S != (xSignalNode)&P->InputPort) {
    QueueLength++;
    S = S->Suc;
  }
  if (P->NameNode->Super == (xPrsIdNode)0) {
    if (QueueLength > P->NameNode->MaxQueueLength)
      P->NameNode->MaxQueueLength = QueueLength;
  } else {
    if (QueueLength > P->NameNode->Super->MaxQueueLength)
      P->NameNode->Super->MaxQueueLength = QueueLength;
  }
#endif
}

/*---+---------------------------------------------------------------
     xRemoveFromQueue
-------------------------------------------------------------------*/

/* This routine removes a signal, timer, or process from a queue,
   assuming that Pre and Suc are the two first components in all
   these objects. */

void xRemoveFromQueue (void * S)
{
  if ( ((xSignalNode)S)->Pre != (xSignalNode)0 ) {
    ((xSignalNode)S)->Pre->Suc = ((xSignalNode)S)->Suc;
    ((xSignalNode)S)->Suc->Pre = ((xSignalNode)S)->Pre;
    ((xSignalNode)S)->Pre = (xSignalNode)0;
    ((xSignalNode)S)->Suc = (xSignalNode)0;
  }
}


/****+***************************************************************
17   Timer routines
********************************************************************/

/*---+---------------------------------------------------------------
     xRemoveTimer
-------------------------------------------------------------------*/
/* S==0 used to remove all timers connected to a process instance.
   Used by SDL_Stop. */

static int xRemoveTimer(
  xSignalNode  S,
  xPrsNode     P )
{
  xSignalNode Timer, TempTimer;
#ifdef XCOUNTRESETS
  int       Count = 0;
#endif 

  Timer = XSYSDPRS_TQ(P)->Suc;
  while ( Timer != XSYSDPRS_TQ(P) ) {
    TempTimer = Timer->Suc;
    if ( (Timer->Sender.LocalPId->PrsP == P) &&
         ( (S == (xSignalNode)0) ||
           ( (S->NameNode == Timer->NameNode) &&
             ( (S->NameNode->Equal_Timer == 0) ||
               (*S->NameNode->Equal_Timer)(S, Timer)
             )
           )
         )
       ) {
#ifdef XMSCE
      xMSCEReset(Timer);
#endif
      xRemoveFromQueue((void *)Timer);
      xReleaseSignal(&Timer);
      if ( S != (xSignalNode)0 ) 
        return 1;
#ifdef XCOUNTRESETS
      Count++;
#endif 
    }  /* end if */
    Timer = TempTimer;
  }  /* end while */
#ifdef XCOUNTRESETS
  return Count;
#else 
  return 0;
#endif 
}

/*---+---------------------------------------------------------------
     xRemoveTimerSignal
-------------------------------------------------------------------*/
static xbool xRemoveTimerSignal(
  xSignalNode  S,
  xSignalNode  Inputport )
{
  xSignalNode TempS;

  TempS = Inputport->Suc;
  while ( TempS != Inputport ) {
    if ( (TempS->NameNode == S->NameNode) &&
         ( (S->NameNode->Equal_Timer == 0) ||
           (*S->NameNode->Equal_Timer)(S, TempS)
         )
       ) {
      xRemoveFromQueue((void *)TempS);
#ifdef XMSCE
      xMSCEReset(TempS);
#endif
#ifdef XREMOVETIMERSIG
      if ( TempS->Receiver.LocalPId->PrsP->Signal == TempS ) {
        SDL_NextState(TempS->Receiver.LocalPId->PrsP,
                      xFindState(TempS->Receiver.LocalPId->PrsP));
      } else {
#endif
        xReleaseSignal(&TempS);
#ifdef XREMOVETIMERSIG
      }
#endif
      return (xbool)1;
    }
    TempS = TempS->Suc;
  }
  return (xbool)0;
}


/****+***************************************************************
18   Scheduling
********************************************************************/

/*---+---------------------------------------------------------------
     xSchedule
-------------------------------------------------------------------*/
static void xSchedule(
  xPrsNode     P,
  int          IsInOutput )
{
#if defined(XSIGPRIO) || defined(XSIGPRSPRIO) || defined(XPRSPRIO) || defined(XPRSSIGPRIO)
  xPrsNode  TempPrs;
#endif
#if defined(XSIGPRSPRIO) || defined(XPRSPRIO) || defined(XPRSSIGPRIO)
  int       PrsPrio;
#endif

#if defined(XSIGPRIO) || defined(XSIGPRSPRIO)
  TempPrs = XSYSDPRS_RQ(P)->Pre;
  while ( TempPrs != XSYSDPRS_RQ(P) &&
          P->Signal->Prio < TempPrs->Signal->Prio ) {
    TempPrs = TempPrs->Pre;
  }
#endif
#ifdef XSIGPRSPRIO
  if ( TempPrs != XSYSDPRS_RQ(P) )
    PrsPrio = P->NameNode->Prio;
  while ( TempPrs != XSYSDPRS_RQ(P) &&
          P->Signal->Prio == TempPrs->Signal->Prio &&
          PrsPrio < TempPrs->NameNode->Prio ) {
    TempPrs = TempPrs->Pre;
  }
#endif

#ifdef XPRSPRIO
  TempPrs = XSYSDPRS_RQ(P)->Pre;
  PrsPrio = P->NameNode->Prio;
  while ( TempPrs != XSYSDPRS_RQ(P) &&
          PrsPrio < TempPrs->NameNode->Prio ) {
    TempPrs = TempPrs->Pre;
  }
#endif

#ifdef XPRSSIGPRIO
  TempPrs = XSYSDPRS_RQ(P)->Pre;
  PrsPrio = P->NameNode->Prio;
  while ( TempPrs != XSYSDPRS_RQ(P) &&
          PrsPrio < TempPrs->NameNode->Prio ) {
    TempPrs = TempPrs->Pre;
  }
  while ( TempPrs != XSYSDPRS_RQ(P) &&
          PrsPrio == TempPrs->NameNode->Prio && 
          P->Signal->Prio < TempPrs->Signal->Prio ) {
    TempPrs = TempPrs->Pre;
  }
#endif

#if defined(XSIGPRIO) || defined(XSIGPRSPRIO) || defined(XPRSPRIO) || defined(XPRSSIGPRIO)
  /* If in Output, do not insert P first in ready queue as the sender of
     the signal should remain at that place. */
  if (IsInOutput && TempPrs == XSYSDPRS_RQ(P))
    TempPrs = XSYSDPRS_RQ(P)->Suc;
  xInsertPrsIntoQueue(P, TempPrs);
#else
  xInsertPrsIntoQueue(P, XSYSDPRS_RQ(P)->Pre);
#endif

}


/****+***************************************************************
19   SDL Actions
********************************************************************/

/*---+---------------------------------------------------------------
     SDL_Output
-------------------------------------------------------------------*/
void SDL_Output(
              xSignalNode  S
  xSigPrioPar(int          Prio),
              xIdNode      ViaList[] )
{
  xPrsNode     ToPrs;
  xInputAction InputAction;
  int          NrReceivers;
#ifdef XSIGPATH
  xIdNode      Path[xSizeOfPathStack];
  int          PathLength = -1;
#else
  xIdNode      ChannelId;
#endif
#if !defined(XENV) && defined(XMONITOR) && defined(XENVSIGNALLIMIT)
  int          IPLength = 0;
#endif

#if defined(XSIGPRIO) || defined(XSIGPRSPRIO) || defined(XPRSSIGPRIO)
  S->Prio = Prio;
#endif

/* ********* Handle Receiver = NULL in TO clause ********* */
  if ( xEq_SDL_PId_NULL(S->Receiver) ) {
#ifdef XEOUTPUT
    xSDLOutputError(4, S, 0);
#endif
#ifdef XMSCE
    if (xSysD.xSilentMSCE == 0) {
# ifdef XSIGPATH
      xMSCEOutput(S, -100, Path, PathLength);
                    /* Dummy value to indicate Receiver = NULL in TO clause */
# else
      xMSCEOutput(S, -100);
                    /* Dummy value to indicate Receiver = NULL in TO clause */
# endif
    }
#endif
    xReleaseSignal(&S);
    return;
  }

#ifndef XOPTCHAN
/* ****** Find receiver when output contained no TO clause ****** */
  if ( xEq_SDL_PId(S->Receiver, xNotDefPId) ) {
#ifdef XSIGPATH
    S->Receiver = xFindReceiver(S->NameNode, S->Sender, ViaList,
                                &NrReceivers, Path, &PathLength);
#else
    S->Receiver = xFindReceiver(S->NameNode, S->Sender, ViaList,
                                &NrReceivers, &ChannelId);
#endif

/* ****** Check path when output contained TO clause ****** */
  } else {
#ifndef XEOUTPUT
    NrReceivers = 1;     /* Always correct when no error check */
#else
#ifdef XMONITOR
    if ( xSysD.xMonitorOutput ) {
# ifdef XSIGPATH
      /* Must setup path if env split into channels in MSC trace */
      if (xIsEnvSplitIntoChannels() && xEq_SDL_PId(S->Sender, xEnv)) {
        NrReceivers = xIsPath(S->NameNode, (xIdNode)xEnvId,
                              (S->Receiver.GlobalNodeNr != xGlobalNodeNumber()
                               ? xEnvId : S->Receiver.LocalPId->PrsP->NameNode
                               ),
                              ViaList, Path, &PathLength);
      }
# endif
      NrReceivers = 1;
    }
    else
#endif
    if ( S->NameNode->EC == xSignalEC )  /* ! xTimerEC, xStartUpSignalEC, xRPCSignalEC */
#ifdef XSIGPATH
      NrReceivers = xIsPath(S->NameNode,
        (S->Sender.GlobalNodeNr != xGlobalNodeNumber()
          ? (xIdNode)xEnvId
#ifndef XNOUSEOFSERVICE
          : ( S->Sender.LocalPId->PrsP->ActiveSrv == (xSrvNode)0
              ? (xIdNode)S->Sender.LocalPId->PrsP->NameNode
	      : (xIdNode)S->Sender.LocalPId->PrsP->ActiveSrv->NameNode
            )
#else
          : (xIdNode)S->Sender.LocalPId->PrsP->NameNode
#endif
        ),
        (S->Receiver.GlobalNodeNr != xGlobalNodeNumber()
          ? xEnvId : S->Receiver.LocalPId->PrsP->NameNode
        ),
        ViaList, Path, &PathLength);
#else
      NrReceivers = xIsPath(S->NameNode,
        (S->Sender.GlobalNodeNr != xGlobalNodeNumber()
          ? (xIdNode)xEnvId
#ifndef XNOUSEOFSERVICE
          : ( S->Sender.LocalPId->PrsP->ActiveSrv == (xSrvNode)0
              ? (xIdNode)S->Sender.LocalPId->PrsP->NameNode
	      : (xIdNode)S->Sender.LocalPId->PrsP->ActiveSrv->NameNode
            )
#else
          : (xIdNode)S->Sender.LocalPId->PrsP->NameNode
#endif
        ),
        (S->Receiver.GlobalNodeNr != xGlobalNodeNumber()
          ? xEnvId : S->Receiver.LocalPId->PrsP->NameNode
        ),
        ViaList);
#endif
    else 
      NrReceivers = 1;
#endif
  }
#else
  NrReceivers = 1;
#endif
       /* ! XOPTCHAN */

/* ********************** Signal log  ************************ */
#ifdef XMONITOR
  xMonitorSignalLog(S, NrReceivers, Path, PathLength);
#endif
#ifdef XSIGLOG
  xSignalLog(S, NrReceivers, Path, PathLength);
#endif

/* ***************** Handle error situations ***************** */
  if ( NrReceivers <= 0 ) {
                     /* no receiver found, no path to receiver */
# ifdef XMSCE
    if (xSysD.xSilentMSCE == 0) {
# ifdef XSIGPATH
      xMSCEOutput(S, NrReceivers, Path, PathLength);
# else
      xMSCEOutput(S, NrReceivers);
# endif
    }
# endif
#ifdef XEOUTPUT
    xSDLOutputError(1, S, NrReceivers);
#endif
    xReleaseSignal(&S);
    return;
  }

/* ***************** Output to environment ***************** */
  if ( (S->Receiver.GlobalNodeNr != xGlobalNodeNumber()) ||
       (S->Receiver.LocalPId == xEnv.LocalPId) ) {
#ifdef XMSCE
    if (xSysD.xSilentMSCE == 0) {
# ifdef XSIGPATH
      xMSCEOutput(S, NrReceivers, Path, PathLength);
# else
      xMSCEOutput(S, NrReceivers);
# endif
      xMSCEEnvReceive(S);
    }
#endif
#if defined (XTRACE) || defined (THREADED_XTRACE)
    xTraceOutput(S);
#endif
#if defined(XENV) && !defined(XMONITOR)
    xOutEnv(&S);
#else
# if defined(XPMCOMM) && !defined(XMONITOR)
    xOutPM(&S, 0);
# else
#  if defined(XMONITOR)
#   if defined(XENV)
    xOutEnv(&S);
#   else
#    if defined(XPMCOMM) || defined(XITEXCOMM)
#     if defined(XPMCOMM) && defined(XITEXCOMM)
    if ( xSysD.xNoticeBoard.CommStarted || xSysD.xNoticeBoard.ITEXCommStarted ) {
#     endif
#     if defined(XPMCOMM) && !defined(XITEXCOMM)
    if ( xSysD.xNoticeBoard.CommStarted ) {
#     endif
#     if !defined(XPMCOMM) && defined(XITEXCOMM)
    if ( xSysD.xNoticeBoard.ITEXCommStarted ) {
#     endif
      xOutPM(&S, (xChannelIdNode)Path[PathLength-1]);
    } else {
#    endif
      xInsertIntoInputPort(xEnv.LocalPId->PrsP, S);
#    ifdef XENVSIGNALLIMIT
      for (S = xEnv.LocalPId->PrsP->InputPort.Suc;
           S != (xSignalNode)&xEnv.LocalPId->PrsP->InputPort;
           S = S->Suc)
        IPLength++;
      if ( IPLength > XENVSIGNALLIMIT ) {
        S = xEnv.LocalPId->PrsP->InputPort.Suc;
        xRemoveFromQueue((void *)S);
        xReleaseSignal(&S);
      }
#     if defined(XPMCOMM)
    }
#     endif
#    endif
#   endif
#  else
#   if defined(XEOUTPUT)
    xSDLOutputError(2, S, NrReceivers);
#   endif
    xReleaseSignal(&S);
#  endif
# endif
#endif
    return;
  }

#ifdef THREADED
/* ***************** Output to other tread ****************** */
  if (S->Suc == 0 &&
      S->Sender.LocalPId != 0 &&
      S->Receiver.LocalPId->PrsP->SysD != S->Sender.LocalPId->PrsP->SysD
     ) {
THREADED_SEND_OUTPUT(S->Receiver.LocalPId->PrsP->SysD)
#ifdef THREADED_MSCTRACE
   xMSCEOutput(S, NrReceivers);
#endif /* THREADED_MSCTRACE */
/*
    THREADED_LOCK_INPUTPORT(S->Receiver.LocalPId->PrsP->SysD)
    S->Suc = (xSignalNode)&S->Receiver.LocalPId->PrsP->SysD->xNewSignals;
    S->Pre = S->Receiver.LocalPId->PrsP->SysD->xNewSignals.Pre;
    S->Receiver.LocalPId->PrsP->SysD->xNewSignals.Pre->Suc = S;
    S->Receiver.LocalPId->PrsP->SysD->xNewSignals.Pre = S;
    THREADED_SIGNAL_AND_UNLOCK_INPUTPORT(S->Receiver.LocalPId->PrsP->SysD)
*/
    return;
  }
  if (S->Suc != 0) {
    /* Called from xMainLoop. Critical region already entered */
    S->Suc->Pre = S->Pre;
    S->Pre->Suc = S->Suc;
    S->Suc = 0;
    S->Pre = 0;
  }
#endif


/* ************ Error: Output to stopped process ************ */
  ToPrs = S->Receiver.LocalPId->PrsP;
#ifndef XPRSOPT
  if ( ToPrs->Self.LocalPId != S->Receiver.LocalPId ) {
#else
#ifdef XNRINST
  if ( ToPrs->Self.LocalPId->InstNr == 0 ) {
#else
  if ( ToPrs->Self.LocalPId->InAvailList ) {
#endif
#endif
#ifdef XMSCE
    if (xSysD.xSilentMSCE == 0) {
# ifdef XSIGPATH
      xMSCEOutput(S, NrReceivers, Path, PathLength);
# else
      xMSCEOutput(S, NrReceivers);
# endif
    }
#endif
#ifdef XEOUTPUT
    xSDLOutputError(3, S, NrReceivers);
#endif
    xReleaseSignal(&S);
    return;
  }

/* ************ Output. Signal to be received ************ */
  if (ToPrs->Signal == (xSignalNode)0
#if defined(XSIGPRIO) || defined(XSIGPRSPRIO) || defined(XPRSSIGPRIO)
     || (XSYSDPRS_RQ(ToPrs)->Suc != ToPrs && S->Prio < ToPrs->Signal->Prio)
#endif
     ) {
    InputAction = xFindInputAction(S->NameNode, ToPrs, (xbool)0);
  } else {
    InputAction = xSave;
  }

  if ( InputAction == xInput || InputAction == xPrioInput ) {
    xInsertIntoInputPort(ToPrs, S);
    ToPrs->Signal = S;
    xSchedule(ToPrs, 1);

#ifdef XMSCE
    if (xSysD.xSilentMSCE == 0) {
# ifdef XSIGPATH
      xMSCEOutput(S, NrReceivers, Path, PathLength);
# else
      xMSCEOutput(S, NrReceivers);
# endif
    }
#endif
#if defined (XTRACE) || defined (THREADED_XTRACE)
    xTraceOutput(S);
#endif

#if defined(XBREAKBEFORE) && defined(XMONITOR)
    xSetUpCurrentSymbolRef();
#endif

    return;
  }

/* ************** Output. Signal to be saved ************** */
  if ( InputAction == xSave ||
       ( S->Sender.GlobalNodeNr == xGlobalNodeNumber() &&
         ToPrs == S->Sender.LocalPId->PrsP &&
         S->NameNode->EC == xSignalEC ) ) {
    xInsertIntoInputPort(ToPrs, S);
#ifdef XMSCE
    if (xSysD.xSilentMSCE == 0) {
# ifdef XSIGPATH
      xMSCEOutput(S, NrReceivers, Path, PathLength);
# else
      xMSCEOutput(S, NrReceivers);
# endif
    }
#endif
#if defined (XTRACE) || defined (THREADED_XTRACE)
    xTraceOutput(S);
#endif

    return;
  }

/* ************ Output. Signal to be discarded ************ */
#ifdef XMSCE
  if (xSysD.xSilentMSCE == 0) {
# ifdef XSIGPATH
    xMSCEOutput(S, NrReceivers, Path, PathLength);
# else
    xMSCEOutput(S, NrReceivers);
# endif
    xMSCEOutputDiscard(S);
  }
#endif
#if defined (XTRACE) || defined (THREADED_XTRACE)
  xTraceOutput(S);
  xTraceOutputDiscard(S);
#endif
  xReleaseSignal(&S);
}


/*---+---------------------------------------------------------------
     SDL_Create
-------------------------------------------------------------------*/
void SDL_Create(
  xSignalNode  StartUpSig,
  xPrsIdNode   PrsId,
  int          BlockInstNumber)
{
  if ( (PrsId->MaxNoOfInst == -1)
       || (xNoOfActivePrs(PrsId, BlockInstNumber) < PrsId->MaxNoOfInst)
#ifdef XMONITOR
       || xSysD.xMonitorCreate     /* Create command given in monitor */
#endif
     ) {
    StartUpSig->Receiver = xGetPId(PrsId, StartUpSig->Sender);
    StartUpSig->Receiver.LocalPId->PrsP->BlockInstNumber = BlockInstNumber;
         /* Sets also up parent - offspring links */

#ifdef THREADED
    if (PrsId->SysD == 0) {
      StartUpSig->Receiver.LocalPId->PrsP->SysD =
	(xSystemData *)xAlloc(sizeof(xSystemData));
      xSysDInit(StartUpSig->Receiver.LocalPId->PrsP->SysD);
    } else {
      StartUpSig->Receiver.LocalPId->PrsP->SysD = PrsId->SysD;
    }
#endif

#if defined (XTRACE) || defined (THREADED_XTRACE)
    if ( StartUpSig->Sender.LocalPId != (xLocalPIdNode)0 )
      xTraceCreate(StartUpSig);
    xSysD.xSilent++;
#endif
#ifdef XMSCE
    xMSCECreate(StartUpSig->Receiver, StartUpSig);
#endif
    StartUpSig->Sender = SDL_NULL;
#ifdef XMONITOR
    if ( PrsId->PAD_Function == 0 && PrsId->Super == (xPrsIdNode)0)
      xReleaseSignal(&StartUpSig);   /* Create of for ex. Env */
    else
#endif
      SDL_Output(StartUpSig  xSigPrioPar(xDefaultPrioCreate),
                 (xIdNode*)0);
#ifdef THREADED
    if (PrsId->SysD == 0) {
      THREADED_START_THREAD(xMainLoop, StartUpSig->Receiver.LocalPId->PrsP->SysD, PrsId->ThreadParam->ThreadStackSize, PrsId->ThreadParam->ThreadPrio, PrsId->ThreadParam->MaxQueueLength, PrsId->ThreadParam->MaxMesSize);
    }
#endif
#ifdef XTRACE
    xSysD.xSilent--;
#endif
  } else {
    if ( StartUpSig->Sender.LocalPId != (xLocalPIdNode)0 ) {
             /* Not static create */
#if defined (XTRACE) || defined (THREADED_XTRACE)
      xTraceUnsuccessfulCreate(PrsId);
#endif
#ifdef XMSCE
      xMSCEUnsuccessfulCreate(PrsId, StartUpSig->Sender, StartUpSig);
#endif
      StartUpSig->Sender.LocalPId->PrsP->Offspring = SDL_NULL;
      xReleaseSignal(&StartUpSig);
    }
#ifdef XECREATE
    else
             /* static create */
      xSDLCreateError(PrsId);
#endif
  }
}


/*---+---------------------------------------------------------------
     SDL_Stop
-------------------------------------------------------------------*/
void SDL_Stop (xPrsNode PrsP)
{
  xSignalNode  S, TempS;
#ifndef XNOUSEOFSERVICE
  xSrvNode     Srv;
#endif

#if defined (XTRACE) || defined (THREADED_XTRACE)
  xTraceStop(PrsP);
#endif

#ifndef XNOUSEOFSERVICE
  if (PrsP->ActiveSrv != (xSrvNode)0 ) {
    Srv = PrsP->ActiveSrv->NextSrv;
    xReleaseService(&(PrsP->ActiveSrv));
    if (Srv != (xSrvNode)0 &&
        Srv->State == START_STATE &&
        Srv->ActivePrd == (xPrdNode)0 &&
        Srv->pREPLY_Waited_For == (XSIGTYPE)0) {
      PrsP->ActiveSrv = Srv;
#if defined (XTRACE) || defined (THREADED_XTRACE)
      xInsertIntoInputPort(PrsP, PrsP->Signal);   /* To get trace correct */
#endif
#ifdef XBREAKBEFORE
#ifdef THREADED_MSCTRACE
      xSetUpCurrentSymbolRef(PrsP);
#else
      xSetUpCurrentSymbolRef();
#endif /* THREADED_MSCTRACE */
#endif
      return;
    }
    if (PrsP->SrvList != (xSrvNode)0) {
             /* More services alive */
      PrsP->ActiveSrv = PrsP->SrvList;
#ifdef XTRACE
      xSysD.xSilent++;
#endif
#ifdef XMSCE
      xSysD.xSilentMSCE++;
#endif
      if (PrsP->ActiveSrv->pREPLY_Waited_For != (XSIGTYPE)0)
        SDL_NextState(PrsP, XRPC_WAIT_STATE);
      else if (PrsP->ActiveSrv->ActivePrd == (xPrdNode)0)
        SDL_NextState(PrsP, PrsP->ActiveSrv->State);
      else
        SDL_NextState(PrsP, PrsP->ActiveSrv->ActivePrd->State);
#ifdef XTRACE
      xSysD.xSilent--;
#endif
#ifdef XMSCE
      xSysD.xSilentMSCE--;
#endif
#ifdef XMONITOR
      if ( PrsP->Suc != (xPrsNode)0 )
#endif
        if (PrsP->Signal == (xSignalNode)0)
          xRemoveFromQueue((void *)PrsP);
#ifdef XBREAKBEFORE
#ifdef THREADED_MSCTRACE
      xSetUpCurrentSymbolRef(PrsP);
#else
      xSetUpCurrentSymbolRef();
#endif /* THREADED_MSCTRACE */
#endif
      return;
    }
  }
#endif

  if ( PrsP->Signal != (xSignalNode)0 ) {
    if ( PrsP->Signal->Suc != (xSignalNode)0 )
      PrsP->Signal = (xSignalNode)0;
    else
      xReleaseSignalNotPara(&PrsP->Signal);
  }
  S = PrsP->InputPort.Suc;
  while ( S != (xSignalNode)&PrsP->InputPort ) {
    TempS = S->Suc;
    xRemoveFromQueue((void *)S);
#ifdef XMSCE
    xMSCENextstateDiscard(PrsP, S);
#endif
    xReleaseSignal(&S);
    S = TempS;
  }
  xRemoveTimer((xSignalNode)0, PrsP);
#ifdef XMSCE
  xMSCEStop(PrsP);
#endif
#ifdef XMONITOR
  if ( PrsP->Suc != (xPrsNode)0 )
#endif
    xRemoveFromQueue((void *)PrsP);
#ifdef THREADED
  if (PrsP->NameNode->SysD == 0) {
    THREADED_STOP_THREAD(PrsP->SysD);
    xFree((void **)&PrsP->SysD);
  }
#endif
  xReleasePId(&PrsP->Self);

#ifdef XBREAKBEFORE
#ifdef THREADED_MSCTRACE
      xSetUpCurrentSymbolRef(PrsP);
#else
      xSetUpCurrentSymbolRef();
#endif /* THREADED_MSCTRACE */
#endif
}

/*---+---------------------------------------------------------------
     SDL_Set
-------------------------------------------------------------------*/
void SDL_Set(
  SDL_Time     T,
  xSignalNode  S )
{
  xSignalNode TempPrs;
  SDL_Time    TempT;

#if defined (XTRACE) || defined (THREADED_XTRACE)
  xTraceSet(T,S);
#endif
  TempT = SDL_Now();
  if ( xLT_SDL_Time(T, TempT) )
    T = TempT;
  if ( !xRemoveTimer(S, S->Sender.LocalPId->PrsP) ) {
    if (xRemoveTimerSignal
          (S, (xSignalNode)&S->Sender.LocalPId->PrsP->InputPort))
#if defined (XTRACE) || defined (THREADED_XTRACE)
      xTraceResetAction(4, S);
#endif
      ;
  }
#if defined (XTRACE) || defined (THREADED_XTRACE)
  else
    xTraceResetAction(3, S);
#endif
#ifdef XMSCE
  xMSCESet(T,S);
#endif
  ((xTimerNode)S)->TimerTime = T;

     /* Find correct position to insert timer. Timer list is
        sorted with lowest TimerTime first.
        Note that head object in queue has a very large TimerTime.  */
  TempPrs = XSYSDPRS_TQ(S->Sender.LocalPId->PrsP)->Suc;   /* First object */
  while ( xGE_SDL_Time(T, ((xTimerNode)TempPrs)->TimerTime) ) {
    TempPrs = TempPrs->Suc;
  }
  S->Suc = TempPrs;
  S->Pre = TempPrs->Pre;
  TempPrs->Pre->Suc = S;
  TempPrs->Pre = S;
}


/*---+---------------------------------------------------------------
     SDL_Reset
-------------------------------------------------------------------*/
void SDL_Reset (xSignalNode *TimerS)
{
#if defined (XTRACE) || defined (THREADED_XTRACE)
  xTraceReset(*TimerS);
#endif
#ifdef XMSCE
  xSysD.DoingReset = 1;
#endif
  if ( !xRemoveTimer(*TimerS,
                     (*TimerS)->Sender.LocalPId->PrsP) ) {
    if (xRemoveTimerSignal(*TimerS,
           (xSignalNode)&(*TimerS)->Sender.LocalPId->PrsP->InputPort))
#if defined (XTRACE) || defined (THREADED_XTRACE)
      xTraceResetAction(1, *TimerS);
    else
      xTraceResetAction(2, *TimerS)
#endif
      ;
  }
#if defined (XTRACE) || defined (THREADED_XTRACE)
  else
    xTraceResetAction(0, *TimerS);
#endif
#ifdef XMSCE
  xSysD.DoingReset = 0;
#endif
  xReleaseSignal(TimerS);
}


/*---+---------------------------------------------------------------
     SDL_SimpleReset
-------------------------------------------------------------------*/
void SDL_SimpleReset(
  xPrsNode     P,
  XSIGTYPE     TimerId )
{
  xSignalNode  TimerS;

  TimerS = xGetSignal(TimerId, SDL_NULL, SDL_NULL);
#if defined (XTRACE) || defined (THREADED_XTRACE)
  xTraceReset(TimerS);
#endif
#ifdef XMSCE
  xSysD.DoingReset = 1;
#endif
  if ( !xRemoveTimer(TimerS, P) ) {
    if (xRemoveTimerSignal(TimerS, (xSignalNode)&P->InputPort))
#if defined (XTRACE) || defined (THREADED_XTRACE)
      xTraceResetAction(1, TimerS);
    else
      xTraceResetAction(2, TimerS)
#endif
      ;
  }
#if defined (XTRACE) || defined (THREADED_XTRACE)
  else
    xTraceResetAction(0, TimerS);
#endif
#ifdef XMSCE
  xSysD.DoingReset = 0;
#endif
  xReleaseSignalNotPara(&TimerS);   /* Simple reset -> no parameters */
}


/*---+---------------------------------------------------------------
     SDL_Active
-------------------------------------------------------------------*/
SDL_Boolean SDL_Active( 
  XSIGTYPE     TimerId,
  xPrsNode     P )
{
  xSignalNode Timer;
  xSignalNode Signal;

  /* true if timer set */
  for (Timer = XSYSDPRS_TQ(P)->Suc; Timer != XSYSDPRS_TQ(P); Timer = Timer->Suc)
    if ( (Timer->NameNode == TimerId) &&
         (Timer->Sender.LocalPId->PrsP == P) )
      return SDL_True;

  /* true if timer signal in input port */
  for (Signal = P->InputPort.Suc;
       Signal != (xSignalNode)&P->InputPort;
       Signal = Signal->Suc)
    if ( Signal->NameNode == TimerId )
      return SDL_True;

  /* else false */
  return SDL_False;
}


/*---+---------------------------------------------------------------
     SDL_OutputTimerSignal
-------------------------------------------------------------------*/
static void SDL_OutputTimerSignal (xSignalNode T)
{
  xRemoveFromQueue((void *)T);
#if defined (XTRACE) || defined (THREADED_XTRACE)
  xTraceTimerOutput(T);
  xSysD.xSilent++;
#endif
#ifdef XMSCE
  xMSCETimerOutput(T);
  xSysD.xSilentMSCE++;
#endif
  SDL_Output(T  xSigPrioPar(xDefaultPrioTimerSignal),  (xIdNode*)0);
#if defined (XTRACE) || defined (THREADED_XTRACE)
  xSysD.xSilent--;
  if (T->Pre == (xSignalNode)0)
    xTraceTimerOutputDiscard(T);
#endif
#ifdef XMSCE
  xSysD.xSilentMSCE--;
  if (T->Pre == (xSignalNode)0)
    xMSCETimerOutputDiscard(T);
#endif
}


/*---+---------------------------------------------------------------
     SDL_NextState
-------------------------------------------------------------------*/
void SDL_NextState(
  xPrsNode  PrsP,
  int       InState )
{
  xSignalNode  InputPort;
  xSignalNode  S, TempS;
  xInputAction InputAction;
  int          ContSigPrio;
  xStateIdNode StateId = 0;
  xIdNode      PrsIdWithInput;
  int          RestartAddress;
  xbool        NeedsRecalc = 0;
#ifndef XNOUSEOFSERVICE
  xSrvNode     TmpSrv;
  xSrvNode     ActiveSrv;
  int          TmpContSigPrio;
  xIdNode      TmpPrsIdWithInput;
  int          TmpRestartAddress;
#endif

#ifndef XNOUSEOFSERVICE
  if (InState != XRPC_WAIT_STATE) {
    if (PrsP->ActiveSrv != (xSrvNode)0)
      PrsP->ActiveSrv->pREPLY_Waited_For = (XSIGTYPE)0;
    else
#endif
      PrsP->pREPLY_Waited_For = (XSIGTYPE)0;
#ifndef XNOUSEOFSERVICE
  }
#endif

#if defined (XTRACE) || defined (THREADED_XTRACE)
  xTraceNextstate(PrsP, InState);
#endif
#ifdef XMSCE
  if (xSysD.xSilentMSCE == 0)
    xMSCENextstate(PrsP, InState);
#endif

     /* Set up new state */
#ifndef XNOUSEOFSERVICE
  if (PrsP->ActiveSrv != (xSrvNode)0 ) {
#ifdef XMONITOR
    PrsP->ActiveSrv->InTransition = (xbool)0;
#endif
    if (InState != XRPC_WAIT_STATE) {
      if (PrsP->ActiveSrv->ActivePrd == (xPrdNode)0 ) {
        PrsP->ActiveSrv->State = InState;
      } else {
        PrsP->ActiveSrv->ActivePrd->State = InState;
      }
    }
  } else {
#endif
#ifdef XMONITOR
    PrsP->InTransition = (xbool)0;
#endif
    if (PrsP->ActivePrd == (xPrdNode)0 ) {
      PrsP->State = InState;
    } else {
      PrsP->ActivePrd->State = InState;
    }
#ifndef XNOUSEOFSERVICE
  }
#endif

#ifndef XNOUSEOFSERVICE
  if (PrsP->ActiveSrv != (xSrvNode)0 &&
      PrsP->ActiveSrv->NextSrv != (xSrvNode)0 &&
      PrsP->ActiveSrv->NextSrv->State == START_STATE &&
      PrsP->ActiveSrv->NextSrv->ActivePrd == (xPrdNode)0 &&
      PrsP->ActiveSrv->NextSrv->pREPLY_Waited_For == (XSIGTYPE)0 ) {
    PrsP->ActiveSrv = PrsP->ActiveSrv->NextSrv;
#if defined (XTRACE) || defined (THREADED_XTRACE)
    xInsertIntoInputPort(PrsP, PrsP->Signal);   /* To get trace correct */
#endif
#ifdef XBREAKBEFORE
#ifdef THREADED_MSCTRACE
      xSetUpCurrentSymbolRef(PrsP);
#else
      xSetUpCurrentSymbolRef();
#endif /* THREADED_MSCTRACE */
#endif
    return;
  }
#endif

     /* Release signal initiating this transition and remove
        process from ready queue */
  xReleaseSignalNotPara(&PrsP->Signal);
  xRemoveFromQueue((void *)PrsP);

#ifdef XERRORSTATE
  if ( InState == ERROR_STATE )
    return;
#endif

     /* Find next signal to be consumed */
#ifndef XNOUSEOFSERVICE
  if (PrsP->ActiveSrv == (xSrvNode)0 ) {
#endif
    if ( PrsP->ActivePrd != (xPrdNode)0 )
      StateId = PrsP->ActivePrd->NameNode->StateList[InState];
    else
      StateId = PrsP->NameNode->StateList[InState];
#ifndef XNOUSEOFSERVICE
  }
#endif

  InputPort = (xSignalNode)&PrsP->InputPort;
  if (
#ifndef XNOUSEOFSERVICE
       PrsP->ActiveSrv != (xSrvNode)0 ||
#endif
       HASPRIOINPUT(StateId)
     ) {
    S = InputPort->Suc;
    while ( PrsP->Signal == (xSignalNode)0 && S != InputPort ) {
      InputAction = xFindInputAction(S->NameNode, PrsP, (xbool)1);
      if ( InputAction == xPrioInput )
        PrsP->Signal = S;
      else
        S = S->Suc;
    }
  }

  S = InputPort->Suc;
  while ( PrsP->Signal == (xSignalNode)0 && S != InputPort ) {
    InputAction = xFindInputAction(S->NameNode, PrsP, (xbool)0);
    if ( InputAction == xInput ) {
      PrsP->Signal = S;
    } else if ( InputAction != xSave ) {
#if defined (XTRACE) || defined (THREADED_XTRACE)
      xTraceNextstateDiscard(PrsP, S);
#endif
#ifdef XMSCE
      xMSCENextstateDiscard(PrsP, S);
#endif
      TempS = S->Suc;
      xRemoveFromQueue((void *)S);
      xReleaseSignal(&S);
      S = TempS;
    } else {
      S = S->Suc;
    }
  }

    /* If still no signal found, try continuous signals */
  if ( PrsP->Signal == (xSignalNode)0 ) {
#ifndef XNOUSEOFSERVICE
    if (PrsP->ActiveSrv != (xSrvNode)0 ) {
      ContSigPrio = -1;
      RestartAddress = -1;
      ActiveSrv = (xSrvNode)0;
      for (TmpSrv=PrsP->SrvList; TmpSrv!=(xSrvNode)0; TmpSrv=TmpSrv->NextSrv) {
        if (TmpSrv->pREPLY_Waited_For != (XSIGTYPE)0)
          StateId = &xRPCWaitStateIdRec;
        else if ( TmpSrv->ActivePrd != (xPrdNode)0 )
          StateId = TmpSrv->ActivePrd->NameNode->StateList
                          [TmpSrv->ActivePrd->State];
        else
          StateId = TmpSrv->NameNode->StateList[TmpSrv->State];
        NeedsRecalc = NeedsRecalc && NEEDSRECALC(StateId);
        if (StateId->ContSig_Function != 0) {
          PrsP->ActiveSrv = TmpSrv;
          (*StateId->ContSig_Function)((void *)PrsP, &TmpContSigPrio,
                                     &TmpPrsIdWithInput, &TmpRestartAddress);
          if (TmpRestartAddress > 0 &&
              (ContSigPrio == -1 || TmpContSigPrio < ContSigPrio)) {
            ActiveSrv = TmpSrv;
            ContSigPrio = TmpContSigPrio;
            PrsIdWithInput = TmpPrsIdWithInput;
            RestartAddress = TmpRestartAddress;
          }
        }
      }
      if (RestartAddress > 0) {
        PrsP->ActiveSrv = ActiveSrv;
        if (PrsP->ActiveSrv->ActivePrd == (xPrdNode)0) {
          PrsP->ActiveSrv->RestartPAD =
            ((xSrvIdNode)PrsIdWithInput)->PAD_Function;
          PrsP->ActiveSrv->RestartAddress = RestartAddress;
        } else {
          PrsP->ActiveSrv->ActivePrd->RestartPRD =
            ((xPrdIdNode)PrsIdWithInput)->Assoc_Function;
          PrsP->ActiveSrv->ActivePrd->RestartAddress = RestartAddress;
        }
        PrsP->Signal = xGetSignal(xContSigId, PrsP->Self, PrsP->Self);
        PrsP->Signal->Prio = ContSigPrio;
        xInsertIntoInputPort(PrsP, PrsP->Signal);
      }
    } else {
#endif
      NeedsRecalc = NEEDSRECALC(StateId);
      if (StateId->ContSig_Function != 0) {
        (*StateId->ContSig_Function)((void *)PrsP, &ContSigPrio,
                                     &PrsIdWithInput, &RestartAddress);
        if ( RestartAddress > 0 ) {
          if (PrsP->ActivePrd == (xPrdNode)0) {
            PrsP->RestartPAD =
              ((xPrsIdNode)PrsIdWithInput)->PAD_Function;
            PrsP->RestartAddress = RestartAddress;
          } else {
            PrsP->ActivePrd->RestartPRD =
              ((xPrdIdNode)PrsIdWithInput)->Assoc_Function;
            PrsP->ActivePrd->RestartAddress = RestartAddress;
          }
          PrsP->Signal = xGetSignal(xContSigId, PrsP->Self, PrsP->Self);
          PrsP->Signal->Prio = ContSigPrio;
          xInsertIntoInputPort(PrsP, PrsP->Signal);
        }
      }
#ifndef XNOUSEOFSERVICE
    }
#endif
  }

    /* Schedule process if signal for input has been found */
  if ( PrsP->Signal != (xSignalNode)0 )
    xSchedule(PrsP, 0);

    /* Else if state contains cont.sig. or enabl.cond. that can change
       even if process is waiting in state then insert process in
       CheckList */
  else if ( NeedsRecalc )
    xInsertPrsIntoQueue(PrsP, XSYSDPRS_CL(PrsP));

#ifdef XBREAKBEFORE
#ifdef THREADED_MSCTRACE
   xSetUpCurrentSymbolRef(PrsP);
#else
  xSetUpCurrentSymbolRef();
#endif /* THREADED_MSCTRACE */
#endif
}


/*---+---------------------------------------------------------------
     SDL_RPC_WaitState
-------------------------------------------------------------------*/
void SDL_RPC_WaitState(
  xPrsNode  PrsP,
  int       RestartAddress,
  XSIGTYPE  pREPLY_Waited_For )
{
#ifndef XNOUSEOFSERVICE
  if (PrsP->ActiveSrv != (xSrvNode)0 ) {
    if (PrsP->ActiveSrv->ActivePrd == (xPrdNode)0 ) {
      PrsP->ActiveSrv->RestartAddress = RestartAddress;
    } else {
      PrsP->ActiveSrv->ActivePrd->RestartAddress = RestartAddress;
    }
    PrsP->ActiveSrv->pREPLY_Waited_For = pREPLY_Waited_For;
    SDL_NextState(PrsP, XRPC_WAIT_STATE);
    return;
  }
#endif

#ifdef XMONITOR
  PrsP->InTransition = (xbool)0;
#endif
  if (PrsP->ActivePrd == (xPrdNode)0 ) {
    PrsP->RestartAddress = RestartAddress;
  } else {
    PrsP->ActivePrd->RestartAddress = RestartAddress;
  }
  PrsP->pREPLY_Waited_For = pREPLY_Waited_For;
#if defined (XTRACE) || defined (THREADED_XTRACE)
  xTraceNextstate(PrsP, PrsP->State);
#endif
#ifdef XMSCE
  xMSCENextstate(PrsP, PrsP->State);
#endif

     /* Release signal initiating this transition and remove
        process from ready queue */
  xReleaseSignalNotPara(&PrsP->Signal);
  xRemoveFromQueue((void *)PrsP);

#ifdef XBREAKBEFORE
#ifdef THREADED_MSCTRACE
      xSetUpCurrentSymbolRef(PrsP);
#else
      xSetUpCurrentSymbolRef();
#endif /* THREADED_MSCTRACE */
#endif
}


/*---+---------------------------------------------------------------
     SDL_Now
-------------------------------------------------------------------*/
SDL_Time SDL_Now (void)
{
#ifndef XCLOCK
  return xSysD.xSystemTime;
#else
#ifdef XCALENDARCLOCK
  return SDL_Clock();
#else
#ifdef XMONITOR
  return xMinusT_SDL_Time(SDL_Clock(),
            xPlus_SDL_Time(xSysD.xStartTime, xSysD.xTimeInMonitor));
#else
  return xMinusT_SDL_Time(SDL_Clock(), xSysD.xStartTime);
#endif
#endif
#endif
}



/*---+---------------------------------------------------------------
     xIsInSameInstance
-------------------------------------------------------------------*/
static xbool xIsInSameInstance(
  xIdNode     ParentUnit,
  xPrsIdNode  Importer,
  xPrsIdNode  Exporter )
{
  xIdNode      BlockInstImporter, BlockInstExporter;
  xBlockIdNode BT;

  if (ParentUnit->EC == xProcessTypeEC)
    return (xbool)(Importer == Exporter);

/* Travers the instantiation chain upward until the instance is an
   instantiation of the type referenced by ParentUnit
*/
  for (BlockInstImporter = Importer->Parent;
       BlockInstImporter != (xIdNode)0;
       BlockInstImporter = BlockInstImporter->Parent) {
    if (BlockInstImporter->EC == xBlockEC) {
      for (BT = ((xBlockIdNode)BlockInstImporter)->Super;
           BT != (xBlockIdNode)0 && BT != (xBlockIdNode)ParentUnit;
           BT = BT->Super) ;
      if (BT == (xBlockIdNode)ParentUnit) break;
    }
  }
  for (BlockInstExporter = Exporter->Parent;
       BlockInstExporter != (xIdNode)0;
       BlockInstExporter = BlockInstExporter->Parent) {
    if (BlockInstExporter->EC == xBlockEC) {
      for (BT = ((xBlockIdNode)BlockInstExporter)->Super;
           BT != (xBlockIdNode)0 && BT != (xBlockIdNode)ParentUnit;
           BT = BT->Super) ;
      if (BT == (xBlockIdNode)ParentUnit) break;
    }
  }
  if (BlockInstImporter == BlockInstExporter) return (xbool)1;
  return (xbool)0;
}


/*---+---------------------------------------------------------------
     xGetExportAddr
-------------------------------------------------------------------*/
void * xGetExportAddr(
  xRemoteVarIdNode RemoteVarNode,
  SDL_PId          P,
  xbool            IsDefP,
  xPrsNode         Importer )
{
  xRemoteVarListNode LoopNode;
  xRemoteVarListNode ExportNode = (xRemoteVarListNode)0;
  xPrsNode           Prs        = (xPrsNode)0;
  xbool              IsInError  = (xbool)0;
  xIdNode            ParentUnit;
#ifndef XNOUSEOFSERVICE
   xSrvNode          Srv;
#endif

  if (IsDefP) {
    if (xEq_SDL_PId_NULL(P)) {
#ifdef XEEXPORT
      xSDLExportError("Attempt to import from NULL", P,
                      RemoteVarNode );
#endif
      IsInError = (xbool)1;
    } else if (P.GlobalNodeNr != xGlobalNodeNumber()) {
#ifdef XEEXPORT
      xSDLExportError("Attempt to import from the environment",
                      P, RemoteVarNode );
#endif
      IsInError = (xbool)1;
    } else {
      Prs = P.LocalPId->PrsP;
      if (Prs->Self.LocalPId != P.LocalPId) {
#ifdef XEEXPORT
        xSDLExportError("Attempt to import from stopped process instance",
                        P, RemoteVarNode );
#endif
        IsInError = (xbool)1;
      }
    }
  }

  if (! IsInError) {
    ParentUnit = RemoteVarNode->Parent;
    if (ParentUnit->EC == xBlocksubstEC) ParentUnit = ParentUnit->Parent;
    for (LoopNode = RemoteVarNode->RemoteList;
         LoopNode != (xRemoteVarListNode)0 && ExportNode == (xRemoteVarListNode)0;
         LoopNode = LoopNode->Next) {
      if (!IsDefP) {
        Prs = xFindInst(LoopNode->ExportingPrs, Importer->Self);
        if ( Prs != (xPrsNode)0 &&
             ( ( ParentUnit->EC != xBlockTypeEC && ParentUnit->EC != xProcessTypeEC ) ||
               xIsInSameInstance(ParentUnit, Importer->NameNode, LoopNode->ExportingPrs)
             )
           ) {
          ExportNode = LoopNode;
        }
      } else if ( Prs->NameNode == LoopNode->ExportingPrs ) {
        ExportNode = LoopNode;
      }
    }
  }

#ifdef XEEXPORT
  if (! IsInError && (ExportNode == (xRemoteVarListNode)0) ) {
    if (IsDefP)
      xSDLExportError
        ("The specified process does not export this variable",
         P, RemoteVarNode );
    else
      xSDLExportError("No process exports this variable", P, RemoteVarNode );
  }
#endif

  if ( ExportNode != (xRemoteVarListNode)0 ) {
#ifndef XNOUSEOFSERVICE
    if ( ExportNode->SrvId == (xSrvIdNode)0 ) {
#endif
      return (void *) ((xptrint)Prs + ExportNode->Offset);
#ifndef XNOUSEOFSERVICE
    } else {
      Srv = Prs->SrvList;
      while (Srv != (xSrvNode)0 && Srv->NameNode != ExportNode->SrvId)
        Srv = Srv->NextSrv;
      if (Srv != (xSrvNode)0)
        return (void *) ((xptrint)Srv + ExportNode->Offset);
#ifdef XEEXPORT
      xSDLExportError("Attempt to import from stopped service",
                      P, RemoteVarNode );
#endif
    }
#endif
  }

  if (RemoteVarNode->SortSize <= XTEMPDATA_SIZE) {
    (void)memset((void *)xData, 0, RemoteVarNode->SortSize);
    return (void *)xData;
  }
  return xAlloc((xptrint)RemoteVarNode->SortSize);
}


/*---+---------------------------------------------------------------
     xGetExportingPrs
-------------------------------------------------------------------*/
SDL_PId xGetExportingPrs (
  xRemotePrdIdNode RemotePrdNode,
  xPrsNode         Importer )
{
  xRemotePrdListNode Node;
  xIdNode            ParentUnit;
  xPrsNode           Prs;

  ParentUnit = RemotePrdNode->Parent;
  if (ParentUnit->EC == xBlocksubstEC) ParentUnit = ParentUnit->Parent;
  for ( Node = RemotePrdNode->RemoteList;
        Node != (xRemotePrdListNode)0;
        Node = Node->Next ) {
    Prs = xFindInst(Node->ExportedPrs, Importer->Self);
    if ( Prs != (xPrsNode)0 &&
         ( ( ParentUnit->EC != xBlockTypeEC && ParentUnit->EC != xProcessTypeEC ) ||
           xIsInSameInstance(ParentUnit, Importer->NameNode, Node->ExportedPrs)
         )
       )
      return Prs->Self;
  }
  return SDL_NULL;
}


/*---+---------------------------------------------------------------
     SDL_View_Index
-------------------------------------------------------------------*/
int SDL_View_Index (
  xPrsNode      ViewingPrs,  /* process instance perfoming view */
  char *        UniqueVar)  /* variable + prefix for type */
{
  xIdNode ParentUnit;
  int Index;
  ParentUnit = ViewingPrs->NameNode->Parent;
  if (ParentUnit->EC == xBlocksubstEC) ParentUnit = ParentUnit->Parent;
  Index = 0;
  while (((xBlockIdNode)ParentUnit)->ViewIndex[Index].ViewName) {
    if (! strcmp(((xBlockIdNode)ParentUnit)->ViewIndex[Index].ViewName, UniqueVar))
      return ((xBlockIdNode)ParentUnit)->ViewIndex[Index].Index;
    Index++;
  }
  return 0;
}


/*---+---------------------------------------------------------------
     SDL_View
-------------------------------------------------------------------*/
void * SDL_View (
         xViewListRec *VList,     /* list of prs revealing this variable */
         SDL_PId       P,           /* PId expr in view */
         xbool         IsDefP,      /* is PId expression in view() */
         xPrsNode      ViewingPrs,  /* process instance perfoming view */
  xeView(char *        Reveal_Var)  /* viewed variable name as string */
         int           SortSize)    /* size of sort */
{
  xPrsNode    Prs          = (xPrsNode)0;
  xbool       IsInError    = (xbool)0;
  int         FoundAtIndex = -1;
  xIdNode     ParentUnit;
  int         Index;
#ifndef XNOUSEOFSERVICE
  xSrvNode    Srv;
#endif

  if (IsDefP) {
    if (xEq_SDL_PId_NULL(P)) {
#ifdef XEVIEW
      xSDLViewError("Attempt to view from NULL", P, Reveal_Var);
#endif
      IsInError = (xbool)1;
    } else if (P.GlobalNodeNr != xGlobalNodeNumber()) {
#ifdef XEVIEW
      xSDLViewError("Attempt to view from the environment", P, Reveal_Var);
#endif
      IsInError = (xbool)1;
    } else {
      Prs = P.LocalPId->PrsP;
      if (Prs->Self.LocalPId != P.LocalPId) {
#ifdef XEVIEW
        xSDLViewError("Attempt to view from stopped process instance",
                       P, Reveal_Var);
#endif
        IsInError = (xbool)1;
      }
    }
  }

  if (! IsInError) {
    ParentUnit = ViewingPrs->NameNode->Parent;
    if (ParentUnit->EC == xBlocksubstEC) ParentUnit = ParentUnit->Parent;
    for (Index = 0; VList[Index].ViewingPrs != 0 && FoundAtIndex == -1; Index++) {
      if (!IsDefP) {
        Prs = xFindInst(VList[Index].ViewingPrs, ViewingPrs->Self);
        if ( Prs != (xPrsNode)0 &&
             ( ( ParentUnit->EC != xBlockTypeEC && ParentUnit->EC != xProcessTypeEC ) ||
               xIsInSameInstance(ParentUnit, ViewingPrs->NameNode, VList[Index].ViewingPrs)
             )
           ) {
          FoundAtIndex = Index;
        }
      } else if ( Prs->NameNode == VList[Index].ViewingPrs) {
        FoundAtIndex = Index;
      }
    }
  }

#ifdef XEVIEW
  if (! IsInError && FoundAtIndex == -1 ) {
    if (IsDefP)
      xSDLViewError("The specified process does not reveal this variable", P,
                    Reveal_Var);
    else
      xSDLViewError("No process reveals this variable", P, Reveal_Var);
  }
#endif

  if ( FoundAtIndex != -1 ) {
#ifndef XNOUSEOFSERVICE
    if ( VList[FoundAtIndex].SrvId == (xSrvIdNode)0 ) {
#endif
      return (void *) ((xptrint)Prs + VList[FoundAtIndex].Offset);
#ifndef XNOUSEOFSERVICE
    } else {
      Srv = Prs->SrvList;
      while (Srv != (xSrvNode)0 && Srv->NameNode != VList[FoundAtIndex].SrvId)
        Srv = Srv->NextSrv;
      if (Srv != (xSrvNode)0)
        return (void *) ((xptrint)Srv + VList[FoundAtIndex].Offset);
#ifdef XEVIEW
      xSDLViewError("Attempt to view from stopped service", P, Reveal_Var);
#endif
    }
#endif
  }

  if (SortSize <= XTEMPDATA_SIZE) {
    (void)memset((void *)xData, 0, SortSize);
    return (void *)xData;
  }
  return xAlloc((xptrint)SortSize);
}


/*---+---------------------------------------------------------------
     SDL_Halt
-------------------------------------------------------------------*/
void SDL_Halt  (void)
{
#ifdef XMONITOR
  xCloseAllMonitorFiles();
#endif
#ifdef XCONNECTPM
  xClosePM();
#endif
#ifdef XENV
  xCloseEnv();
#endif
#ifdef XEALLOC
  xReportPtrList();
#endif
  xHalt();
}


/*---+---------------------------------------------------------------
     xEq_SDL_PId
-------------------------------------------------------------------*/
SDL_Boolean xEq_SDL_PId(
  SDL_PId A,
  SDL_PId B )
{
  return ( A.GlobalNodeNr == B.GlobalNodeNr &&
           A.LocalPId == B.LocalPId );
}


/*---+---------------------------------------------------------------
     xEq_SDL_PId_NULL
-------------------------------------------------------------------*/
SDL_Boolean xEq_SDL_PId_NULL (SDL_PId A)
{
  return ( A.GlobalNodeNr==0 && A.LocalPId==(xLocalPIdNode)0 );
}


#ifndef XNOUSEOFSERVICE
/*---+---------------------------------------------------------------
     xStart_Services
-------------------------------------------------------------------*/
void xStart_Services (xPrsNode Process)
{
  xSrvIdNode SrvIdNode;
  xSrvNode   SrvNode;
  int        i;

  SrvIdNode = (xSrvIdNode)(Process->NameNode->Contents[0]);
  i = 1;
  SrvNode = (xSrvNode)0;
  while (SrvIdNode != (xSrvIdNode)0) {
    if (SrvIdNode->EC == xServiceEC) {
      SrvNode = xGetService(SrvIdNode, Process);
#if defined (XTRACE) || defined (THREADED_XTRACE)
      xTraceStartService(SrvNode);
#endif
    }
    SrvIdNode = (xSrvIdNode)(Process->NameNode->Contents[i++]);
  }

  /* Set up for the first service to execute its start transition.
     In SDL_Nexstate and SDL_Stop the process will not be removed
     from the ReadyQ until all services has exectuted its start
     transition */
  Process->ActiveSrv = SrvNode;
#if defined (XTRACE) || defined (THREADED_XTRACE)
  xInsertIntoInputPort(Process, Process->Signal); /* To get trace correct */
#endif
#ifdef XBREAKBEFORE
#ifdef THREADED_MSCTRACE
      xSetUpCurrentSymbolRef(Process);
#else
      xSetUpCurrentSymbolRef();
#endif /* THREADED_MSCTRACE */
#endif
}
#endif



/****+***************************************************************
24   MainInit and MainLoop
********************************************************************/

/*---+---------------------------------------------------------------
     xSysDInit
-------------------------------------------------------------------*/
void xSysDInit(
#if defined (XCONNECTPM) && !defined (THREADED_MSCTRACE)
  int     argc, 
  char   *argv[],
#endif
  xSystemData* SysD
)
{
  SysD->xReadyQueue = (xPrsNode)xAlloc((xptrint)sizeof(xPrsRec));
  SysD->xReadyQueue->Suc = SysD->xReadyQueue;
  SysD->xReadyQueue->Pre = SysD->xReadyQueue;
  SysD->xTimerQueue = (xSignalNode)xAlloc((xptrint)sizeof(xTimerRec));
  SysD->xTimerQueue->Suc = SysD->xTimerQueue;
  SysD->xTimerQueue->Pre = SysD->xTimerQueue;
  ((xTimerNode)SysD->xTimerQueue)->TimerTime = xMaxTime;
  SysD->xCheckList = (xPrsNode)xAlloc((xptrint)sizeof(xPrsRec));
  SysD->xCheckList->Suc = SysD->xCheckList;
  SysD->xCheckList->Pre = SysD->xCheckList;
#ifdef THREADED
  SysD->xNewSignals.Pre = (xSignalNode)&SysD->xNewSignals;
  SysD->xNewSignals.Suc = (xSignalNode)&SysD->xNewSignals;
#endif
#ifdef XCLOCK
#ifndef XCALENDARCLOCK
  SysD->xStartTime = SDL_Clock();
#endif
#else
  SysD->xSystemTime = SDL_Time_Lit( (xint32)0, (xint32)0 );
#endif

#ifdef XERRORSTATE
  SysD->xErrorStateId = &ErrorStateId;
#endif

  THREADED_THREAD_INIT(SysD)
}


/*---+---------------------------------------------------------------
     xMainInit
-------------------------------------------------------------------*/
void xMainInit(
#ifdef XCONNECTPM
  int     argc, 
  char   *argv[]
#else
  void
#endif
  )
{
  /* Initialize the Postmaster communication */
#ifdef XCONNECTPM
  xSysD.xNoticeBoard.PMConnected = (xbool)0;
  xSysD.xNoticeBoard.MyPID = (int)0;
  xInitPM(argc, argv);
#endif

  /* Initialize the env */
#ifdef XENV
  xInitEnv();
#endif

  /* Initialize the kernel */
#if defined(XGRTRACE) || defined(XMONITOR)
  xSysD.xCurrentSymbolRef = "";
  xSysD.xPreviousSymbolRef = "";
#endif
#ifdef XMSCE
  xSysD.xCurrentSymbolRef = " ";
  xSysD.xSilentMSCE = 0;
#endif
#ifdef XCTRACE
  xSysD.xCFileName = (char *)0;
  xSysD.xCLineNo = 0;
  xSysD.xBetweenTrans = (xbool)1;
#endif
#ifdef XPMCOMM
  xSysD.xRaW_use_Global_PId = (xbool)0;
#endif
#ifdef XITEXCOMM
  xSysD.xUse_Itex_Syntax = (xbool)0;
#endif

#if !defined(XNOUSEOFREAL) && defined(XEFIXOF)
  for (xMax_SDL_Integer = 1;
       xMax_SDL_Integer > 0;
       xMax_SDL_Integer <<= 1) ;
  xMax_SDL_Integer = ~xMax_SDL_Integer;
#endif
#ifdef X_XINT32_INT
  xMaxTime.s = 2147483647;
  xMaxTime.ns = 0;
#else
  xMaxTime.s = 2147483647L;
  xMaxTime.ns = 0L;
#endif
  xAvailSignal = (xSignalNode)0;
  xAvailTimer = (xSignalNode)0;
#ifdef THREADED
  THREADED_GLOBAL_INIT
#endif

  SDL_NULL.GlobalNodeNr = 0;
  SDL_NULL.LocalPId = (xLocalPIdNode)0;
#ifndef XOPTCHAN
  xNotDefPId.GlobalNodeNr = -1;
  xNotDefPId.LocalPId = (xLocalPIdNode)0;
#endif
  xEnvId = &yEnvR_env;
  xInsertIdNode((xIdNode)&yEnvR_env);
  xEnv = xGetPId(xEnvId, SDL_NULL);
  xEnv.LocalPId->PrsP->BlockInstNumber = 1;
  xEnv.LocalPId->PrsP->Self = xEnv;
  *xEnvId->ActivePrsList = xEnv.LocalPId->PrsP;
#ifndef XNOSTARTUPIDNODE
  xInsertIdNode((xIdNode)&ySigR_Env);
#endif
#ifndef XOPTSORT
  yInit_Predefined();
#endif

#ifdef XREADANDWRITEF
  xInitReadAndWrite();
#endif

#ifndef THREADED
#ifdef XCONNECTPM
  xSysDInit(argc, argv, &xSysD);
#else
  xSysDInit(&xSysD);
#endif
#endif

  /* Initialize the SDL system */
  yInit();

#ifdef XMONITOR
  /* Initialize the monitor system */
  xInitMonitorSystem();
#endif
}


#if !defined(XNOMAIN) && !defined(THREADED)
/*---+---------------------------------------------------------------
     xMainLoop
-------------------------------------------------------------------*/
void xMainLoop (void)
{
  SDL_Time T;
#ifdef XTENV
  SDL_Time xNextENVInTime;

  xNextENVInTime = SDL_Time_Lit( (xint32)0, (xint32)0 );
#endif
#ifdef XBREAKBEFORE
  xSetUpCurrentSymbolRef();
#endif

  while (1) {
    /* Main loop for simulated time i.e. !defined(XCLOCK). */

#ifndef XCLOCK

#ifdef XENV 
# ifdef XMONITOR 
    if ( xSysD.xInEnvOn )
# endif
      xInEnv(SDL_Time_Lit( (xint32)0, (xint32)0 ));
#endif
#if defined(XCONNECTPM)
    xInPM();
#endif
#ifdef XMONITOR 
    xCheckMonitors();
    T = xNextMonTime();
    if ( xSysD.xReadyQueue->Suc == xSysD.xReadyQueue &&
         xGT_SDL_Time(((xTimerNode)xSysD.xTimerQueue->Suc)->TimerTime, SDL_Now()) &&
         xGT_SDL_Time(T, SDL_Now()) ) {
      if ( xLT_SDL_Time(((xTimerNode)xSysD.xTimerQueue->Suc)->TimerTime, T) )
        T = ((xTimerNode)xSysD.xTimerQueue->Suc)->TimerTime;
      if ( xLT_SDL_Time (T, xMaxTime) )
        xSysD.xSystemTime = T;  /* go to next time with event */
    }
#endif
    if ( xSysD.xTimerQueue->Suc != xSysD.xTimerQueue &&
         xLE_SDL_Time(((xTimerNode)xSysD.xTimerQueue->Suc)->TimerTime,
                      SDL_Now()) ) {
      SDL_OutputTimerSignal(xSysD.xTimerQueue->Suc);
      if (xSysD.xCheckList->Suc != xSysD.xCheckList)
        xCheckCheckList(xSysD.xCheckList);
    } else if ( xSysD.xReadyQueue->Suc != xSysD.xReadyQueue) {
#if defined (XTRACE) || defined (THREADED_XTRACE)
      /* If xSysD.xReadyQueue->Suc->Signal is 0 or
         xSysD.xReadyQueue->Suc->Signal is not member of a list
         no trace of transition is performed. (Single step) */
      if ( (xSysD.xReadyQueue->Suc->Signal != (xSignalNode)0) &&
           (xSysD.xReadyQueue->Suc->Signal->Pre != (xSignalNode)0) )
        xTraceTransition(xSysD.xReadyQueue->Suc);
#endif
#ifdef XSIGLOG
      if ( (xSysD.xReadyQueue->Suc->Signal != (xSignalNode)0) &&
           (xSysD.xReadyQueue->Suc->Signal->Pre != (xSignalNode)0) )
              xProcessLog(xSysD.xReadyQueue->Suc);
#endif
      xRemoveFromQueue((void *)xSysD.xReadyQueue->Suc->Signal);
#ifdef XPRSSENDER
      xSysD.xReadyQueue->Suc->Sender = xSysD.xReadyQueue->Suc->Signal->Sender;
#endif
      (*xSysD.xReadyQueue->Suc->RestartPAD)(xSysD.xReadyQueue->Suc);
#ifdef XEOWN
      xCheckForOwnLoops();
#endif
      if (xSysD.xCheckList->Suc != xSysD.xCheckList)
        xCheckCheckList(xSysD.xCheckList);
    }
#if !defined(XMONITOR) && !defined(XENV)
    else if ( xSysD.xTimerQueue->Suc != xSysD.xTimerQueue )
      xSysD.xSystemTime = ((xTimerNode)xSysD.xTimerQueue->Suc)->TimerTime;
    else
      SDL_Halt();
#endif

#endif


    /*Main loop for real time i.e. defined(XCLOCK) && !defined(XMONITOR).*/

#if defined(XCLOCK) && !defined(XMONITOR)

#ifdef XTENV
    T = SDL_Now();
    if ( xGE_SDL_Time(T, xNextENVInTime) )
      xNextENVInTime = xInEnv( xSysD.xReadyQueue->Suc != xSysD.xReadyQueue
                               ? T : ((xTimerNode)xSysD.xTimerQueue->Suc)->TimerTime);
#endif
#if !defined(XTENV) && defined(XENV)
    (void)xInEnv( xSysD.xReadyQueue->Suc != xSysD.xReadyQueue
                  ? SDL_Now() : ((xTimerNode)xSysD.xTimerQueue->Suc)->TimerTime);
#endif
#if defined(XCONNECTPM)
    xInPM();
#endif
    if ( xSysD.xTimerQueue->Suc != xSysD.xTimerQueue &&
         xLE_SDL_Time(((xTimerNode)xSysD.xTimerQueue->Suc)->TimerTime,
                      SDL_Now()) )
      SDL_OutputTimerSignal(xSysD.xTimerQueue->Suc);
    else if ( xSysD.xReadyQueue->Suc != xSysD.xReadyQueue) {
#if defined (XTRACE) || defined (THREADED_XTRACE)
      /* If xSysD.xReadyQueue->Suc->Signal is 0 or
         xSysD.xReadyQueue->Suc->Signal is not member of a list
         no trace of transition is performed. (Single step) */
      if ( (xSysD.xReadyQueue->Suc->Signal != (xSignalNode)0) &&
           (xSysD.xReadyQueue->Suc->Signal->Pre != (xSignalNode)0) )
        xTraceTransition(xSysD.xReadyQueue->Suc);
#endif
#ifdef XSIGLOG
      if ( (xSysD.xReadyQueue->Suc->Signal != (xSignalNode)0) &&
           (xSysD.xReadyQueue->Suc->Signal->Pre != (xSignalNode)0) )
              xProcessLog(xSysD.xReadyQueue->Suc);
#endif
      xRemoveFromQueue((void *)xSysD.xReadyQueue->Suc->Signal);
#ifdef XPRSSENDER
      xSysD.xReadyQueue->Suc->Sender = xSysD.xReadyQueue->Suc->Signal->Sender;
#endif
      (*xSysD.xReadyQueue->Suc->RestartPAD)(xSysD.xReadyQueue->Suc);
    }
#ifdef XTENV
    else
      xNextENVInTime = xInEnv(((xTimerNode)xSysD.xTimerQueue->Suc)->TimerTime);
#endif
#if !defined(XENV) && !defined(XCONNECTPM)
    else if ( xSysD.xTimerQueue->Suc != xSysD.xTimerQueue )
      xSleepUntil(((xTimerNode)xSysD.xTimerQueue->Suc)->TimerTime);
    else
      SDL_Halt();
#endif
    if (xSysD.xCheckList->Suc != xSysD.xCheckList)
      xCheckCheckList(xSysD.xCheckList);

#endif


    /*Main loop for real time and XMONITOR i.e. XCLOCK && XMONITOR.*/

#if defined(XCLOCK) && defined(XMONITOR)
#ifdef XTENV
    if ( xSysD.xInEnvOn ) {
      T = SDL_Now();
      if ( xGE_SDL_Time(T, xNextENVInTime) ) {
        if ( xSysD.xReadyQueue->Suc != xSysD.xReadyQueue ) {
          xNextENVInTime = xInEnv(T);
        } else {
          T = xNextMonTime();
          xNextENVInTime = xInEnv(
            xLT_SDL_Time(T, ((xTimerNode)xSysD.xTimerQueue->Suc)->TimerTime)
            ? T : ((xTimerNode)xSysD.xTimerQueue->Suc)->TimerTime );
        }
      }
    }
#endif
#if !defined(XTENV) && defined(XENV)
    if ( xSysD.xInEnvOn ) {
      if ( xSysD.xReadyQueue->Suc != xSysD.xReadyQueue ) {
        (void)xInEnv(SDL_Now());
      } else {
        T = xNextMonTime();
        (void)xInEnv(
          xLT_SDL_Time(T, ((xTimerNode)xSysD.xTimerQueue->Suc)->TimerTime)
          ? T : ((xTimerNode)xSysD.xTimerQueue->Suc)->TimerTime );
      }
    }
#endif
#if defined(XCONNECTPM)
    xInPM();
#endif
    xCheckMonitors();
#ifndef XENV
    T = xNextMonTime();
    if ( (xSysD.xReadyQueue->Suc == xSysD.xReadyQueue) &&
         xGT_SDL_Time(((xTimerNode)xSysD.xTimerQueue->Suc)->TimerTime, SDL_Now()) &&
         xGT_SDL_Time(T, SDL_Now()) ) {
      if ( xLT_SDL_Time(((xTimerNode)xSysD.xTimerQueue->Suc)->TimerTime, T) )
        T = ((xTimerNode)xSysD.xTimerQueue->Suc)->TimerTime;
      if ( xLT_SDL_Time (T, xMaxTime) ) {
        if ( xGT_SDL_Time(T, xPlus_SDL_Time(SDL_Now(),
               SDL_Duration_Lit( (xint32)1, (xint32)0) )) )
          T = xPlus_SDL_Time(SDL_Now(),
                SDL_Duration_Lit( (xint32)1, (xint32)0 ));
        xSleepUntil(T);
      }
    }
#endif
    if ( xSysD.xTimerQueue->Suc != xSysD.xTimerQueue &&
         xLE_SDL_Time(((xTimerNode)xSysD.xTimerQueue->Suc)->TimerTime,
                      SDL_Now()) ) {
      if (xSysD.xProceedUntil == 2)
        xSysD.xProceedUntil = 3;
      else
        SDL_OutputTimerSignal(xSysD.xTimerQueue->Suc);
    } else if ( xSysD.xReadyQueue->Suc != xSysD.xReadyQueue) {
#if defined (XTRACE) || defined (THREADED_XTRACE)
      /* If xSysD.xReadyQueue->Suc->Signal is 0 or
         xSysD.xReadyQueue->Suc->Signal is not member of a list
         no trace of transition is performed. (Single step) */
      if ( (xSysD.xReadyQueue->Suc->Signal != (xSignalNode)0) &&
           (xSysD.xReadyQueue->Suc->Signal->Pre != (xSignalNode)0) )
        xTraceTransition(xSysD.xReadyQueue->Suc);
#endif
#ifdef XSIGLOG
      if ( (xSysD.xReadyQueue->Suc->Signal != (xSignalNode)0) &&
           (xSysD.xReadyQueue->Suc->Signal->Pre != (xSignalNode)0) )
              xProcessLog(xSysD.xReadyQueue->Suc);
#endif
      xRemoveFromQueue((void *)xSysD.xReadyQueue->Suc->Signal);
#ifdef XPRSSENDER
      xSysD.xReadyQueue->Suc->Sender = xSysD.xReadyQueue->Suc->Signal->Sender;
#endif
      (*xSysD.xReadyQueue->Suc->RestartPAD)(xSysD.xReadyQueue->Suc);
    }
#ifdef XTENV
    else if ( xSysD.xInEnvOn ) {
      T = xNextMonTime();
      xNextENVInTime = 
        xInEnv( xLT_SDL_Time(T, ((xTimerNode)xSysD.xTimerQueue->Suc)->TimerTime)
                ? T : ((xTimerNode)xSysD.xTimerQueue->Suc)->TimerTime );
    }
#endif
    if (xSysD.xCheckList->Suc != xSysD.xCheckList)
      xCheckCheckList(xSysD.xCheckList);

#endif

  } /*while (1)*/
}
#endif


#ifndef XNOMAIN
/*---+---------------------------------------------------------------
     main
-------------------------------------------------------------------*/
#ifndef XMAIN_NAME
#define XMAIN_NAME main
#endif

#ifdef NUCLEUS_MNT
void XMAIN_NAME(UNSIGNED argc, VOID *argv)

#else

#ifdef XCONNECTPM
int XMAIN_NAME( int argc, char * argv[] )
#else
int XMAIN_NAME (void)
#endif
#endif  /* NUCLEUS MNT */
{

#ifdef XCONNECTPM
  xMainInit(argc, argv);
#else
  xMainInit();
#endif
#ifndef THREADED
  xMainLoop();
#endif
  return 0;
}
#endif


#ifdef THREADED
/*---+---------------------------------------------------------------
     xMainLoop
-------------------------------------------------------------------*/
#if defined(THREADSOLARIS) || defined(THREADVXWORKS)
void * xMainLoop (void * SysD)
#elif THREADOSE
OS_PROCESS(xMainLoop)
#else
void xMainLoop (xSystemData * SysD)
#endif /* THREADSOLARIS */
{
#ifdef XTENV
  SDL_Time xNextENVInTime;
  xNextENVInTime = SDL_Time_Lit( (xint32)0, (xint32)0 );
#endif
  THREADED_THREAD_BEGINNING(((xSystemData *)SysD))
  while (1) {
#ifdef XTENV
    T = SDL_Now();
    if ( xGE_SDL_Time(T, xNextENVInTime) )
      xNextENVInTime = xInEnv( ((xSystemData *)SysD)->xReadyQueue->Suc != ((xSystemData *)SysD)->xReadyQueue
                               ? T : ((xTimerNode)((xSystemData *)SysD)->xTimerQueue->Suc)->TimerTime);
#endif
#if !defined(XTENV) && defined(XENV)
    (void)xInEnv( ((xSystemData *)SysD)->xReadyQueue->Suc != ((xSystemData *)SysD)->xReadyQueue
                  ? SDL_Now() : ((xTimerNode)((xSystemData *)SysD)->xTimerQueue->Suc)->TimerTime);
#endif
    THREADED_LOCK_INPUTPORT(((xSystemData *)SysD))
		while (((xSystemData *)SysD)->xNewSignals.Suc != (xSignalNode)&((xSystemData *)SysD)->xNewSignals)
      SDL_Output(((xSystemData *)SysD)->xNewSignals.Suc xSigPrioPar(((xSystemData *)SysD)->xNewSignals.Suc->Prio), 0);
	  THREADED_UNLOCK_INPUTPORT(((xSystemData *)SysD))
    if ( ((xSystemData *)SysD)->xTimerQueue->Suc != ((xSystemData *)SysD)->xTimerQueue &&
         xLE_SDL_Time(((xTimerNode)((xSystemData *)SysD)->xTimerQueue->Suc)->TimerTime,
		 SDL_Now()) ) 
SDL_OutputTimerSignal(((xSystemData *)SysD)->xTimerQueue->Suc);
    else if ( ((xSystemData *)SysD)->xReadyQueue->Suc != ((xSystemData *)SysD)->xReadyQueue) {
#ifdef XSIGLOG
      if ( (((xSystemData *)SysD)->xReadyQueue->Suc->Signal != (xSignalNode)0) &&
           (((xSystemData *)SysD)->xReadyQueue->Suc->Signal->Pre != (xSignalNode)0) )
              xProcessLog(((xSystemData *)SysD)->xReadyQueue->Suc);
#endif
      xRemoveFromQueue((void *)((xSystemData *)SysD)->xReadyQueue->Suc->Signal);
      (*((xSystemData *)SysD)->xReadyQueue->Suc->RestartPAD)(((xSystemData *)SysD)->xReadyQueue->Suc);
	} else {
      THREADED_LOCK_INPUTPORT(((xSystemData *)SysD))
      if (((xSystemData *)SysD)->xNewSignals.Suc == (xSignalNode)&((xSystemData *)SysD)->xNewSignals) {
        THREADED_WAIT_AND_UNLOCK_INPUTPORT(((xSystemData *)SysD))
      } else {
        THREADED_UNLOCK_INPUTPORT(((xSystemData *)SysD))
      }
    }
    if (((xSystemData *)SysD)->xCheckList->Suc != ((xSystemData *)SysD)->xCheckList)
      xCheckCheckList(((xSystemData *)SysD)->xCheckList);
  }
#if defined(THREADSOLARIS) || defined(THREADVXWORKS)
return 0;
#endif
}
#endif  /* THREADED */


#if defined(XNOMAIN) && !defined(THREADED)
/*---+---------------------------------------------------------------
     SDL_OutputTimer
-------------------------------------------------------------------*/
void SDL_OutputTimer (void)
{
  SDL_OutputTimerSignal(xSysD.xTimerQueue->Suc);
  if (xSysD.xCheckList->Suc != xSysD.xCheckList)
    xCheckCheckList(xSysD.xCheckList);
}


/*---+---------------------------------------------------------------
     SDL_Execute
-------------------------------------------------------------------*/
void SDL_Execute (void)
{
#if defined (XTRACE) || defined (THREADED_XTRACE)
  /* If xSysD.xReadyQueue->Suc->Signal is 0 or
     xSysD.xReadyQueue->Suc->Signal is not member of a list
     no trace of transition is performed. (Single step) */
  if ( (xSysD.xReadyQueue->Suc->Signal != (xSignalNode)0) &&
       (xSysD.xReadyQueue->Suc->Signal->Pre != (xSignalNode)0) )
    xTraceTransition(xSysD.xReadyQueue->Suc);
#endif
#ifdef XSIGLOG
      if ( (xSysD.xReadyQueue->Suc->Signal != (xSignalNode)0) &&
           (xSysD.xReadyQueue->Suc->Signal->Pre != (xSignalNode)0) )
              xProcessLog(xSysD.xReadyQueue->Suc);
#endif
  xRemoveFromQueue((void *)xSysD.xReadyQueue->Suc->Signal);
  (*xSysD.xReadyQueue->Suc->RestartPAD)(xSysD.xReadyQueue->Suc);
  if (xSysD.xCheckList->Suc != xSysD.xCheckList)
    xCheckCheckList(xSysD.xCheckList);
}


/*---+---------------------------------------------------------------
     SDL_Timer_Prio
-------------------------------------------------------------------*/
int SDL_Timer_Prio (void)
{
  if ( xGT_SDL_Time(((xTimerNode)xSysD.xTimerQueue->Suc)->TimerTime, SDL_Now()) )
    return -1;
  else
#if defined(XPRSPRIO) || defined(XPRSSIGPRIO)
    return xSysD.xTimerQueue->Suc->Receiver.
           LocalPId->PrsP->NameNode->Prio;
#endif
#if defined(XSIGPRIO) || defined(XSIGPRSPRIO)
    return xSysD.xTimerQueue->Suc->Prio;
#endif
#if ! (defined(XPRSPRIO) || defined(XPRSSIGPRIO) || defined(XSIGPRIO) || defined(XSIGPRSPRIO))
    return xDefaultPrioProcess;
#endif
}


/*---+---------------------------------------------------------------
     SDL_Transition_Prio
-------------------------------------------------------------------*/
int SDL_Transition_Prio (void)
{
  if ( xSysD.xReadyQueue->Suc == xSysD.xReadyQueue )
    return -1;
  else
#if defined(XPRSPRIO) || defined(XPRSSIGPRIO)
    return xSysD.xReadyQueue->Suc->NameNode->Prio;
#endif
#if defined(XSIGPRIO) || defined(XSIGPRSPRIO)
    return xSysD.xReadyQueue->Suc->Signal->Prio;
#endif
#if ! (defined(XPRSPRIO) || defined(XPRSSIGPRIO) || defined(XSIGPRIO) || defined(XSIGPRSPRIO))
    return xDefaultPrioProcess;
#endif
}


/*---+---------------------------------------------------------------
     SDL_Timer_Time
-------------------------------------------------------------------*/
SDL_Time SDL_Timer_Time (void)
{
  return ((xTimerNode)xSysD.xTimerQueue->Suc)->TimerTime;
}
#endif
       /* XNOMAIN && !THREADED */



/**************************************************************/
/*        FUNCTIONS USED FOR PARTITIONING OF SYSTEMS          */
/**************************************************************/

#ifndef XOPTCHAN
/*---+---------------------------------------------------------------
     xAddToEnv
-------------------------------------------------------------------*/
void xAddToEnv (xChannelIdNode ChanId)
{
  static int Remains = XTRACHANNELSTOENV;
  int i;

#ifndef XFIXED_SIZE_ENV_LIST
  static int AddIfNeeded = 20;
  xIdNode *OldList;
  for (i=0; xEnvId->ToId[i] != (xIdNode)0; i++)
    ;
  if (Remains == 0) {
    OldList = xEnvId->ToId;
    xEnvId->ToId = (xIdNode *)xAlloc(sizeof(xIdNode *) * (i+AddIfNeeded));
    for (i=0; OldList[i] != (xIdNode)0; i++)
      xEnvId->ToId[i] = OldList[i];
    if (AddIfNeeded > 20)
      xFree((void **)&OldList);   /* Do not free first one, as it is not allocated */
    Remains = AddIfNeeded;
    AddIfNeeded = AddIfNeeded*2;
  }
  xEnvId->ToId[i] = (xIdNode)ChanId;
  Remains--;

#else

  if (Remains == 0) {
#ifdef XREADANDWRITEF
    xPrintString("Too many channels added to Env, terminating ...\n");
#endif
    exit(1);
    /* If your program exits here, you should redefine XTRACHANNELSTOENV
       to a larger value and redefine XTRACHANNELLIST to an approriate
       number of zeroes */
  }
  for (i=0; xEnvId->ToId[i] != (xIdNode)0; i++)
    ;
  xEnvId->ToId[i] = (xIdNode)ChanId;
  Remains--;
#endif
}
#endif



#ifdef XEOWN
/**************************************************************/
/*                  OWN DATA TYPE HANDLING                    */
/**************************************************************/

typedef struct xOwnListStr {
  void               *Ptr;
  tSDLTypeInfo       *Sort;
  xPrsNode            Owner;
  struct xOwnListStr *Next;
  int                 Flag;
} xOwnListType;
static xOwnListType *xOwnList = 0;


static xOwnListType * xLocateInOwnList(void *Ptr)
{
  xOwnListType * obj;
  obj = xOwnList;
  while (obj != 0 && obj->Ptr != Ptr)
    obj = obj->Next;
  return obj;
}

xbool xInOwnList(void *Ptr)
{
  if (xLocateInOwnList(Ptr))
    return (xbool)1;
  return (xbool)0;
}

void xInsertOwnList(void *Ptr, tSDLTypeInfo *Sort)
{
  xOwnListType *newobj;
  newobj = (xOwnListType *)xAlloc(sizeof(xOwnListType));
  newobj->Ptr = Ptr;
  newobj->Sort = Sort;
  newobj->Owner = xSysD.xReadyQueue->Suc;
  newobj->Flag = 0;
  newobj->Next = xOwnList;
  xOwnList = newobj;
}

void xRemoveOwnList(void *Ptr)
{
  xOwnListType *curobj, *prevobj;
  if (xOwnList == 0) {
    xPrintString("Internal error: OwnList 0 in RemoveOwnList\n");
  } else if (xOwnList->Ptr == Ptr) {
    curobj = xOwnList;
    xOwnList = xOwnList->Next;
    xFree((void **)&curobj);
  } else {
    prevobj = xOwnList;
    curobj = xOwnList->Next;
    while (curobj != 0) {
      if (curobj->Ptr == Ptr) {
        prevobj->Next = curobj->Next;
        xFree((void **)&curobj);
        curobj = 0;
      } else {
        prevobj = curobj;
        curobj = curobj->Next;
        if (curobj == 0)
          xPrintString("Internal error: Object not found in RemoveOwnList\n");
      }
    }
  }
}

static void xLocalSetUpOwner(void ** Value, tSDLTypeInfo *S, xbool ToSignal)
{
  xOwnListType * obj;
  int i;

  if (S->TypeClass == type_SDL_Own) {
    obj = xLocateInOwnList(*Value);
    if (obj != 0) {
      if (ToSignal)
	obj->Owner = 0;
      else
	obj->Owner = xSysD.xReadyQueue->Suc;
      xLocalSetUpOwner((void **)*Value, ((tSDLGenInfo *)S)->CompOrFatherSort,
                       ToSignal);
    }
  } else if (S->TypeClass == type_SDL_Struct) {
    for (i=0; i<((tSDLStructInfo *)S)->NumOfComponents; i++) {
      xLocalSetUpOwner((void **)((xptrint)Value+
                  ((tSDLStructInfo *)S)->Components[i].Offset), 
                  ((tSDLStructInfo *)S)->Components[i].CompSort, ToSignal);
    }
  } else if (S->TypeClass == type_SDL_Array) {
    for (i=0; i<((tSDLArrayInfo *)S)->Length; i++) {
      xLocalSetUpOwner(
         (void **)((xptrint)Value +
                  i*((tSDLArrayInfo *)S)->CompSort->SortSize),
         ((tSDLArrayInfo *)S)->CompSort, ToSignal);
    }
  }
}

void xSetUpOwner(void **Ptr, xbool ToSignal)
{
  xOwnListType * obj;
  obj = xLocateInOwnList(*Ptr);
  if (obj != 0) xLocalSetUpOwner(Ptr, obj->Sort, ToSignal);
}


static xptrint IsStackVarInUnit (xIdNode P)
{
  xVarIdNode V;
  xptrint Offset;
  Offset = 0;
  while (P != 0) {
    V = (xVarIdNode)P->First;
    while (V != 0) {
      if (V->EC == xVariableEC || V->EC == xFormalParEC) {
	if (V->Offset + V->TypeNode->SortSize > Offset)
	  Offset = V->Offset + V->TypeNode->SortSize;
      }
      V = (xVarIdNode)V->Suc;
    }
    if (P->EC == xProcessEC)
      P = (xIdNode)((xPrsIdNode)P)->Super;
#ifndef XNOUSEOFSERVICE
    else if (P->EC == xServiceEC)
      P = (xIdNode)((xSrvIdNode)P)->Super;
#endif
    else if (P->EC == xProcedureEC)
      P = (xIdNode)((xPrdIdNode)P)->Super;
    else
      P = 0;
  }
  return Offset;
}


static xbool IsStackVariable( void * Ptr )
{
  xPrsNode P;
  xPrdNode Prd;
  xptrint Offset;
  P = xSysD.xReadyQueue->Suc;

  /* Test variables in process */
  Offset = IsStackVarInUnit((xIdNode)(xVarIdNode)P->NameNode);
  if ((xptrint)Ptr >= (xptrint)P && (xptrint)Ptr <= (xptrint)P+Offset)
    return (xbool)1;

  /* Test variables in service */
#ifndef XNOUSEOFSERVICE
  if (P->ActiveSrv != (xSrvNode)0) {
    Offset = IsStackVarInUnit((xIdNode)(xVarIdNode)P->ActiveSrv->NameNode);
    if ((xptrint)Ptr >= (xptrint)P->ActivePrd &&
        (xptrint)Ptr <= (xptrint)P->ActivePrd+Offset)
      return (xbool)1;
  }
#endif

  /* Test variables in procedures */
#ifndef XNOUSEOFSERVICE
  if (P->ActiveSrv != (xSrvNode)0)
    Prd = P->ActiveSrv->ActivePrd;
  else
#endif
    Prd = P->ActivePrd;
  while (Prd != 0) {
    Offset = IsStackVarInUnit((xIdNode)(xVarIdNode)Prd->NameNode);
    if ((xptrint)Ptr >= (xptrint)Prd && (xptrint)Ptr <= (xptrint)Prd+Offset)
      return (xbool)1;
    Prd = Prd->DynamicFather;
  }

  return (xbool)0;
}


void xCheckRefOwn(void * Ptr)
{
  xOwnListType * obj;
  obj = xLocateInOwnList(Ptr);
  if (obj == 0) {
    if (!IsStackVariable(Ptr)) {
      xPrintString("\n*************************** ERROR **************************");
      xPrintString("\nRef Error : reference to deallocated data\n");
      xSDLDynamicErrorInfo(xSysD.xReadyQueue->Suc);
#ifdef XMONITOR
      xSysD.xDynamicError = (xbool)1;
#ifdef XSTOPONSERIOUSERROR
      xPrintString("\nSerious Error. The program will terminate when leaving the monitor\n");
      xCheckMonitors();
      xHalt();
#endif
#endif
    }
  } else if (obj->Owner != xSysD.xReadyQueue->Suc) {
    xPrintString("\n*************************** ERROR **************************");
    xPrintString("\nRef Error : reference to data owned by ");
    if (obj->Owner == 0)
      xPrintString("a signal\n");
    else {
      xPrintString(xWri_SDL_PId(&obj->Owner->Self));
      xPrintString("\n");
    }
    xSDLDynamicErrorInfo(xSysD.xReadyQueue->Suc);
#ifdef XMONITOR
    xSysD.xDynamicError = (xbool)1;
#endif
  }
}


static void xLocalCheckLoops(void ** Value, tSDLTypeInfo *S, xbool MarkLoop)
{
  xOwnListType * obj;
  int i;

  if (S->TypeClass == type_SDL_Own) {
    obj = xLocateInOwnList(*Value);
    if (obj != 0) {
      if (MarkLoop) {
        if (obj->Flag != 3) {
          obj->Flag = 3;
          xLocalCheckLoops((void **)*Value, ((tSDLGenInfo *)S)->CompOrFatherSort,
                           MarkLoop);
	}
      } else if (obj->Flag == 0) {
        obj->Flag = 1;
	xLocalCheckLoops((void **)*Value, ((tSDLGenInfo *)S)->CompOrFatherSort,
                         MarkLoop);
      } else if (obj->Flag == 1) {
        xPrintString("\n*************************** ERROR **************************\n");
	xPrintString("During the previous transition a loop of own data has been created.\n");
	xPrintString("This memory will be lost.\n");
	xPrintString("************************************************************\n");
#ifdef XMONITOR
	xSysD.xDynamicError = (xbool)1;
#endif
        obj->Flag = 3;
      }
    }
  } else if (S->TypeClass == type_SDL_Struct) {
    for (i=0; i<((tSDLStructInfo *)S)->NumOfComponents; i++) {
      xLocalCheckLoops((void **)((xptrint)Value+
                                 ((tSDLStructInfo *)S)->Components[i].Offset), 
                       ((tSDLStructInfo *)S)->Components[i].CompSort, MarkLoop);
    }
  } else if (S->TypeClass == type_SDL_Array) {
    for (i=0; i<((tSDLArrayInfo *)S)->Length; i++) {
      xLocalCheckLoops(
         (void **)((xptrint)Value +
                   i*((tSDLArrayInfo *)S)->CompSort->SortSize),
         ((tSDLArrayInfo *)S)->CompSort, MarkLoop);
    }
  }
}



void xCheckForOwnLoops (void)
{
  xOwnListType * obj;
  xOwnListType * obj2;
  /* For all objects not already part of detected loop, set Flag to 0 */
  /* Flag = 0 : object not yet tested
            1 : object found in the current "sequence"
            2 : object tested and is not part of loop
            3 : object part of already reported loop
  */
  for (obj2=xOwnList; obj2!=0; obj2=obj2->Next)
    if (obj2->Flag <= 2)
      obj2->Flag = 0;
  /* Test for all objects if they are part of loop */
  for (obj=xOwnList; obj!=0; obj=obj->Next) {
    if (obj->Flag == 0) {
      xLocalCheckLoops(&obj->Ptr, obj->Sort, (xbool)0);
      for (obj2=xOwnList; obj2!=0; obj2=obj2->Next)
        if (obj2->Flag == 1)
          obj2->Flag = 2;
    }
  }
}

#endif  /* XEOWN */



#ifdef XEALLOC
/**************************************************************/
/*                  ALLOC TEST FUNCTIONS                      */
/**************************************************************/

typedef struct xPtrListStr {
  void               *Ptr;
  tSDLTypeInfo       *S;
  struct xPtrListStr *Next;
} xPtrListType;
static xPtrListType *xPtrList = 0;

void * xAllocSort(xptrint Size, tSDLTypeInfo * S)
{
  void * Result;
  struct xPtrListStr *tmp;
  Result = xAlloc(Size);
  if (Result == 0) return Result;
  tmp = (struct xPtrListStr *)malloc(sizeof(struct xPtrListStr));
  tmp->Ptr = Result;
  tmp->S = S;
  tmp->Next = xPtrList;
  xPtrList = tmp;
#ifdef XEALLOC_TRACE
#ifdef T_SDL_NAMES
  if (S != 0)
    printf("*       alloc of data %s at address %p\n", S->Name, Result);
  else
#endif
    printf("*       alloc of data at address %p\n", Result);
#endif
  return Result;
}


void xFreeSort(void ** Ptr)
{
  struct xPtrListStr *tmp;
  struct xPtrListStr *prevtmp;

  if (*Ptr == 0) return;
  if (xPtrList == 0) {
    printf("Pointer not found in list of currently allocated memory\n");
    xFree(Ptr);
    return;
  }
  prevtmp = xPtrList;
  if (prevtmp->Ptr == *Ptr) {
    xPtrList = prevtmp->Next;
#ifdef XEALLOC_TRACE
#ifdef T_SDL_NAMES
    if (prevtmp->S != 0)
      printf("*       free of data %s at address %p\n", prevtmp->S->Name, *Ptr);
    else
#endif
      printf("*       free of data at address %p\n", *Ptr);
#endif
    free(prevtmp);
    xFree(Ptr);
    return;
  }
  tmp = prevtmp->Next;
  while (tmp != 0) {
    if (tmp->Ptr == *Ptr) {
      prevtmp->Next = tmp->Next;
#ifdef XEALLOC_TRACE
#ifdef T_SDL_NAMES
      if (tmp->S != 0)
	printf("*       free of data %s at address %p\n", tmp->S->Name, *Ptr);
      else
#endif
	printf("*       free of data at address %p\n", *Ptr);
#endif
      free(tmp);
      xFree(Ptr);
      return;
    }
    prevtmp = tmp;
    tmp = prevtmp->Next;
  }
  printf("Pointer not found in list of currently allocated memory\n");
  xFree(Ptr);
}


#ifndef XSCT_CMICRO
#ifdef XSYMBTLINK
static void CleanUpAtExit(xIdNode P)
{
  xIdNode Son;
  if (P->EC == xProcessEC) {
#if defined (XTRACE) || defined (THREADED_XTRACE)
    ((xPrsIdNode)P)->Trace_Default = 0;
#endif
#ifdef XGRTRACE
    ((xPrsIdNode)P)->GRTrace = 0;
#endif
#ifdef XMSCE
    ((xPrsIdNode)P)->MSCETrace = 0;
#endif
    while (*((xPrsIdNode)P)->ActivePrsList != 0)
      SDL_Stop(*((xPrsIdNode)P)->ActivePrsList);
  } else {
    for (Son = P->First; Son != 0; Son = Son->Suc)
      CleanUpAtExit(Son);
  }
}
#endif
#endif


void xReportPtrList(void)
{
  struct xPtrListStr *tmp;
  int i = 0;
#ifndef XSCT_CMICRO
#ifdef XSYMBTLINK
  CleanUpAtExit(&xSymbolTableIdRec);
#endif
#endif
  tmp = xPtrList;
  while (tmp != 0) {
    tmp = tmp->Next;
    i++;
  }
  if (i > 0) {
    printf("Memory leak: %d items\n", i);
    tmp = xPtrList;
    while (tmp != 0) {
#ifdef T_SDL_NAMES
      if (tmp->S != 0)
        printf("Type: %s  Address: %p\n", tmp->S->Name, tmp->Ptr);
      else
#endif
        printf("Type: not known  Address: %p\n", tmp->Ptr);
      tmp = tmp->Next;
    }
  } else
    printf("No memory leaks\n");
}



#endif  /* XEALLOC */

#if defined(THREADED) && !defined(XNOUSE_THREADED_API)

/**************************************************************/
/*                  THREADED API FUNCTIONS                 */
/**************************************************************/
/*---+---------------------------------------------------------------
     xThreadedRegExtTask
-------------------------------------------------------------------*/
/* Creates an SDL_PId representing an external thread. */
SDL_PId xThreadedRegExtTask()
{
  xPrsIdRec * PrsIdExtTaskPtr;
  SDL_PId SDLIdExtTask;
  xSystemData * SysDExtTaskPtr;
  xPrsNode yPrsB_ExtTask = (xPrsNode)0;
  xPrsNode yPrsA_ExtTask = (xPrsNode)0;
  THREADED_THREADID_TYPE MyThreadId;

  /* Get ThreadId for your external task */
  MyThreadId = THREADED_GET_CURRENT_THREAD_ID;

  THREADED_REGEXTTASK_LOCAL_VARS

  THREADED_REGEXTTASK_CREATE_QUEUE

  /* Allocates an xPrsIdRec for the External thread */
  PrsIdExtTaskPtr = xAlloc(sizeof(xPrsIdRec));
  memset((void *)PrsIdExtTaskPtr,0,sizeof(xPrsIdRec));

  /* Assign necessary elements in the xPrsIdRec */
  PrsIdExtTaskPtr->ActivePrsList = &yPrsB_ExtTask;
  PrsIdExtTaskPtr->AvailPrsList = &yPrsA_ExtTask;
  PrsIdExtTaskPtr->VarSize = sizeof(xPrsRec);
  PrsIdExtTaskPtr->EC = xProcessEC;

#ifdef THREADED_MSCTRACE
  /* Additional assignments needed for MSC trace */
  PrsIdExtTaskPtr->Name = "ExtTask";
  PrsIdExtTaskPtr->MSCETrace =1;
#endif /* THREADED_MSCTRACE */

  /* Calling the kernel function xGetPId() to get an SDL_PId */
  SDLIdExtTask = xGetPId(PrsIdExtTaskPtr, SDL_NULL);

#ifdef THREADED_MSCTRACE
  xMSCECreate(SDLIdExtTask,(xSignalNode)0);
#endif

  /* Allocate and initialize a "system data record" for the external thread. 
     This record holds the inputqueues, the syncronization semaphores and 
     the external threadid for the SDL process */
  SysDExtTaskPtr = xAlloc(sizeof(xSystemData));
  xSysDInit(SysDExtTaskPtr);
  THREADED_REGEXTTASK_ASSIGN_THREADID

  /* Assign the SysD entry the "system data record" */
  SDLIdExtTask.LocalPId->PrsP->SysD = SysDExtTaskPtr;
  return SDLIdExtTask;
/*#endif  THREADED_ALTERNATIVE_SIGNAL_SENDING */
}

/*---+---------------------------------------------------------------
     xThreadedReceiveSDLSig_WithTimeOut
-------------------------------------------------------------------*/
/* Wait for the specified time for inputport-semaphore to be signaled or signal to be received 
   (Alternative signalsending used). Remove the signal 
   from the inputport and return the SDL Signal. If MSCTrace is on a 
   Trace function is called. */
xSignalNode xThreadedReceiveSDLSig_WithTimeOut(SDL_PId ExtTask, SDL_Duration TimeOut)
{
  xSignalNode yInputSignalPtr;

  THREADED_RECEIVESDLSIG(TimeOut)

  /* Check if new signal in inputport */
  if(ExtTask.LocalPId->PrsP->SysD->xNewSignals.Suc !=(xSignalNode)&(ExtTask.LocalPId->PrsP->SysD->xNewSignals)) {

#ifdef THREADED_MSCTRACE
    /* If MSCTrace is on the signal must be assigned to the xPrsRec->Signal entry */
    ExtTask.LocalPId->PrsP->Signal = ExtTask.LocalPId->PrsP->SysD->xNewSignals.Suc;
    xMSCETransition(ExtTask.LocalPId->PrsP);
    ExtTask.LocalPId->PrsP->Signal = NULL;
#endif

    /* Take the signal out of the input queue and set the Suc and Pre pointers right.
       Return the signal.*/
    yInputSignalPtr = ExtTask.LocalPId->PrsP->SysD->xNewSignals.Suc;
    ExtTask.LocalPId->PrsP->SysD->xNewSignals.Suc = ExtTask.LocalPId->PrsP->SysD->xNewSignals.Suc->Suc;
    ExtTask.LocalPId->PrsP->SysD->xNewSignals.Suc->Pre = (xSignalNode)&(ExtTask.LocalPId->PrsP->SysD->xNewSignals);
    return yInputSignalPtr;
  }
}

/*---+---------------------------------------------------------------
     xThreadedReceiveSDLSig
-------------------------------------------------------------------*/
/* Wait indefinitely for inputport-semaphore to be signaled or signal to be received 
   (Alternative signalsending). Remove the signal 
   from the inputport and return the SDL Signal. If MSCTrace is on a 
   Trace function is called. */
xSignalNode xThreadedReceiveSDLSig(SDL_PId ExtTask)
{
  SDL_Duration TimeOut;
  xSignalNode yInputSignalPtr;

  TimeOut = SDL_Duration_Lit(0,0);

  yInputSignalPtr = xThreadedReceiveSDLSig_WithTimeOut(ExtTask, TimeOut);
  return yInputSignalPtr;
}
#endif /* XNOUSE_THREADED_API */
