⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 aiosysdrv.c

📁 VXWORKS源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* aioSysDrv.c - AIO system driver *//* Copyright 1984-1994 Wind River Systems, Inc. */#include "copyright_wrs.h"/*modification history-------------------1c,01feb94,dvs	documentation changes.1b,12jan94,kdl  changed name to aioSysDrv.c; general cleanup.1a,04apr93,elh  written.*//* DESCRIPTIONThis library is the AIO system driver.  The system driver implementsasynchronous I/O with system AIO tasks performing the AIO requestsin a synchronous manner.  It is installed as the default driver for AIO.INTERNALTwo types of tasks are used to implement the system driver: the aioIoTask and the aioWaitTask.  The aioIoTask services the work queue and performs the I/O.  It gets an AIO request from the work queue, performs the I/O on behalf of the task that initiated the I/O request, and then notifies the caller of the I/O completion.  The number of aioIoTasks gets specifiedby the user in the call to aioSysInit.The aioWaitTask services the wait queue and is used for AIO requests that can not be performed immediately due to blocking I/O.  The aioWaitTask waits for data (or events) to arrive that will allow waiting AIO requests to complete successfully. Therefore, if the aioIoTask gets an AIO request that will block, the aioIoTask will not execute the I/O command but instead put the request in "wait" state, add it to the wait queue and notify the aioWaitTask that the I/Orequest is waiting on data.  Once the data arrives, the aioWaitTask moves the request back to the work queue and notifies the aioIoTask the request can now be completed.This library uses pipeDrv to communicate between the aioIoTasks and aioWaitTask.  Therefore pipeDrv must get dragged in to use the system driver.SEE ALSO: POSIX 1003.1b document*//* includes */#include "vxWorks.h" #include "aioSysDrv.h"#include "stdio.h"#include "taskLib.h"#include "private/iosLibP.h"#include "logLib.h"#include "selectLib.h"#include "string.h"	#include "pipeDrv.h"#include "ioLib.h"/* defines *//* other defines */#define AIO_TASK_BASE_NAME	"tAioIoTask"	/* task base name */#define AIO_TASK_NAME_LEN	50		/* expected task name length */#define AIO_WAIT_TASK_NAME	"tAioWait"	/* wait task name */#define AIO_PIPE_NAME		"/aioPipe"	/* pipe name */#define AIO_PIPE_MSG_MAX	50		/* max pipe messages */#define READ_OP			0		/* read operation */#define WRITE_OP		1		/* write operation */#define IO_OP(op)		((op) == IO_READ ? READ_OP : WRITE_OP)/* AIO system driver flags */#define DRV_SELECT		0x4		/* select device */#define	DRV_NOSELECT		0x8		/* not a select device *//* typedefs */typedef struct wait_msg				/* wait message */    {    int			op;			/* READ_OP || WRITE_OP */    int			fd;			/* file descriptor */    } WAIT_MSG;/* globals */FUNCPTR aioSysPrintRtn = NULL;			/* print routine */struct						/* aioWaitTask wait fds */    {    fd_set	ioWait [2];	    fd_set	io [2];	    } ioFds;/* locals */LOCAL AIO_DEV	aioDev;				/* AIO device structure */LOCAL SEMAPHORE aioIOSem;			/* I/O semaphore */LOCAL SEMAPHORE	aioSysQSem;			/* Q semaphore (work & done) */LOCAL SEMAPHORE	aioSysWorkSem;			/* work semaphore */LOCAL BOOL	aioSysInitialized = FALSE;	/* library initialized */LOCAL int	aioSysFd;			/* wait task control fd *//* forward declarations */void   		aioIoTask (AIO_DEV * pDev);void   		aioWaitTask (void);LOCAL STATUS 	aioSysInsert (int value, struct aiocb * pAiocb, int prio);LOCAL STATUS 	aioSysIoctl (int value, int function, int arg);LOCAL STATUS	aioSysRead (struct aiocb * pAiocb, int * pError);LOCAL STATUS 	aioSysWrite (struct aiocb * pAiocb, int * pError);LOCAL STATUS 	aioSysSyncReq (AIO_DEV * pDev, AIO_SYS * pReq);LOCAL BOOL 	aioSysOpWillBlock (int fd, int op);LOCAL BOOL 	aioSysBlockingDev (int fd);LOCAL BOOL 	aioSysWaitFind (AIO_SYS * pReq, IO_Q * pQ, int bogus4);/********************************************************************************* aioSysInit - initialize the AIO system driver* * This routine initializes the AIO system driver.  It should be called* once after the AIO library has been initialized.  It spawns* <numTasks> system I/O tasks to be executed at <taskPrio> priority level,* with a stack size of <taskStackSize>.  It also starts the wait task and sets * the system driver as the default driver for AIO. If <numTasks>, <taskPrio>,* or <taskStackSize> is 0, a default value (AIO_IO_TASKS_DFLT, AIO_IO_PRIO_DFLT,* or AIO_IO_STACK_DFLT, respectively) is used.** RETURNS: OK if successful, otherwise ERROR.*/STATUS aioSysInit     (    int			numTasks,		/* number of system tasks */    int			taskPrio,		/* AIO task priority */    int			taskStackSize		/* AIO task stack size */    )    {    int			ix;			/* index */    char 		taskName [AIO_TASK_NAME_LEN];								/* area to build task name */    if (aioSysInitialized)	return (OK);				/* already initialized */    /* Set default parameter values */    taskStackSize = (taskStackSize == 0) ? AIO_IO_STACK_DFLT : taskStackSize;    numTasks	  = (numTasks == 0) ? AIO_IO_TASKS_DFLT : numTasks;    taskPrio	  = (taskPrio == 0) ? AIO_IO_PRIO_DFLT : min (taskPrio, 254);    /* Initialize the I/O queues (workQ and waitQ) */    semMInit (&aioSysQSem, SEM_DELETE_SAFE | SEM_Q_PRIORITY);    ioQInit (&aioDev.ioQ, ioQLockSem, ioQUnlockSem, (int) &aioSysQSem);    /* Create IPC pipe for I/O tasks and wait task */    pipeDrv ();    if ((pipeDevCreate (AIO_PIPE_NAME, AIO_PIPE_MSG_MAX, 			sizeof (WAIT_MSG)) == ERROR) ||        (aioSysFd = open (AIO_PIPE_NAME, O_RDWR, 0666)) == ERROR)	return (ERROR);				/* pipe driver needed */    /* Start aioWaitTask.  It must have a lower priority than aioIoTasks. */    if (taskSpawn (AIO_WAIT_TASK_NAME, taskPrio + 1, AIO_TASK_OPT, 		   AIO_WAIT_STACK, (FUNCPTR) aioWaitTask, 		   0, 0, 0, 0, 0, 0, 0, 0, 0, 0) == ERROR) 	return (ERROR);    /* Initialize the work and position semaphores */    semCInit (&aioSysWorkSem, SEM_Q_FIFO, SEM_EMPTY);    semMInit (&aioIOSem, SEM_DELETE_SAFE | SEM_Q_PRIORITY);    /* Spawn aioIoTasks */    while (numTasks-- > 0)	{	sprintf (taskName,"%s%d", AIO_TASK_BASE_NAME, numTasks); 	if (aioSysPrintRtn != NULL)	    (* aioSysPrintRtn) ("aioIoTask: %s starting\n", (int) taskName, 				0, 0, 0, 0, 0);	if (taskSpawn (taskName, taskPrio, AIO_TASK_OPT, taskStackSize, 		       (FUNCPTR) aioIoTask, (int) &aioDev, 0, 0, 0, 0, 0, 0, 		       0, 0, 0) == ERROR)	    return (ERROR);	}    /* Install AIO system driver as the default driver */    for (ix = 0 ; ix < maxDrivers; ix++)	aioDrvInstall (ix, aioSysInsert, aioSysIoctl, 0);    aioSysInitialized = TRUE;			/* mark as initialized */    return (OK);    }/******************************************************************************* aioSysInsert - Insert an AIO request into the system work queue** This routine accepts an AIO request into the driver.  If there are * other requests waiting on the fd (for the requested op) it adds * the AIO request to the wait queue and notifies the aioWaitTask.  * Otherwise it adds the request to the work queue and signals the aioIoTask.** RETURNS: OK if successfully inserted, ERROR otherwise.*/LOCAL STATUS aioSysInsert     (    int 		value,			/* not used */    struct aiocb *	pAiocb,			/* AIO control block */    int			prio			/* priority */    )    {    WAIT_MSG 		newFd;			/* new fd to wait on */    IO_Q *		pQ = &aioDev.ioQ;	/* I/O queue */    AIO_SYS *		pReq = &pAiocb->aio_sys;/* AIO request */    if (aioSysPrintRtn != NULL)	(* aioSysPrintRtn) ("aioSysInsert: aiocb (0%x) prio (%d) op %d\n", 			    (int) pAiocb, prio, pReq->ioNode.op, 0, 0, 0);    IOQ_LOCK (pQ);				/* lock access */         if (pReq->state != AIO_READY)   	{        IOQ_UNLOCK (pQ);	return (ERROR);				/* requests been mucked */ 	}    /* Check if the wait task is already waiting on the file descriptor     * for the requested op.       */    if (FD_ISSET (pAiocb->aio_fildes, &ioFds.ioWait [IO_OP(pReq->ioNode.op)]))	{        if (aioSysPrintRtn != NULL)	    (* aioSysPrintRtn) ("aioSysInsert: will block - move wait queue\n");	IOQ_WAIT_ADD (pQ, &pReq->ioNode, prio);		/* add to wait Q */	pReq->state = AIO_WAIT;    	IOQ_UNLOCK (pQ);			newFd.op = IO_OP (pReq->ioNode.op);		/* notify waitTask */	newFd.fd = pAiocb->aio_fildes;	write (aioSysFd, (caddr_t) &newFd, sizeof (WAIT_MSG));	}    else	{        if (aioSysPrintRtn != NULL)	    (* aioSysPrintRtn) ("aioSysInsert: move to work queue\n");    	IOQ_WORK_ADD (pQ, &pReq->ioNode, prio);		/* add it to work Q */     	pReq->state = AIO_QUEUED;    	IOQ_UNLOCK (pQ);    	semGive (&aioSysWorkSem);			/* notify I/O Task */	}    return (OK);    }/******************************************************************************* aioSysIoctl - control an AIO request** This routine performs a control operation on a previously submitted AIO * request.** RETURNS: OK if successful, otherwise ERROR.*/LOCAL STATUS aioSysIoctl     (    int		value,				/* not used */    int		function,			/* ioctl function */    int		arg				/* argument */    )    {    int		retVal = OK;			/* return value */    switch (function)	{ 	case FAIO_CANCEL : 			/* cancel request */	    retVal = aioCancel (&aioDev, (struct aiocb *) arg); 	    break;	case FAIO_PUSH :			/* move to head */	    retVal = aioPush (&aioDev, (struct aiocb *) arg);	    break;	default:				/* unknown function */ 	    errno = S_ioLib_UNKNOWN_REQUEST;	    retVal = ERROR;	    break;	}    return (retVal);    }/********************************************************************************* aioIoTask - AIO I/O task** This routine performs the I/O on behalf of the caller.  It gets a requests * from the work queue and if the operation will not block, performs the * requested operation.  If the request will block it moves the request to the* wait queue and notifies the wait server of the new addition.** RETURNS: N/A* NOMANUAL*/ void aioIoTask    (    AIO_DEV *           pDev			/* AIO device */    )     {    AIO_SYS *		pReq;			/* AIO request */    int			op;			/* operation */    int			fd;			/* file descriptor */    int                 retVal;			/* return value */    int                 errorVal;           	/* error value */    WAIT_MSG		waitMsg;		/* wait msg */      FOREVER        {        semTake (&aioSysWorkSem, WAIT_FOREVER);     /* wait for work */        if ((pReq = aioNext (pDev)) == NULL)	   /* Get I/O request */            continue; 	op = pReq->ioNode.op;	fd = pReq->pAiocb->aio_fildes;	if (aioSysPrintRtn != NULL)	    (* aioSysPrintRtn) ("aioIoTask: (0x%x) op: %d fd: %d\n", 				(int) pReq->pAiocb, op, fd);    	semTake (&aioIOSem, WAIT_FOREVER);	/* Sync function */   	if (op == IO_SYNC) 	    {	    aioSync (pDev, pReq->pAiocb, aioSysSyncReq);    	    semGive (&aioIOSem);	    continue;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -