예제 #1
0
파일: vfs_task.c 프로젝트: AndrewD/prex
/*
 * Convert task ID to a task structure.
 * Returns locked task. Caller must unlock it after using it.
 */
struct task *
task_lookup(task_t task)
{
	list_t head, n;
	struct task *t;

	if (task == TASK_NULL)
		return NULL;

	TASK_LOCK();
	head = &task_table[TASKHASH(task)];
	for (n = list_first(head); n != head; n = list_next(n)) {
		t = list_entry(n, struct task, link);
		ASSERT(t->task);
		if (t->task == task) {
			TASK_UNLOCK();
			mutex_lock(&t->lock);
			return t;
		}
	}
	TASK_UNLOCK();

	/* Not found */
	return NULL;
}
예제 #2
0
static STATUS msgQDestroy(MSG_Q_ID msgQId, BOOL dealloc)
{
	Q_JOB_NODE* pNode;
	FAST int timeout;
	FAST int nMsgs;
	
	/* TODO isr not allowed */

	TASK_SAFE();
	TASK_LOCK();

	if(!IS_CLASS(msgQId, msgQClassId))
	{
		TASK_UNLOCK();
		TASK_UNSAFE();
		return (ERROR);
	}

	objCoreTerminate(&msgQId->objCore);

	TASK_UNLOCK();

	timeout = NO_WAIT;
	nMsgs = 0;

	while(nMsgs < msgQId->maxMsgs)
	{
		while(((pNode = qJobGet(msgQId, &msgQId->freeQ, timeout)) != NULL) &&
			(pNode != (Q_JOB_NODE*)NONE))
		{
			nMsgs++;
		}

		while(((pNode = qJobGet(msgQId, &msgQId->msgQ, timeout)) != NULL) &&
			(pNode != (Q_JOB_NODE*)NONE))
		{
			nMsgs++;
		}

		timeout = 1;
	}

	kernelState = TRUE;

	qJobTerminate(&msgQId->msgQ);
	qJobTerminate(&msgQId->freeQ);

	kernelExit();

	if(dealloc)
	{
		objFree(msgQClassId, (char*)msgQId);
	}

	TASK_UNSAFE();

	return (OK);
}
예제 #3
0
STATUS msgQEvStart
    (
    MSG_Q_ID msgQId,	/* msg Q for which to register events */
    UINT32 events,	/* 32 possible events                 */
    UINT8 options 	/* event-related msg Q options        */
    )
    {
    if (events == 0x0)
	{
	errnoSet (S_eventLib_ZERO_EVENTS);
	return (ERROR);
	}

    if (INT_RESTRICT () != OK)
	return (ERROR);    /* errno set by INT_RESTRICT() */

    TASK_LOCK (); /* to prevent msg Q from being deleted */

    if (OBJ_VERIFY(msgQId,msgQClassId) != OK)
	{
	TASK_UNLOCK ();
	return (ERROR);    /* errno is set by OBJ_VERIFY */
	}

    /* TASK_UNLOCK() will be done by eventStart() */

    return (eventStart ((OBJ_ID)msgQId, &msgQId->events, &msgQEvIsFree,
	    events, options));
    }
예제 #4
0
BOOL memPartBlockIsValid 
    (
    PART_ID partId,
    FAST BLOCK_HDR *pHdr,
    BOOL isFree                 /* expected status */
    )
    {
    BOOL valid;

    TASK_LOCK ();					/* LOCK PREEMPTION */
    semGive (&partId->sem);				/* release mutex */

    valid = MEM_ALIGNED (pHdr)				/* aligned */
            && MEM_ALIGNED (2 * pHdr->nWords)		/* size is round */
            && (pHdr->nWords <= partId->totalWords)	/* size <= total */
	    && (pHdr->free == isFree)			/* right alloc-ness */
#if (CPU_FAMILY == SH)
	    && MEM_ALIGNED(NEXT_HDR (pHdr))		/* aligned(08aug95,sa)*/
	    && MEM_ALIGNED(PREV_HDR (pHdr))		/* aligned(08aug95,sa)*/
#endif
	    && (pHdr == PREV_HDR (NEXT_HDR (pHdr)))	/* matches next block */
	    && (pHdr == NEXT_HDR (PREV_HDR (pHdr)));	/* matches prev block */

    semTake (&partId->sem, WAIT_FOREVER);		/* reacquire mutex */
    TASK_UNLOCK ();					/* UNLOCK PREEMPTION */

    return (valid);
    }
예제 #5
0
int msgQReceive(FAST MSG_Q_ID msgQId, char* buffer, UINT maxNBytes, int timeout)
{
	FAST MSG_NODE* pMsg;
	FAST int bytesReturned;

	/* TODO int restrict */

	if((int)maxNBytes < 0)
	{
		return (ERROR);
	}

	TASK_LOCK();
restart:
	if(!IS_CLASS(msgQId, msgQClassId))
	{
		TASK_UNLOCK();
		return (ERROR);
	}

	pMsg = (MSG_NODE*)qJobGet(msgQId, &msgQId->msgQ, timeout);

	if(pMsg == (MSG_NODE*)NONE)
	{
		/* timeout recalc */
		goto restart;
	}

	if(pMsg == NULL)
	{
		msgQId->recvTimeouts++;
		TASK_UNLOCK();
		return (ERROR);
	}

	bytesReturned = MIN(pMsg->msgLength, maxNBytes);
	memcpy(buffer, MSG_NODE_DATA(pMsg), bytesReturned);

	qJobPut(msgQId, &msgQId->freeQ, &pMsg->node, Q_JOB_PRI_DONT_CARE);

	TASK_UNLOCK();

	return (bytesReturned);
}
예제 #6
0
파일: vfs_task.c 프로젝트: AndrewD/prex
/*
 * Update task id of the specified task.
 */
void
task_update(struct task *t, task_t task)
{

	TASK_LOCK();
	list_remove(&t->link);
	t->task = task;
	list_insert(&task_table[TASKHASH(task)], &t->link);
	TASK_UNLOCK();
}
예제 #7
0
파일: vfs_task.c 프로젝트: AndrewD/prex
/*
 * Free needless task.
 */
void
task_free(struct task *t)
{

	TASK_LOCK();
	list_remove(&t->link);
	mutex_unlock(&t->lock);
	mutex_destroy(&t->lock);
	free(t);
	TASK_UNLOCK();
}
예제 #8
0
long comSafeDec
    (
    long *      pVar
    )
    {
    long n;
    
    TASK_LOCK ();
    n = --(*pVar);
    TASK_UNLOCK ();
    return n;
    }
예제 #9
0
long comSafeInc
    (
    long *      pVar
    )
    {
    long n;
    
    TASK_LOCK ();
    n = ++(*pVar);
    TASK_UNLOCK ();
    return n;
    }
예제 #10
0
파일: vfs_task.c 프로젝트: AndrewD/prex
/*
 * Allocate new task
 */
int
task_alloc(task_t task, struct task **pt)
{
	struct task *t;

	/* Check if specified task already exists. */
	if (task_lookup(task) != NULL)
		return EINVAL;

	if (!(t = malloc(sizeof(struct task))))
		return ENOMEM;
	memset(t, 0, sizeof(struct task));
	t->task = task;
	strcpy(t->cwd, "/");
	mutex_init(&t->lock);

	TASK_LOCK();
	list_insert(&task_table[TASKHASH(task)], &t->link);
	TASK_UNLOCK();
	*pt = t;
	return 0;
}
예제 #11
0
파일: vfs_task.c 프로젝트: AndrewD/prex
void
task_dump(void)
{
#ifdef DEBUG_VFS
	list_t head, n;
	struct task *t;
	int i;

	TASK_LOCK();
	dprintf("Dump file data\n");
	dprintf(" task     opens   cwd\n");
	dprintf(" -------- ------- ------------------------------\n");
	for (i = 0; i < TASK_MAXBUCKETS; i++) {
		head = &task_table[i];
		for (n = list_first(head); n != head; n = list_next(n)) {
			t = list_entry(n, struct task, link);
			dprintf(" %08x %7x %s\n", (int)t->task, t->nopens,
			       t->cwd);
		}
	}
	dprintf("\n");
	TASK_UNLOCK();
#endif
}
예제 #12
0
int msgQSmReceive 
    (
    SM_MSG_Q_ID    smMsgQId,       /* message queue from which to receive*/
    char *         buffer,         /* buffer to receive message */
    UINT           maxNBytes,      /* length of buffer */
    int            timeout         /* ticks to wait */
    )
    {
    SM_MSG_NODE volatile * pMsg;
    int	                   bytesReturned;
    int                    level;
    SM_MSG_Q_ID volatile   smMsgQIdv = (SM_MSG_Q_ID volatile) smMsgQId;
    int                    temp;   /* temp storage */

    /* 
     * even though maxNBytes is unsigned, check for < 0 to catch 
     * possible caller errors
     */

    if ((int) maxNBytes < 0)
	{
	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_MSGQRECEIVE, smMsgQId, buffer, maxNBytes, 
		     timeout, 0,4);

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

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

    /* block until a message is available */

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

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

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

    pMsg = (SM_MSG_NODE volatile *) smDllGet (&smMsgQId->msgQ);

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

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

    bytesReturned = min (ntohl (pMsg->msgLength), maxNBytes);

    bcopy (SM_MSG_NODE_DATA (pMsg), buffer, bytesReturned);

    /* now give back message to free queue */

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

    smDllAdd (&smMsgQId->freeQ, (SM_DL_NODE *) pMsg);

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

    /* now give free queue semaphore */

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

    TASK_UNLOCK ();

    return (bytesReturned);
    }
예제 #13
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);
    }
예제 #14
0
STATUS msgQSend(FAST MSG_Q_ID msgQId, char* buffer, FAST UINT nBytes, int timeout, int priority)
{
	FAST MSG_NODE* pMsg;

	if(!INT_CONTEX())
	{
		TASK_LOCK();
	}
	else
	{
		/* ISR not pend */
		if(0 != timeout)
		{
			return (ERROR);
		}
	}

restart:
	if(!IS_CLASS(msgQId, msgQClassId))
	{
		if(!INT_CONTEX())
		{
			TASK_UNLOCK();
		}
		return (ERROR);
	}

	if(nBytes > msgQId->maxMsgLength)
	{
		if(!INT_CONTEX())
		{
			TASK_UNLOCK();
		}
		return (ERROR);
	}

	pMsg = (MSG_NODE*)qJobGet(msgQId, &msgQId->freeQ, timeout);
	
	if(pMsg == (MSG_NODE*)NONE)
	{
		/* TODO recalc timeout and why? */
		goto restart;
	}

	if(pMsg == NULL)
	{
		msgQId->sendTimeouts++;
		if(!INT_CONTEX())
		{
			TASK_UNLOCK();
		}
		return (ERROR);
	}

	pMsg->msgLength = nBytes;
	memcpy(MSG_NODE_DATA(pMsg), buffer, (int)nBytes);

	if(OK != qJobPut(msgQId, &msgQId->msgQ, &pMsg->node, priority))
	{
		if(!INT_CONTEX())
		{
			TASK_UNLOCK();
		}
		return (ERROR);
	}

	if(!INT_CONTEX())
	{
		TASK_UNLOCK();
	}

	return (OK);
}