Esempio n. 1
0
File: taskLib.c Progetto: phoboz/vmx
STATUS taskRestart(
    int taskId
    )
{
  TCB_ID tcbId;
  char *name, *rename;
  int len;
  unsigned priority;
  int options;
  char *pStackBase;
  unsigned stackSize;
  FUNCPTR entry;
  ARG args[MAX_TASK_ARGS];
  STATUS status;

  if (INT_RESTRICT() != OK)
  {
    errnoSet(S_intLib_NOT_ISR_CALLABLE);
    return ERROR;
  }

  /* If self restart */
  if ( (taskId == 0) || (taskId == (int) taskIdCurrent) )
  {

    /* Task must be unsafe */
    while (taskIdCurrent->safeCount > 0)
      taskSafe();

    /* Spawn a task that will restart this task */
    taskSpawn(restartTaskName, restartTaskPriority, restartTaskOptions,
              restartTaskStackSize, taskRestart, (ARG) taskIdCurrent,
              (ARG) 0,
              (ARG) 0,
              (ARG) 0,
              (ARG) 0,
              (ARG) 0,
              (ARG) 0,
              (ARG) 0,
              (ARG) 0,
              (ARG) 0);

    /* Wait for restart */
    while (1)
      taskSuspend(0);

  } /* End if self restart */

  /* Get task context */
  tcbId = taskTcb(taskId);
  if (tcbId == NULL)
    return ERROR;

  /* TASK_ID_VERIFY() already done by taskTcb() */

  /* Copy task data */
  priority = tcbId->priority;
  options = tcbId->options;
  entry = tcbId->entry;
  pStackBase = tcbId->pStackBase;
  stackSize = (tcbId->pStackEnd - tcbId->pStackBase) * _STACK_DIR;
  taskArgGet(tcbId, pStackBase, args);

  /* Copy name if needed */
  name = tcbId->name;
  rename = NULL;
  if (name != NULL) {
    len = strlen(name) + 1;
    rename = malloc(len);
    if (rename != NULL)
      strcpy(rename, name);
    name = rename;
  }

  /* Prevent deletion */
  taskSafe();

  if (taskTerminate((int) tcbId) != OK)
  {
    taskUnsafe();
    /* errno set by taskTerminate() */
    return ERROR;
  }

  /* Initialize task with same data */
  status = taskInit(tcbId, name, priority, options, pStackBase,
                    stackSize, entry, args[0], args[1], args[2],
                    args[3], args[4], args[5], args[6], args[7],
                    args[8], args[9]);
  if (status != OK)
  {
    /* errno set by taskInit() */
    return ERROR;
  }

  /* And start it */
  status = taskActivate((int) tcbId);
  if (status != OK)
  {
    /* errno set by taskActivate() */
    return ERROR;
  }

  /* Make me mortal */
  taskUnsafe();

  /* Free rename buffer if needed */
  if (rename != NULL)
    free(rename);

  return OK;
}
Esempio n. 2
0
STATUS msgQSmSend 
    (
    SM_MSG_Q_ID    smMsgQId,       /* message queue on which to send */
    char *         buffer,         /* message to send */
    UINT           nBytes,         /* length of message */
    int            timeout,        /* ticks to wait */
    int            priority        /* MSG_PRI_NORMAL or MSG_PRI_URGENT */
    )
    {
    SM_MSG_NODE volatile * pMsg;
    SM_DL_NODE *           prevNode;
    int                    level;
    SM_MSG_Q_ID volatile   smMsgQIdv = (SM_MSG_Q_ID volatile) smMsgQId;
    int                    temp;   /* temp storage */

    if (INT_RESTRICT () != OK)          /* not ISR callable */
        {
        return (ERROR);
        }

    CACHE_PIPE_FLUSH ();                        /* CACHE FLUSH   [SPR 68334] */
    temp = smMsgQIdv->verify;                   /* PCI bridge bug [SPR 68844]*/

    if (SM_OBJ_VERIFY (smMsgQIdv) != OK)
        {
	return (ERROR);
        }

    if (nBytes > ntohl (smMsgQId->maxMsgLength))
	{
	errno = S_msgQLib_INVALID_MSG_LENGTH;
	return (ERROR);
	}

    TASK_LOCK ();

    /* windview level 2 event logging, uses the OSE logging routine */

    EVT_OBJ_SM_MSGQ (EVENT_MSGQSEND, smMsgQId, buffer, nBytes, timeout, 
		     priority,5);

    /* get a free message by taking free msg Q shared counting semaphore */

    if (semSmTake (&smMsgQId->freeQSem, timeout) != OK)
	{
	smMsgQId->sendTimeouts = htonl (ntohl (smMsgQId->sendTimeouts) + 1);
	TASK_UNLOCK ();
	return (ERROR);
	}

    /* a free message was available before timeout, get it */

    if (SM_OBJ_LOCK_TAKE (&smMsgQId->freeQLock, &level) != OK)
        {
	smObjTimeoutLogMsg ("msgQSend", (char *) &smMsgQId->freeQLock);
        TASK_UNLOCK ();
        return (ERROR);                         /* can't take lock */
	}
    pMsg = (SM_MSG_NODE volatile *) smDllGet (&smMsgQId->freeQ);

    SM_OBJ_LOCK_GIVE (&smMsgQId->freeQLock, level);/* release lock */

    pMsg->msgLength = htonl (nBytes);

    bcopy (buffer, SM_MSG_NODE_DATA (pMsg), (int) nBytes);

    CACHE_PIPE_FLUSH ();                        /* CACHE FLUSH   [SPR 68334] */
    temp = pMsg->msgLength;                     /* BRIDGE FLUSH  [SPR 68334] */

    /* now send message */

    if (SM_OBJ_LOCK_TAKE (&smMsgQId->msgQLock, &level) != OK)
        {
	smObjTimeoutLogMsg ("msgQSend", (char *) &smMsgQId->msgQLock);
        TASK_UNLOCK ();
        return (ERROR);                         /* can't take lock */
	}

    /* insert message in message list according to its priority */

    if (priority == MSG_PRI_NORMAL) 
	{
	prevNode = (SM_DL_NODE *) SM_DL_LAST (&smMsgQId->msgQ);
	}
    else prevNode = NULL; 

    smDllInsert (&smMsgQId->msgQ, prevNode, (SM_DL_NODE *) pMsg);

    SM_OBJ_LOCK_GIVE (&smMsgQId->msgQLock, level);/* release lock */
    
      /*
       * If another CPU is currently doing a msgQ send
       * we can have a case where the other CPU has put a message and
       * is delayed by an interrupt before Giving the shared
       * semaphore. In that case, this CPU can put its message and Give
       * the shared semaphore, the receiver will be unblocked by
       * the Give done by this CPU but the message obtained will
       * be the one put by the other CPU (FIFO order of messages will be kept).
       */

    /* unblock receiver */

    if (semSmGive (&smMsgQId->msgQSem) != OK)
        {
        TASK_UNLOCK (); 
	return (ERROR);
	}	

    TASK_UNLOCK ();

    return (OK);
    }
Esempio n. 3
0
File: semBLib.c Progetto: phoboz/vmx
LOCAL STATUS semBTake(
    SEM_ID semId,
    unsigned timeout
    )
{
    STATUS status;
    int level;

    if (INT_RESTRICT() != OK)
    {
        errnoSet (S_intLib_NOT_ISR_CALLABLE);
        status = ERROR;
    }
    else
    {
        /* Loop here if status is SIG_RESTART */
        do
        {
            /* Lock interrupts */
            INT_LOCK(level);

            /* Verify class */
            if (OBJ_VERIFY(semId, semClassId) != OK)
            {
                INT_UNLOCK(level);
                status = ERROR;
                break;
            }

            /* Check if it is already given back */
            if (SEM_OWNER_GET(semId) == NULL)
            {
                /* Then take it */
                SEM_OWNER_SET(semId, taskIdCurrent);

                /* Unlock interrupts */
                INT_UNLOCK(level);
                status = OK;
                break;
            }

            if (timeout == WAIT_NONE)
            {
                INT_UNLOCK(level);
                errnoSet(S_objLib_UNAVAILABLE);
                status = ERROR;
                break;
            }

            /* Enter kernel mode */
            kernelState = TRUE;
            INT_UNLOCK(level);

            /* Put on pending queue */
            vmxPendQPut(&semId->qHead, timeout);

            /* Exit through kernel */
            status = vmxExit();
        } while(status == SIG_RESTART);
    }

    return status;
}
Esempio n. 4
0
MSG_Q_ID msgQSmCreate 
    (
    int	maxMsgs,	/* max messages that can be queued */
    int	maxMsgLength,	/* max bytes in a message */
    int	options		/* message queue options */
    )
    {
    SM_MSG_Q_ID	smMsgQId;
    void *	pSmMsgPool;	/* pointer to memory for messages */
    int         nodeSize = SM_MSG_NODE_SIZE (maxMsgLength);
    int         temp;           /* temp storage */

    if (INT_RESTRICT () != OK)	/* restrict ISR from calling */
        {
	return (NULL);
        }

    /* 
     * allocate shared memory message queue descriptor from 
     * dedicated shared memory pool.
     */

    smMsgQId = (SM_MSG_Q_ID) smMemPartAlloc ((SM_PART_ID) smMsgQPartId,
                                             sizeof (SM_MSG_Q));
    if (smMsgQId == NULL)
        {
	return (NULL);
        }

    /* 
     * allocate shared memory message queue data buffers from 
     * shared memory system pool.
     */

    pSmMsgPool = smMemMalloc (nodeSize * maxMsgs);
    if (pSmMsgPool == NULL)
    	{ 
	smMemPartFree ((SM_PART_ID) smMsgQPartId, (char *) smMsgQId);
	return (NULL);
	}

    /* Initialize shared memory message queue structure */

    if (msgQSmInit (smMsgQId, maxMsgs, maxMsgLength, options, pSmMsgPool) !=OK)
	{
	smMemPartFree ((SM_PART_ID) smMsgQPartId, (char *) smMsgQId);
	smMemFree ((char *) pSmMsgPool);
	return (NULL);
	}

    /* update shared infos data */

    CACHE_PIPE_FLUSH ();                        /* CACHE FLUSH   [SPR 68334] */
    temp = pSmObjHdr->curNumMsgQ;               /* PCI bridge bug [SPR 68844]*/

    pSmObjHdr->curNumMsgQ = htonl (ntohl (pSmObjHdr->curNumMsgQ) + 1);

    CACHE_PIPE_FLUSH ();                        /* CACHE FLUSH   [SPR 68334] */
    temp = pSmObjHdr->curNumMsgQ;               /* BRIDGE FLUSH  [SPR 68334] */

    return ((MSG_Q_ID) (SM_OBJ_ADRS_TO_ID (smMsgQId)));
    }