Exemple #1
0
STATUS
pciIntDisconnect
    (
    VOIDFUNCPTR *vector,        /* interrupt vector to attach to     */
    VOIDFUNCPTR routine         /* routine to be called              */
    )
{
    int irq = IVEC_TO_INUM ((int)vector) - INT_NUM_IRQ0;
    PCI_INT_RTN *pRtn;
    int oldLevel;

    for (pRtn = (PCI_INT_RTN *)DLL_FIRST (&pciIntList[irq]); pRtn != NULL;
         pRtn = (PCI_INT_RTN *)DLL_NEXT (&pRtn->node)) {
        if (pRtn->routine == routine) {
            oldLevel = intLock ();                      /* LOCK INTERRUPT */
            dllRemove (&pciIntList[irq], &pRtn->node);
            intUnlock (oldLevel);                       /* UNLOCK INTERRUPT */

            free ((char *)pRtn);
            return (OK);
        }
    }

    return (ERROR);
}
Exemple #2
0
void qPriDeltaPut
    (
    Q_PRI_HEAD  *pQPriHead,
    Q_PRI_NODE  *pQPriNode,
    ULONG       key
    )
    {
    FAST Q_PRI_NODE *pQNode = (Q_PRI_NODE *) DLL_FIRST (pQPriHead);

    pQPriNode->key = key - vxTicks;	/* relative queue keeps delta time */

    while (pQNode != NULL)		/* empty list? */
        {
	if (pQPriNode->key < pQNode->key)
	    {
	    /* We've reached the place in the delta queue to insert this task */

	    dllInsert (pQPriHead, DLL_PREVIOUS (&pQNode->node),
		       &pQPriNode->node);

	    /* Now decrement the delta key of the guy behind us. */

	    pQNode->key -= pQPriNode->key;
	    return;				/* we're done */
	    }

	pQPriNode->key -= pQNode->key;
	pQNode = (Q_PRI_NODE *) DLL_NEXT (&pQNode->node);
	}

    /* if we fall through, add to end of delta q */

    dllInsert (pQPriHead, (DL_NODE *) DLL_LAST (pQPriHead), &pQPriNode->node);
    }
/*lint --e{527, 578, 529, 533 } */
LOCAL void windCalibrateTickQ (void)
{
    Q_PRI_NODE *node;
    UINT64 delta = vxAbsTicks;
	/*lint -save -e530*/

    for (node = (Q_PRI_NODE *)DLL_FIRST ((void*)(&tickQHead));
         node != NULL;
         node = (Q_PRI_NODE *)DLL_NEXT(&node->node))
        {/*lint -save -e78*/	
        WIND_TCB *tcb = (WIND_TCB *) ((int)node - OFFSET (WIND_TCB, tickNode));
	/*lint -restore +e78*/	
	/*lint -restore +e530*/

        /* perform tick queue finish time recalibration for tasks only */

	if  (tcb->objCore.pObjClass == taskClassId)
	    {
	    /*
	     * NOTE:  use of TASK_CPUTIME_XXX is temporary.  A new field will
	     * be added to the TCB explicitly for this purpose in the future.
	     */
	    /*lint -save -e409*/
	    TASK_CPUTIME_INFO_SET (tcb, 0,
				   (TASK_CPUTIME_INFO_GET (tcb, 0) - delta));
            }
        }
    }
Exemple #4
0
VOID
pciInt (int irq)
{
    PCI_INT_RTN *pRtn;

    for (pRtn = (PCI_INT_RTN *)DLL_FIRST (&pciIntList[irq]); pRtn != NULL;
         pRtn = (PCI_INT_RTN *)DLL_NEXT (&pRtn->node)) {
        (* pRtn->routine) (pRtn->parameter);
    }
}
Exemple #5
0
void iosDevShow (void)
    {
    FAST DEV_HDR *pDevHdr;

    printf ("%3s %-20s\n", "drv", "name");

    for (pDevHdr = (DEV_HDR *) DLL_FIRST (&iosDvList); pDevHdr != NULL;
				pDevHdr = (DEV_HDR *) DLL_NEXT (&pDevHdr->node))
	printf ("%3d %-20s\n", pDevHdr->drvNum, pDevHdr->name);
    }
Exemple #6
0
void qPriDeltaAdvance
    (
    Q_PRI_HEAD *pQPriHead
    )
    {
    FAST Q_PRI_NODE *pQPriNode = (Q_PRI_NODE *) DLL_FIRST (pQPriHead);

    if (pQPriNode != NULL)
	pQPriNode->key --;
    }
void qPriListCalibrate(Q_PRI_HEAD *pQHead, ULONG keyDelta)
{
    FAST Q_PRI_NODE *pQPriNode;

    for (pQPriNode = (Q_PRI_NODE *) DLL_FIRST (pQHead);
		pQPriNode != NULL;
		pQPriNode = (Q_PRI_NODE *) DLL_NEXT (&pQPriNode->node))
	{
        pQPriNode->key += keyDelta;			/* offset key */
	}
}
/* TODO support for it */
Q_PRI_NODE* qPriListEach(Q_PRI_HEAD* pQPriHead, FUNCTION routine, int arg)
{
	FAST Q_PRI_NODE* pQNode = (Q_PRI_NODE*)DLL_FIRST(pQPriHead);

	while((NULL != pQNode) && ((*routine)(pQNode, arg)))
	{
		pQNode = (Q_PRI_NODE*)DLL_NEXT(&pQNode->node);
	}

	return pQNode;
}
Exemple #9
0
Q_PRI_NODE *qPriListGetExpired
    (
    Q_PRI_HEAD *pQPriHead
    )
    {
    FAST Q_PRI_NODE *pQPriNode = (Q_PRI_NODE *) DLL_FIRST (pQPriHead);

    if ((pQPriNode != NULL) && (pQPriNode->key <= vxTicks))
	return ((Q_PRI_NODE *) dllGet (pQPriHead));
    else
	return (NULL);
    }
Q_PRI_NODE *qPriListGetExpired(Q_PRI_HEAD* pQPriHead)
{
	FAST Q_PRI_NODE* pQNode = (Q_PRI_NODE*)DLL_FIRST(pQPriHead);

	if((NULL != pQNode) && (pQNode->key <= kernelTicks))
	{
		return ((Q_PRI_NODE*)dllGet(pQPriHead));
	}
	else
	{
		return NULL;
	}
}
Exemple #11
0
DL_NODE *dllEach
    (
    DL_LIST     *pList,         /* linked list of nodes to call routine for */
    FUNCPTR     routine,        /* the routine to call for each list node */
    int         routineArg      /* arbitrary user-supplied argument */
    )
    {
    FAST DL_NODE *pNode = DLL_FIRST (pList);

    while ((pNode != NULL) && ((* routine) (pNode, routineArg)))
	pNode = DLL_NEXT (pNode);

    return (pNode);			/* return node we ended with */
    }
Exemple #12
0
Q_PRI_NODE *qPriDeltaEach
    (
    Q_PRI_HEAD  *pQHead,        /* queue head of queue to call routine for */
    FUNCPTR     routine,        /* the routine to call for each table entry */
    int         routineArg      /* arbitrary user-supplied argument */
    )
    {
    FAST Q_PRI_NODE *pQNode = (Q_PRI_NODE *) DLL_FIRST (pQHead);

    while ((pQNode != NULL) && ((* routine) (pQNode, routineArg)))
	pQNode = (Q_PRI_NODE *) DLL_NEXT (&pQNode->node);

    return (pQNode);			/* return node we ended with */
    }
Exemple #13
0
void qPriListCalibrate
    (
    Q_PRI_HEAD *pQHead,         /* queue head of queue to calibrate nodes for */
    ULONG       keyDelta        /* offset to add to each node's key */
    )
    {
    FAST Q_PRI_NODE *pQPriNode;

    for (pQPriNode = (Q_PRI_NODE *) DLL_FIRST (pQHead);
         pQPriNode != NULL;
	 pQPriNode = (Q_PRI_NODE *) DLL_NEXT (&pQPriNode->node))
	{
        pQPriNode->key += keyDelta;			/* offset key */
	}
    }
Exemple #14
0
int dllCount
    (
    DL_LIST *pList      /* pointer to list descriptor */
    )
    {
    FAST DL_NODE *pNode = DLL_FIRST (pList);
    FAST int count = 0;

    while (pNode != NULL)
	{
	count++;
	pNode = DLL_NEXT (pNode);
	}

    return (count);
    }
Exemple #15
0
Q_PRI_NODE *qPriDeltaGetExpired
    (
    Q_PRI_HEAD *pQPriHead
    )
    {
    FAST Q_PRI_NODE *pQPriNode = (Q_PRI_NODE *) DLL_FIRST (pQPriHead);

    if (pQPriNode != NULL)
	{
	if (pQPriNode->key != 0)
	    pQPriNode = NULL;
	else
	    qPriDeltaRemove (pQPriHead, pQPriNode);	/* get off delay list */
	}

    return (pQPriNode);
    }
void qPriListPut(Q_PRI_HEAD* pQPriHead, Q_PRI_NODE* pQPriNode, ULONG key)
{
	FAST Q_PRI_NODE* pQNode = (Q_PRI_NODE*)DLL_FIRST(pQPriHead);

	pQPriNode->key = key;

	while(NULL != pQNode)
	{
		/*	HEAD/number small ----<<<<<----TAIL/number big
			The smaller number is, the higher pri is.      */
		if(key < pQNode->key)
		{
			dllInsert(pQPriHead, DLL_PREVIOUS(&pQNode->node), &pQPriNode->node);
			return;
		}
		pQNode = (Q_PRI_NODE*)DLL_NEXT(&pQNode->node);
	}

	/* add at last */
	dllInsert(pQPriHead, DLL_LAST(pQPriHead), &pQPriNode->node);
}
Exemple #17
0
int qPriDeltaInfo
    (
    Q_PRI_HEAD *pQPriHead,      /* priority queue to gather list for */
    FAST int nodeArray[],       /* array of node pointers to be filled in */
    FAST int maxNodes           /* max node pointers nodeArray can accomodate */
    )
    {
    FAST Q_PRI_NODE *pQNode = (Q_PRI_NODE *) DLL_FIRST (pQPriHead);
    FAST int *pElement  = nodeArray;

    if (nodeArray == NULL)		/* NULL node array means return count */
	return (dllCount (pQPriHead));

    while ((pQNode != NULL) && (--maxNodes >= 0))
	{
	*(pElement++) = (int)pQNode;			/* fill in table */
	pQNode = (Q_PRI_NODE *) DLL_NEXT (&pQNode->node);	/* next node */
	}

    return (pElement - nodeArray);	/* return count of active tasks */
    }
Exemple #18
0
int qFifoInfo
    (
    Q_FIFO_HEAD *pQFifoHead,    /* FIFO queue to gather list for */
    FAST int nodeArray[],       /* array of node pointers to be filled in */
    FAST int maxNodes           /* max node pointers nodeArray can accomodate */
    )
    {
    FAST DL_NODE *pNode = DLL_FIRST (pQFifoHead);
    FAST int *pElement  = nodeArray;

    if (nodeArray == NULL)		/* NULL node array means return count */
	return (dllCount (pQFifoHead));

    while ((pNode != NULL) && (--maxNodes >= 0))
	{
	*(pElement++) = (int)pNode;	/* fill in table */
	pNode = DLL_NEXT (pNode);	/* next node */
	}

    return (pElement - nodeArray);	/* return count of active tasks */
    }
Exemple #19
0
void qPriListPut
    (
    Q_PRI_HEAD  *pQPriHead,
    Q_PRI_NODE  *pQPriNode,
    ULONG        key
    )
    {
    FAST Q_PRI_NODE *pQNode = (Q_PRI_NODE *) DLL_FIRST (pQPriHead);

    pQPriNode->key = key;

    while (pQNode != NULL)
        {
	if (key < pQNode->key)		/* it will be last of same priority */
	    {
	    dllInsert (pQPriHead, DLL_PREVIOUS (&pQNode->node),
		       &pQPriNode->node);
	    return;
	    }
	pQNode = (Q_PRI_NODE *) DLL_NEXT (&pQNode->node);
	}

    dllInsert (pQPriHead, (DL_NODE *) DLL_LAST (pQPriHead), &pQPriNode->node);
    }
void* memPartAllignedAlloc(FAST PART_ID partId, unsigned nBytes, unsigned align)
{
	FAST unsigned nWords;
	FAST unsigned nWordsExtra;
	FAST DL_NODE* pNode;
	FAST BLOCK_HDR* pHdr;
	BLOCK_HDR* pNewHdr;
	BLOCK_HDR* origpHdr;

	if(!(IS_CLASS(partId, memPartClassId)))	/* only memPartClass can call this function */
	{
		return (NULL);
	}

	nWords = (MEM_ROUND_UP(nBytes)+sizeof(BLOCK_HDR)) >>1;

	if((nWords<<1) < nBytes)
	{
		/* TODO suspend the task */
		return (NULL);
	}

	if(nWords < partId->minBlockWords)
	{
		nWords = partId->minBlockWords;
	}

	/* TODO task the semaphore hear */
	semTake(partId->semPartId, WAIT_FOREVER);
	
	pNode = DLL_FIRST(&partId->freeList);
	nWordsExtra = nWords + align/2; /* why? */

	for(;;)
	{
		while(NULL != pNode)
		{
			if((NODE_TO_HDR(pNode)->nWords > nWordsExtra) ||
				((NODE_TO_HDR(pNode)->nWords == nWords) && 
				(ALIGNED(HDR_TO_BLOCK(NODE_TO_HDR(pNode)), align))))
			{
				break;
			}

			pNode = DLL_NEXT(pNode);
		}

		if(NULL == pNode)
		{
			/*TODO give the semaphore */
			semGive(partId->semPartId);
			return NULL;
		}

		pHdr = NODE_TO_HDR(pNode);
		origpHdr = pHdr;

		pNewHdr = memAlignedBlockSplit(partId, pHdr, nWords, partId->minBlockWords, align);
		if(NULL != pNewHdr)
		{
			pHdr = pNewHdr;
			break;
		}

		pNode = DLL_NEXT(pNode);
	}

	pHdr->free = FALSE;
	partId->allBlocksAlloc++;
	partId->allWordsAlloc += pHdr->nWords;
	partId->curBlocksAlloc++;
	partId->curWordsAlloc += pHdr->nWords;

	/*TODO give the  semaphore hear */
	semGive(partId->semPartId);
	return (HDR_TO_BLOCK(pHdr));
	
}
Exemple #21
0
static void * worker_thread_handler(void * x) {
    WorkerThread * wt = (WorkerThread *)x;

    for (;;) {
        AsyncReqInfo * req = wt->req;

        assert(req != NULL);
        req->error = 0;
        switch(req->type) {
        case AsyncReqTimer:
#if defined(_WIN32) && !defined(__CYGWIN__)
            Sleep(EVENTS_TIMER_RESOLUTION);
            events_timer_ms = GetTickCount();
#else
            {
                struct timespec timenow;
                usleep(EVENTS_TIMER_RESOLUTION * 1000);
                if (clock_gettime(CLOCK_REALTIME, &timenow) == 0) {
                    events_timer_ms = (uint32_t)(timenow.tv_nsec / 1000000 + timenow.tv_sec * 1000);
                }
            }
#endif
            break;

        case AsyncReqRead:              /* File read */
            req->u.fio.rval = read(req->u.fio.fd, req->u.fio.bufp, req->u.fio.bufsz);
            if (req->u.fio.rval == -1) {
                req->error = errno;
                assert(req->error);
            }
            break;

        case AsyncReqWrite:             /* File write */
            req->u.fio.rval = write(req->u.fio.fd, req->u.fio.bufp, req->u.fio.bufsz);
            if (req->u.fio.rval == -1) {
                req->error = errno;
                assert(req->error);
            }
            break;

        case AsyncReqSeekRead:          /* File read at offset */
            req->u.fio.rval = pread(req->u.fio.fd, req->u.fio.bufp, req->u.fio.bufsz, (off_t)req->u.fio.offset);
            if (req->u.fio.rval == -1) {
                req->error = errno;
                assert(req->error);
            }
            break;

        case AsyncReqSeekWrite:         /* File write at offset */
            req->u.fio.rval = pwrite(req->u.fio.fd, req->u.fio.bufp, req->u.fio.bufsz, (off_t)req->u.fio.offset);
            if (req->u.fio.rval == -1) {
                req->error = errno;
                assert(req->error);
            }
            break;

        case AsyncReqRecv:              /* Socket recv */
            req->u.sio.rval = recv(req->u.sio.sock, req->u.sio.bufp, req->u.sio.bufsz, req->u.sio.flags);
            if (req->u.sio.rval == -1) {
                req->error = errno;
                assert(req->error);
            }
            break;

        case AsyncReqSend:              /* Socket send */
            req->u.sio.rval = send(req->u.sio.sock, req->u.sio.bufp, req->u.sio.bufsz, req->u.sio.flags);
            if (req->u.sio.rval == -1) {
                req->error = errno;
                assert(req->error);
            }
            break;

        case AsyncReqRecvFrom:          /* Socket recvfrom */
            req->u.sio.rval = recvfrom(req->u.sio.sock, req->u.sio.bufp, req->u.sio.bufsz, req->u.sio.flags, req->u.sio.addr, &req->u.sio.addrlen);
            if (req->u.sio.rval == -1) {
                req->error = errno;
                trace(LOG_ASYNCREQ, "AsyncReqRecvFrom: req %p, type %d, error %d", req, req->type, req->error);
                assert(req->error);
            }
            break;

        case AsyncReqSendTo:            /* Socket sendto */
            req->u.sio.rval = sendto(req->u.sio.sock, req->u.sio.bufp, req->u.sio.bufsz, req->u.sio.flags, req->u.sio.addr, req->u.sio.addrlen);
            if (req->u.sio.rval == -1) {
                req->error = errno;
                assert(req->error);
            }
            break;

        case AsyncReqAccept:            /* Accept socket connections */
            req->u.acc.rval = accept(req->u.acc.sock, req->u.acc.addr, req->u.acc.addr ? &req->u.acc.addrlen : NULL);
            if (req->u.acc.rval == -1) {
                req->error = errno;
                trace(LOG_ASYNCREQ, "AsyncReqAccept: req %p, type %d, error %d", req, req->type, req->error);
                assert(req->error);
            }
            break;

        case AsyncReqConnect:           /* Connect to socket */
            req->u.con.rval = connect(req->u.con.sock, req->u.con.addr, req->u.con.addrlen);
            if (req->u.con.rval == -1) {
                req->error = errno;
                trace(LOG_ASYNCREQ, "AsyncReqConnect: req %p, type %d, error %d", req, req->type, req->error);
                assert(req->error);
            }
            break;

/* Platform dependant IO methods */
#if defined(_WIN32) || defined(__CYGWIN__)
        case AsyncReqConnectPipe:
            req->u.cnp.rval = ConnectNamedPipe(req->u.cnp.pipe, NULL);
            if (!req->u.cnp.rval) {
                req->error = set_win32_errno(GetLastError());
                assert(req->error);
            }
            break;
#elif defined(_WRS_KERNEL)
#else
        case AsyncReqWaitpid:           /* Wait for process change */
            req->u.wpid.rval = waitpid(req->u.wpid.pid, &req->u.wpid.status, req->u.wpid.options);
            if (req->u.wpid.rval == -1) {
                req->error = errno;
                assert(req->error);
            }
            break;
#endif

        case AsyncReqSelect:
            {
                struct timeval tv;
                tv.tv_sec = (long)req->u.select.timeout.tv_sec;
                tv.tv_usec = req->u.select.timeout.tv_nsec / 1000;
                req->u.select.rval = select(req->u.select.nfds, &req->u.select.readfds,
                            &req->u.select.writefds, &req->u.select.errorfds, &tv);
                if (req->u.select.rval == -1) {
                    req->error = errno;
                    assert(req->error);
                }
            }
            break;

        case AsyncReqClose:
            req->u.fio.rval = close(req->u.fio.fd);
            if (req->u.fio.rval == -1) {
                req->error = errno;
                assert(req->error);
            }
            break;

        case AsyncReqCloseDir:
            req->u.dio.rval = closedir((DIR *)req->u.dio.dir);
            if (req->u.dio.rval == -1) {
                req->error = errno;
                assert(req->error);
            }
            break;

        case AsyncReqOpen:
            req->u.fio.rval = open(req->u.fio.file_name, req->u.fio.flags, req->u.fio.permission);
            if (req->u.fio.rval == -1) {
                req->error = errno;
                assert(req->error);
            }
            break;

        case AsyncReqOpenDir:
            req->u.dio.dir = opendir(req->u.dio.path);
            if (req->u.dio.dir == NULL) {
                req->error = errno;
                assert(req->error);
            }
            break;

        case AsyncReqFstat:
            memset(&req->u.fio.statbuf, 0, sizeof(req->u.fio.statbuf));
            req->u.fio.rval = fstat(req->u.fio.fd, &req->u.fio.statbuf);
            if (req->u.fio.rval == -1) {
                req->error = errno;
                assert(req->error);
            }
#if defined(_WIN32) || defined(__CYGWIN__)
            req->u.fio.win32_attrs = req->error || !req->u.fio.file_name ?
                INVALID_FILE_ATTRIBUTES : GetFileAttributes(req->u.fio.file_name);
#endif
            break;

        case AsyncReqStat:
            memset(&req->u.fio.statbuf, 0, sizeof(req->u.fio.statbuf));
            req->u.fio.rval = stat(req->u.fio.file_name, &req->u.fio.statbuf);
            if (req->u.fio.rval == -1) {
                req->error = errno;
                assert(req->error);
            }
#if defined(_WIN32) || defined(__CYGWIN__)
            req->u.fio.win32_attrs = req->error ?
                INVALID_FILE_ATTRIBUTES : GetFileAttributes(req->u.fio.file_name);
#endif
            break;

        case AsyncReqLstat:
            memset(&req->u.fio.statbuf, 0, sizeof(req->u.fio.statbuf));
            req->u.fio.rval = lstat(req->u.fio.file_name, &req->u.fio.statbuf);
            if (req->u.fio.rval == -1) {
                req->error = errno;
                assert(req->error);
            }
#if defined(_WIN32) || defined(__CYGWIN__)
            req->u.fio.win32_attrs = req->error ?
                INVALID_FILE_ATTRIBUTES : GetFileAttributes(req->u.fio.file_name);
#endif
            break;

        case AsyncReqSetStat:
            {
                int err = 0;
                if (req->u.fio.set_stat_flags & AsyncReqSetSize) {
                    if (truncate(req->u.fio.file_name, (off_t)req->u.fio.statbuf.st_size) < 0) err = errno;
                }
                if (req->u.fio.set_stat_flags & AsyncReqSetPermissions) {
                    if (chmod(req->u.fio.file_name, req->u.fio.statbuf.st_mode) < 0) err = errno;
                }
#if defined(_WIN32) || defined(__CYGWIN__) || defined(_WRS_KERNEL)
#  if defined(_WIN32) || defined(__CYGWIN__)
                if (req->u.fio.win32_attrs != INVALID_FILE_ATTRIBUTES) {
                    if (SetFileAttributes(req->u.fio.file_name, req->u.fio.win32_attrs) == 0)
                        err = set_win32_errno(GetLastError());
                }
#  endif
#else
                if (req->u.fio.set_stat_flags & AsyncReqSetUidGid) {
                    if (chown(req->u.fio.file_name, req->u.fio.statbuf.st_uid, req->u.fio.statbuf.st_gid) < 0) err = errno;
                }
#endif
                if (req->u.fio.set_stat_flags & AsyncReqSetAcModTime) {
                    struct utimbuf buf;
                    buf.actime = req->u.fio.statbuf.st_atime;
                    buf.modtime = req->u.fio.statbuf.st_mtime;
                    if (utime(req->u.fio.file_name, &buf) < 0) err = errno;
                }
                req->error = err;
            }
            break;

        case AsyncReqFSetStat:
            {
                int err = 0;
                if (req->u.fio.set_stat_flags & AsyncReqSetSize) {
                    if (ftruncate(req->u.fio.fd, (off_t)req->u.fio.statbuf.st_size) < 0) err = errno;
                }
#if defined(_WIN32) || defined(__CYGWIN__) || defined(_WRS_KERNEL)
                if (req->u.fio.set_stat_flags & AsyncReqSetPermissions) {
                    if (chmod(req->u.fio.file_name, req->u.fio.statbuf.st_mode) < 0) err = errno;
                }
#  if defined(_WIN32) || defined(__CYGWIN__)
                if (req->u.fio.win32_attrs != INVALID_FILE_ATTRIBUTES) {
                    if (SetFileAttributes(req->u.fio.file_name, req->u.fio.win32_attrs) == 0)
                        err = set_win32_errno(GetLastError());
                }
#  endif
#else
                if (req->u.fio.set_stat_flags & AsyncReqSetUidGid) {
                    if (fchown(req->u.fio.fd, req->u.fio.statbuf.st_uid, req->u.fio.statbuf.st_gid) < 0) err = errno;
                }
                if (req->u.fio.set_stat_flags & AsyncReqSetPermissions) {
                    if (fchmod(req->u.fio.fd, req->u.fio.statbuf.st_mode) < 0) err = errno;
                }
#endif
                if (req->u.fio.set_stat_flags & AsyncReqSetAcModTime) {
                    struct utimbuf buf;
                    buf.actime = req->u.fio.statbuf.st_atime;
                    buf.modtime = req->u.fio.statbuf.st_mtime;
#if defined(_WIN32) && !defined(__MINGW32__)
                    if (futime(req->u.fio.fd, &buf) < 0) err = errno;
#else
                    if (utime(req->u.fio.file_name, &buf) < 0) err = errno;
#endif
                }
                req->error = err;
            }
            break;

        case AsyncReqRemove:
            req->u.fio.rval = remove(req->u.fio.file_name);
            if (req->u.fio.rval == -1) {
                req->error = errno;
                assert(req->error);
            }
            break;

        case AsyncReqReadDir:
            {
                int cnt = 0;
                while (cnt < req->u.dio.max_files) {
                    char path[FILE_PATH_SIZE];
                    struct DirFileNode * file = req->u.dio.files + cnt;
                    struct dirent * e;
                    struct stat st;
                    errno = 0;
                    e = readdir((DIR *)req->u.dio.dir);
                    if (e == NULL) {
                        req->error = errno;
                        if (req->error == 0) req->u.dio.eof = 1;
                        break;
                    }
                    if (strcmp(e->d_name, ".") == 0) continue;
                    if (strcmp(e->d_name, "..") == 0) continue;
                    file->path = loc_strdup(e->d_name);
                    memset(&st, 0, sizeof(st));
                    snprintf(path, sizeof(path), "%s/%s", req->u.dio.path, e->d_name);
                    if (stat(path, &st) == 0) {
#if defined(_WIN32) || defined(__CYGWIN__)
                        file->win32_attrs =  GetFileAttributes(path);
#endif
                        file->statbuf = (struct stat *)loc_alloc(sizeof(struct stat));
                        memcpy(file->statbuf, &st, sizeof(struct stat));
                    }
                    cnt++;
                }
            }
            break;

        case AsyncReqRoots:
            {
                struct stat st;
                struct RootDevNode * newDevNode = NULL;

#if defined(_WIN32) || defined(__CYGWIN__)
                {
                    struct RootDevNode * curDevNode = NULL;
                    int disk = 0;
                    DWORD disks = GetLogicalDrives();
                    for (disk = 0; disk <= 30; disk++) {
                        if (disks & (1 << disk)) {
                            char path[32];
                            newDevNode = (struct RootDevNode *)loc_alloc_zero(sizeof(struct RootDevNode));
                            if (curDevNode == NULL) req->u.root.lst = newDevNode;
                            else curDevNode->next = newDevNode;
                            curDevNode = newDevNode;
                            snprintf(path, sizeof(path), "%c:\\", 'A' + disk);
                            newDevNode->devname = loc_strdup(path);
                            if (disk >= 2) {
                                ULARGE_INTEGER total_number_of_bytes;
                                BOOL has_size = GetDiskFreeSpaceExA(path, NULL, &total_number_of_bytes, NULL);
                                memset(&st, 0, sizeof(st));
#if defined(__CYGWIN__)
                                snprintf(path, sizeof(path), "/cygdrive/%c", 'a' + disk);
#endif
                                if (has_size && stat(path, &st) == 0) {
                                    newDevNode->win32_attrs =  GetFileAttributes(path);
                                    newDevNode->statbuf = (struct stat *)loc_alloc_zero(sizeof(struct stat));
                                    memcpy(newDevNode->statbuf, &st, sizeof(struct stat));
                                }
                            }
                        }
                    }
                }
#elif defined(_WRS_KERNEL)
                {
                    struct RootDevNode * curDevNode = NULL;
                    extern DL_LIST iosDvList;
                    DEV_HDR * dev;
                    for (dev = (DEV_HDR *)DLL_FIRST(&iosDvList); dev != NULL; dev = (DEV_HDR *)DLL_NEXT(&dev->node)) {
                        char path[FILE_PATH_SIZE];
                        if (strcmp(dev->name, "host:") == 0) {
                            /* Windows host is special case */
                            int d;
                            for (d = 'a'; d < 'z'; d++) {
                                snprintf(path, sizeof(path), "%s%c:/", dev->name, d);
                                if (stat(path, &st) == 0 && S_ISDIR(st.st_mode)) {
                                    newDevNode = (struct RootDevNode *)loc_alloc_zero(sizeof(struct RootDevNode));
                                    if (curDevNode == NULL) req->u.root.lst = newDevNode;
                                    else curDevNode->next = newDevNode;
                                    curDevNode = newDevNode;

                                    newDevNode->devname = loc_strdup(path);
                                    newDevNode->statbuf = (struct stat *)loc_alloc_zero(sizeof(struct stat));
                                    memcpy(newDevNode->statbuf, &st, sizeof(struct stat));
                                }
                            }
                        }
                        snprintf(path, sizeof(path), "%s/", dev->name);
                        if (stat(path, &st) == 0 && S_ISDIR(st.st_mode)) {
                            newDevNode = (struct RootDevNode *)loc_alloc_zero(sizeof(struct RootDevNode));
                            if (curDevNode == NULL) req->u.root.lst = newDevNode;
                            else curDevNode->next = newDevNode;
                            curDevNode = newDevNode;

                            newDevNode->devname = loc_strdup(path);
                            newDevNode->statbuf = (struct stat *)loc_alloc_zero(sizeof(struct stat));
                            memcpy(newDevNode->statbuf, &st, sizeof(struct stat));
                        }
                    }
                }
#else
                req->u.root.lst = newDevNode = (struct RootDevNode *)loc_alloc_zero(sizeof(struct RootDevNode));
                newDevNode->devname = loc_strdup("/");
                if (stat("/", &st) == 0) {
                    newDevNode->statbuf = (struct stat *)loc_alloc_zero(sizeof(struct stat));
                    memcpy(newDevNode->statbuf, &st, sizeof(struct stat));
                }
#endif
            }
            break;

        case AsyncReqUser:              /* User defined request */
            req->u.user.rval = req->u.user.func(req->u.user.data);
            if (req->u.user.rval == -1) {
                req->error = errno;
                assert(req->error);
            }
            break;

        default:
            req->error = ENOSYS;
            break;
        }
        if (req->type == AsyncReqTimer) {
            if (async_shutdown.state == SHUTDOWN_STATE_PENDING) break;
            continue;
        }
        trace(LOG_ASYNCREQ, "async_req_complete: req %p, type %d, error %d", req, req->type, req->error);
        check_error(pthread_mutex_lock(&wtlock));
        /* Post event inside lock to make sure a new worker thread is not created unnecessarily */
        post_event(req->done, req);
        wt->req = NULL;
        if (wtlist_size >= MAX_WORKER_THREADS || async_shutdown.state == SHUTDOWN_STATE_PENDING) {
            check_error(pthread_mutex_unlock(&wtlock));
            break;
        }
        list_add_last(&wt->wtlink, &wtlist);
        wtlist_size++;
        for (;;) {
            check_error(pthread_cond_wait(&wt->cond, &wtlock));
            if (wt->req != NULL) break;
        }
        check_error(pthread_mutex_unlock(&wtlock));
        if (wt->req == &shutdown_req) break;
    }
    post_event(worker_thread_exit, wt);
    return NULL;
}
Exemple #22
0
void *memPartAlignedAlloc 
    (
    FAST PART_ID	partId,		/* memory partition to allocate from */
    unsigned		nBytes,		/* number of bytes to allocate */
    unsigned		alignment	/* boundary to align to */
    )
    {
    FAST unsigned	nWords;
    FAST unsigned	nWordsExtra;
    FAST DL_NODE *	pNode;
    FAST BLOCK_HDR *	pHdr;
    BLOCK_HDR *		pNewHdr;
    BLOCK_HDR 		origpHdr;

    if (OBJ_VERIFY (partId, memPartClassId) != OK)
	return (NULL);

    /* get actual size to allocate; add overhead, check for minimum */

    nWords = (MEM_ROUND_UP (nBytes) + sizeof (BLOCK_HDR)) >> 1;

    /* check if we have an overflow. if so, set errno and return NULL */

    if ((nWords << 1) < nBytes)
	{
	if (memPartAllocErrorRtn != NULL)
	    (* memPartAllocErrorRtn) (partId, nBytes);

	errnoSet (S_memLib_NOT_ENOUGH_MEMORY);

	if (partId->options & MEM_ALLOC_ERROR_SUSPEND_FLAG)
	    {
	    if ((taskIdCurrent->options & VX_UNBREAKABLE) == 0)
		taskSuspend (0);			/* suspend ourselves */
	    }

	return (NULL);
	}

    if (nWords < partId->minBlockWords)
	nWords = partId->minBlockWords;

    /* get exclusive access to the partition */

    semTake (&partId->sem, WAIT_FOREVER);

    /* first fit */

    pNode = DLL_FIRST (&partId->freeList);

    /* We need a free block with extra room to do the alignment.  
     * Worst case we'll need alignment extra bytes.
     */

    nWordsExtra = nWords + alignment / 2;

    FOREVER
	{
	while (pNode != NULL)
	    {
	    /* fits if:
	     *	- blocksize > requested size + extra room for alignment or,
	     *	- block is already aligned and exactly the right size
	     */
	    if ((NODE_TO_HDR (pNode)->nWords > nWordsExtra) ||
		((NODE_TO_HDR (pNode)->nWords == nWords) &&
		 (ALIGNED (HDR_TO_BLOCK(NODE_TO_HDR(pNode)), alignment))))
		  break;
	    pNode = DLL_NEXT (pNode);
	    }
	
	if (pNode == NULL)
	    {
	    semGive (&partId->sem);

	    if (memPartAllocErrorRtn != NULL)
		(* memPartAllocErrorRtn) (partId, nBytes);

	    errnoSet (S_memLib_NOT_ENOUGH_MEMORY);

	    if (partId->options & MEM_ALLOC_ERROR_SUSPEND_FLAG)
		{
		if ((taskIdCurrent->options & VX_UNBREAKABLE) == 0)
		    taskSuspend (0);			/* suspend ourselves */
		}

	    return (NULL);
	    }

	pHdr = NODE_TO_HDR (pNode);
	origpHdr = *pHdr;


	/* now we split off from this block, the amount required by the user;
	 * note that the piece we are giving the user is at the end of the
	 * block so that the remaining piece is still the piece that is
	 * linked in the free list;  if memAlignedBlockSplit returned NULL,
	 * it couldn't split the block because the split would leave the
	 * first block too small to be hung on the free list, so we continue
	 * trying blocks.
	 */

	pNewHdr = 
	    memAlignedBlockSplit (partId, pHdr, nWords, partId->minBlockWords,
				  alignment);

	if (pNewHdr != NULL)
	    {
	    pHdr = pNewHdr;			/* give split off block */
	    break;
	    }
	
	pNode = DLL_NEXT (pNode);
	}

    /* mark the block we're giving as not free */

    pHdr->free = FALSE;

#ifdef WV_INSTRUMENTATION
    EVT_OBJ_4 (OBJ, partId, memPartClassId, EVENT_MEMALLOC, partId, HDR_TO_BLOCK (pHdr), 2 * (pHdr->nWords), nBytes);
#endif

    /* update allocation statistics */

    partId->curBlocksAllocated++;
    partId->cumBlocksAllocated++;
    partId->curWordsAllocated += pHdr->nWords;
    partId->cumWordsAllocated += pHdr->nWords;

    semGive (&partId->sem);

    return ((void *) HDR_TO_BLOCK (pHdr));
    }