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

📄 aiopxlib.c

📁 VXWORKS源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
/* aioPxLib.c - asynchronous I/O (AIO) library (POSIX) *//* Copyright 1984-2002 Wind River Systems, Inc. */#include "copyright_wrs.h"/*modification history--------------------01k,17jul00,jgn  merge DOT-4 pthreads changes01j,26sep01,jgn  disable manual generation for aio_fsync (SPR #34282)01i,04feb99,vcm  adding errno code for aio_return()01h,15jan95,rhp  fix typo.            jdi  doc cleanup.01g,08apr94,kdl  changed aio_show() reference to aioShow().01f,01feb94,dvs  documentation changes.01e,26jan94,kdl	 commented out aio_fsync().01d,21jan94,kdl	 minor doc cleanup; made driver-related routines NOMANUAL.01c,12jan94,kdl	 changed aioInit() to aioPxLibInit(); added include of 		 private/schedP.h; general cleanup.01b,06dec93,dvs  minor configuration related changes; changed S_aioLib* to 		 S_aioPxLib*01a,04apr93,elh  written.*//* DESCRIPTIONThis library implements asynchronous I/O (AIO) according to the definition given by the POSIX standard 1003.1b (formerly 1003.4, Draft 14).  AIO provides the ability to overlap application processing and I/O operations initiated by the application.  With AIO, a task can perform I/O simultaneously to a single file multiple times or to multiple files.After an AIO operation has been initiated, the AIO proceeds in logical parallel with the processing done by the application.The effect of issuing an asynchronous I/O request is as if a separatethread of execution were performing the requested I/O. AIO LIBRARYThe AIO library is initialized by calling aioPxLibInit(), whichshould be called once (typically at system start-up) after the I/O system has already been initialized.AIO COMMANDS The file to be accessed asynchronously is opened via the standard open call.  Open returns a file descriptor which is used in subsequent AIO calls. The caller initiates asynchronous I/O via one of the following routines: .IP aio_read() 15initiates an asynchronous read.IP aio_write()initiates an asynchronous write.IP lio_listio()initiates a list of asynchronous I/O requests.LPEach of these routines has a return value and error value associated with it; however, these values indicate only whether the AIO request was successfully submitted (queued), not the ultimate success orfailure of the AIO operation itself.  There are separate return and error values associated with the success orfailure of the AIO operation itself.  The error status can be retrievedusing aio_error(); however, until the AIO operation completes, the errorstatus will be EINPROGRESS.  After the AIO operation completes, the returnstatus can be retrieved with aio_return().The aio_cancel() call cancels a previously submitted AIO request.  Theaio_suspend() call waits for an AIO operation to complete.Finally, the aioShow() call (not a standard POSIX function) displaysoutstanding AIO requests.AIO CONTROL BLOCKEach of the calls described above takes an AIO control block (`aiocb') asan argument.  The calling routine must allocate space for the `aiocb', andthis space must remain available for the duration of the AIO operation.(Thus the `aiocb' must not be created on the task's stack unless thecalling routine will not return until after the AIO operation is completeand aio_return() has been called.)  Each `aiocb' describes a single AIOoperation.  Therefore, simultaneous asynchronous I/O operations using thesame `aiocb' are not valid and produce undefined results.The `aiocb' structure and the data buffers referenced by it are used by the system to perform the AIO request.  Therefore, once the `aiocb' hasbeen submitted to the system, the application must not modify the `aiocb' structure until after a subsequent call to aio_return().  The aio_return() call retrieves the previously submitted AIO data structures from the system.After the aio_return() call, the calling application can modify the`aiocb', free the memory it occupies, or reuse it for another AIO call. As a result, if space for the `aiocb' is allocated off the stack the task should not be deleted (or complete running) until the `aiocb' has been retrieved from the system via an aio_return().The `aiocb' is defined in aio.h.  It has the following elements:.CS 	struct    	    {    	    int                 aio_fildes;      	    off_t               aio_offset;     	    volatile void *     aio_buf;     	    size_t              aio_nbytes;    	    int                 aio_reqprio;    	    struct sigevent     aio_sigevent;    	    int                 aio_lio_opcode;    	    AIO_SYS             aio_sys;     	    } aiocb.CE .IP `aio_fildes'file descriptor for I/O..IP `aio_offset'offset from the beginning of the file where theAIO takes place.  Note that performing AIO on the file does not cause the offset location to automatically increase as in read and write;the caller must therefore keep track of the location of reads and writes made to the file (see POSIX COMPLIANCE below). .IP `aio_buf'address of the buffer from/to which AIO is requested..IP `aio_nbytes'number of bytes to read or write..IP `aio_reqprio'amount by which to lower the priority of an AIO request.  EachAIO request is assigned a priority; this priority, based on the callingtask's priority, indicates the desired order of execution relative toother AIO requests for the file.  The `aio_reqprio' member allows thecaller to lower (but not raise) the AIO operation priority by thespecified value.  Valid values for `aio_reqprio' are in the range of zerothrough AIO_PRIO_DELTA_MAX.  If the value specified by `aio_req_prio'results in a priority lower than the lowest possible task priority, thelowest valid task priority is used..IP `aio_sigevent'(optional) if nonzero, the signal to return on completion of an operation..IP `aio_lio_opcode'operation to be performed by a lio_listio() call; valid entries includeLIO_READ, LIO_WRITE, and LIO_NOP.  .IP `aio_sys'a Wind River Systems addition to the `aiocb' structure; it isused internally by the system and must not be modified by the user..LPEXAMPLESA writer could be implemented as follows:.CS    if ((pAioWrite = calloc (1, sizeof (struct aiocb))) == NULL)        {        printf ("calloc failed\en");        return (ERROR);        }    pAioWrite->aio_fildes = fd;    pAioWrite->aio_buf = buffer;    pAioWrite->aio_offset = 0;    strcpy (pAioWrite->aio_buf, "test string");    pAioWrite->aio_nbytes  = strlen ("test string");    pAioWrite->aio_sigevent.sigev_notify = SIGEV_NONE;    aio_write (pAioWrite);    /@  .	.	do other work	.	.    @/    /@ now wait until I/O finishes @/    while (aio_error (pAioWrite) == EINPROGRESS)        taskDelay (1);    aio_return (pAioWrite);    free (pAioWrite);.CE   A reader could be implemented as follows:.CS    /@ initialize signal handler @/     action1.sa_sigaction = sigHandler;    action1.sa_flags   = SA_SIGINFO;    sigemptyset(&action1.sa_mask);    sigaction (TEST_RT_SIG1, &action1, NULL);    if ((pAioRead = calloc (1, sizeof (struct aiocb))) == NULL)        {        printf ("calloc failed\en");        return (ERROR);        }     pAioRead->aio_fildes = fd;    pAioRead->aio_buf = buffer;    pAioRead->aio_nbytes = BUF_SIZE;    pAioRead->aio_sigevent.sigev_signo = TEST_RT_SIG1;    pAioRead->aio_sigevent.sigev_notify = SIGEV_SIGNAL;    pAioRead->aio_sigevent.sigev_value.sival_ptr = (void *)pAioRead;     aio_read (pAioRead);    /@        .        .        do other work 	.	.    @/.CEThe signal handler might look like the following:.CSvoid sigHandler    (    int                 sig,    struct siginfo      info,    void *              pContext    )    {    struct aiocb *      pAioDone;    pAioDone = (struct aiocb *) info.si_value.sival_ptr;    aio_return (pAioDone);    free (pAioDone);    }.CEPOSIX COMPLIANCECurrently VxWorks does not support the O_APPEND flag in the open call.  Therefore, the user must keep track of the offset in the file that the asynchronous writes occur (as in the case of reads).  The `aio_offset'field is used to specify that file position.In addition, VxWorks does not currently support synchronized I/O.INCLUDE FILES: aio.hSEE ALSO: POSIX 1003.1b documentINTERNALAs it currently stands, aioLib could be better integrated into the I/O system.  aioDrvTable and aioFdTable could be integrated with drvTable and fdTable respectively.  Also, the hook routines aioFdNew and aioFdFreecould be eliminated.  However we choose not to do this (for now) toavoid increasing the size of the I/O structures (thus causing the userto have to recompile their applications).  This should be changed  later.Although the interface between aioLib and AIO drivers has been defined, currently there is only support to use it with the AIO system driver.  Workneeds to be done (as well as modifications to the xxxFsLib and scsiLib) before it can be implemented in our block devices.*/ /* includes */ #include "vxWorks.h" #include "aio.h"#include "private/iosLibP.h" #include "string.h"#include "qFifoLib.h"#include "timers.h"#include "intLib.h"#include "taskLib.h"#include "stdlib.h"#include "tickLib.h"#include "private/mutexPxLibP.h"#include "private/schedP.h" #define __PTHREAD_SRC#include "pthread.h"/* defines */#define AIO_LOCK()		(semTake (&aioSem, WAIT_FOREVER))#define AIO_UNLOCK()		(semGive (&aioSem))/* typedefs */typedef struct 					/* each parameter */    {    AIO_DEV * 	pDev;				/* device */    int		retVal;				/* return value */    int		errorVal;			/* error value */    FUNCPTR	syncRtn;			/* sync routine */    } ARGS;/* globals */FUNCPTR			aioPrintRtn = NULL;/* locals */LOCAL AIO_DRV_ENTRY *	aioDrvTable = NULL;		/* driver table */LOCAL AIO_FD_ENTRY *	aioFdTable = NULL;		/* fd table */LOCAL AIO_CLUST *	aioClustTable = NULL;		/* cluster table */LOCAL int		aioClustMax;			/* max clusters */LOCAL SEMAPHORE		aioSem;				/* AIO semaphore *//* forward declarations */LOCAL STATUS  aioSubmit (struct aiocb * pAiocb, int op, AIO_CLUST * pClust);LOCAL int     aioListEach (struct aiocb * list[], int num, FUNCPTR routine, 			   int arg1, int arg2);LOCAL BOOL    aioListSubmit (struct aiocb * pAiocb, AIO_CLUST * pClust, 			     BOOL * pFailed);LOCAL BOOL    aioListClust (struct aiocb * pAiocb, AIO_CLUST * pClust, 			    int bogus);LOCAL BOOL    aioListError (struct aiocb * pAiocb, int * pError, int bogus);LOCAL BOOL    aioListWait (struct aiocb * pAiocb, AIO_WAIT_ID * pAioId, 			    int bogus);LOCAL BOOL    aioListUnwait (struct aiocb * pAiocb, AIO_WAIT_ID * pAioId, 			     int bogus);LOCAL STATUS  aioSyncNode (DL_NODE * pFdNode, ARGS * pArgs);LOCAL void    aioClustRet (struct aiocb * pAiocb, AIO_CLUST * pClust);LOCAL AIO_CLUST *    aioClustGet (void);/* I/O hook routines */LOCAL void    aioFdFree (int fd);		LOCAL void    aioFdNew (int fd);extern BOOL		iosLibInitialized;/******************************************************************************** * aioPxLibInit - initialize the asynchronous I/O (AIO) library** This routine initializes the AIO library.  It should be called only* once after the I/O system has been initialized.  <lioMax> specifies the * maximum number of outstanding lio_listio() calls at one time.  If <lioMax>* is zero, the default value of AIO_CLUST_MAX is used.** RETURNS: OK if successful, otherwise ERROR.** ERRNO: S_aioPxLib_IOS_NOT_INITIALIZED** INTERNAL:  This library relies on the fact that the IOS library * has been installed because it uses the variables maxDrivers and maxFiles. * This can be better integrated into the I/O system but for now we do this * to avoid adding entries to the drvTable and fdTable.*/STATUS aioPxLibInit     (    int			lioMax 			/* max outstanding lio calls */    )    {    int			ix;			/* index */    if (!iosLibInitialized)	{	errno = S_aioPxLib_IOS_NOT_INITIALIZED;	return (ERROR);				/* ios not initialized */	}    if (aioDrvTable != NULL)	return (OK);				/* already initialized */    /* Allocate memory for the AIO driver table */    if ((aioDrvTable = calloc (maxDrivers, sizeof (AIO_DRV_ENTRY))) == NULL)	return (ERROR);    /* Allocate memory for the AIO fd table */    if ((aioFdTable = calloc (maxFiles, sizeof (AIO_FD_ENTRY))) == NULL)	return (ERROR);    for (ix = 0; ix < maxFiles; ix++)	{	AIO_FD_ENTRY *	pEntry = &aioFdTable [ix];        pEntry->pFdEntry = &fdTable [ix];        semMInit (&pEntry->ioQSem, SEM_DELETE_SAFE | SEM_Q_PRIORITY);	}    /* Allocate and initialize the cluster table */    aioClustMax = (lioMax == 0) ? AIO_CLUST_MAX : lioMax;    if ((aioClustTable = calloc (aioClustMax, sizeof (AIO_CLUST))) == NULL)	return (ERROR);				/* memory problem */     for (ix = 0 ; ix < aioClustMax; ix++)	aioClustTable [ix].inuse = FALSE;    /* Initialize semaphore that protects data structures created above */    semMInit (&aioSem, SEM_DELETE_SAFE | SEM_Q_PRIORITY);    /* Hook into the ios system */     iosFdNewHookRtn  = aioFdNew;    iosFdFreeHookRtn = aioFdFree;    return (OK);    }/* POSIX specified routines *//********************************************************************************* aio_read - initiate an asynchronous read (POSIX)** This routine asynchronously reads data based on the following parameters* specified by members of the AIO control structure <pAiocb>.  It reads* `aio_nbytes' bytes of data from the file `aio_fildes' into the buffer* `aio_buf'.** The requested operation takes place at the absolute position in the file* as specified by `aio_offset'.** `aio_reqprio' can be used to lower the priority of the AIO request; if* this parameter is nonzero, the priority of the AIO request is* `aio_reqprio' lower than the calling task priority.** The call returns when the read request has been initiated or queued to the* device.  aio_error() can be used to determine the error status and of the* AIO operation.  On completion, aio_return() can be used to determine the* return status.** `aio_sigevent' defines the signal to be generated on completion * of the read request.  If this value is zero, no signal is generated. ** RETURNS: OK if the read queued successfully, otherwise ERROR.** ERRNO: EBADF, EINVAL** INCLUDE FILES: aio.h** SEE ALSO: aio_error(), aio_return(), read()**/int aio_read     (    struct aiocb * 	pAiocb			/* AIO control block */    )    {    return (aioSubmit (pAiocb, IO_READ, NULL));    }    /********************************************************************************* aio_write - initiate an asynchronous write (POSIX)** This routine asynchronously writes data based on the following parameters* specified by members of the AIO control structure <pAiocb>.  It writes* `aio_nbytes' of data to the file `aio_fildes' from the buffer `aio_buf'.** The requested operation takes place at the absolute position in the file* as specified by `aio_offset'.** `aio_reqprio' can be used to lower the priority of the AIO request; if* this parameter is nonzero, the priority of the AIO request is

⌨️ 快捷键说明

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