Modify logic to use AIO control block container

This commit is contained in:
Gregory Nutt 2014-10-06 08:10:32 -06:00
parent 52ce95b8b8
commit a5b4a4161b
5 changed files with 115 additions and 52 deletions

View File

@ -1,5 +1,5 @@
/**************************************************************************** /****************************************************************************
* libc/aio/aio_cancel.c * fs/aio/aio_cancel.c
* *
* Copyright (C) 2014 Gregory Nutt. All rights reserved. * Copyright (C) 2014 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org> * Author: Gregory Nutt <gnutt@nuttx.org>
@ -60,11 +60,11 @@
****************************************************************************/ ****************************************************************************/
/**************************************************************************** /****************************************************************************
* Private Variables * Private Data
****************************************************************************/ ****************************************************************************/
/**************************************************************************** /****************************************************************************
* Public Variables * Public Data
****************************************************************************/ ****************************************************************************/
/**************************************************************************** /****************************************************************************
@ -95,7 +95,7 @@
* will not be modified by aio_cancel(). * will not be modified by aio_cancel().
* *
* Input Parameters: * Input Parameters:
* fildes - Not used in this implmentation * fildes - Not used in this implementation
* aiocbp - Points to the asynchronous I/O control block for a particular * aiocbp - Points to the asynchronous I/O control block for a particular
* request to be cancelled. * request to be cancelled.
* *
@ -122,6 +122,7 @@
int aio_cancel(int fildes, FAR struct aiocb *aiocbp) int aio_cancel(int fildes, FAR struct aiocb *aiocbp)
{ {
FAR struct aio_container_s *aioc;
int status; int status;
int ret; int ret;
@ -143,16 +144,38 @@ int aio_cancel(int fildes, FAR struct aiocb *aiocbp)
if (aiocbp->aio_result == -EINPROGRESS) if (aiocbp->aio_result == -EINPROGRESS)
{ {
/* No ... attempt to cancel the I/O. There are two possibilities: (1) /* No.. Find the container for this AIO control block */
* the work has already been started and is no longer queued, or (2)
* the work has not been started and is still in the work queue. Only aio_lock();
* the second case can be cancelled. work_cancel() will return for (aioc = (FAR struct aio_container_s *)g_aio_pending.head;
* -ENOENT in the first case. aioc && aioc->aioc_aiocbp != aiocbp;
aioc = (FAR struct aio_container_s *)aioc->aioc_link.flink);
aio_unlock();
/* Did we find the container? */
if (!aioc)
{
/* No.. the aio_result says that that the transfer is pending,
* but there is no container in the pending I/O list. I am
* confused.
*/ */
status = work_cancel(LPWORK, &aiocbp->aio_work); ret = AIO_ALLDONE;
}
else
{
/* Yes... attempt to cancel the I/O. There are two possibilities:
* (1) the work has already been started and is no longer queued,
* or (2) the work has not been started and is still in the work
* queue. Only the second case can be cancelled. work_cancel()
* will return -ENOENT in the first case.
*/
status = work_cancel(LPWORK, &aioc->aioc_work);
ret = status >= 0 ? AIO_CANCELED : AIO_NOTCANCELED; ret = status >= 0 ? AIO_CANCELED : AIO_NOTCANCELED;
} }
}
else else
{ {
/* The I/O has already completed */ /* The I/O has already completed */

View File

@ -1,5 +1,5 @@
/**************************************************************************** /****************************************************************************
* libc/aio/aio_fsync.c * fs/aio/aio_fsync.c
* *
* Copyright (C) 2014 Gregory Nutt. All rights reserved. * Copyright (C) 2014 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org> * Author: Gregory Nutt <gnutt@nuttx.org>
@ -54,18 +54,17 @@
/**************************************************************************** /****************************************************************************
* Pre-processor Definitions * Pre-processor Definitions
****************************************************************************/ ****************************************************************************/
/* Configuration ************************************************************/
/**************************************************************************** /****************************************************************************
* Private Types * Private Types
****************************************************************************/ ****************************************************************************/
/**************************************************************************** /****************************************************************************
* Private Variables * Private Data
****************************************************************************/ ****************************************************************************/
/**************************************************************************** /****************************************************************************
* Public Variables * Public Data
****************************************************************************/ ****************************************************************************/
/**************************************************************************** /****************************************************************************
@ -90,10 +89,20 @@
static void aio_fsync_worker(FAR void *arg) static void aio_fsync_worker(FAR void *arg)
{ {
FAR struct aiocb *aiocbp = (FAR struct aiocb *)arg; FAR struct aio_container_s *aioc = (FAR struct aio_container_s *)arg;
DEBUGASSERT(arg); FAR struct aiocb *aiocbp;
pid_t pid;
int ret; int ret;
/* Get the information from the container, decant the AIO control block,
* and free the container before starting any I/O. That will minimize
* the delays by any other threads waiting for a pre-allocated container.
*/
DEBUGASSERT(aioc && aioc->aioc_aiocbp);
pid = aioc->aioc_pid;
aiocbp = aioc_decant(aioc);
/* Perform the fsync using aio_fildes */ /* Perform the fsync using aio_fildes */
ret = fsync(aiocbp->aio_fildes); ret = fsync(aiocbp->aio_fildes);
@ -111,7 +120,7 @@ static void aio_fsync_worker(FAR void *arg)
/* Signal the client */ /* Signal the client */
(void)aio_signal(aiocbp); (void)aio_signal(pid, aiocbp);
} }
/**************************************************************************** /****************************************************************************
@ -198,6 +207,7 @@ static void aio_fsync_worker(FAR void *arg)
int aio_fsync(int op, FAR struct aiocb *aiocbp) int aio_fsync(int op, FAR struct aiocb *aiocbp)
{ {
FAR struct aio_container_s *aioc;
int ret; int ret;
DEBUGASSERT(op == O_SYNC /* || op == O_DSYNC */); DEBUGASSERT(op == O_SYNC /* || op == O_DSYNC */);
@ -208,13 +218,16 @@ int aio_fsync(int op, FAR struct aiocb *aiocbp)
aiocbp->aio_result = -EINPROGRESS; aiocbp->aio_result = -EINPROGRESS;
aiocbp->aio_priv = NULL; aiocbp->aio_priv = NULL;
/* Save the ID of the calling, client thread */ /* Create a container for the AIO control block. This will not fail but
* may cause us to block if there are insufficient resources to satisfy
* the request.
*/
aiocbp->aio_pid = getpid(); aioc = aio_contain(aiocbp);
/* Defer the work to the worker thread */ /* Defer the work to the worker thread */
ret = work_queue(LPWORK, &aiocbp->aio_work, aio_fsync_worker, aiocbp, 0); ret = work_queue(LPWORK, &aioc->aioc_work, aio_fsync_worker, aioc, 0);
if (ret < 0) if (ret < 0)
{ {
aiocbp->aio_result = ret; aiocbp->aio_result = ret;

View File

@ -1,5 +1,5 @@
/**************************************************************************** /****************************************************************************
* libc/aio/aio_read.c * fs/aio/aio_read.c
* *
* Copyright (C) 2014 Gregory Nutt. All rights reserved. * Copyright (C) 2014 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org> * Author: Gregory Nutt <gnutt@nuttx.org>
@ -55,18 +55,17 @@
/**************************************************************************** /****************************************************************************
* Pre-processor Definitions * Pre-processor Definitions
****************************************************************************/ ****************************************************************************/
/* Configuration ************************************************************/
/**************************************************************************** /****************************************************************************
* Private Types * Private Types
****************************************************************************/ ****************************************************************************/
/**************************************************************************** /****************************************************************************
* Private Variables * Private Data
****************************************************************************/ ****************************************************************************/
/**************************************************************************** /****************************************************************************
* Public Variables * Public Data
****************************************************************************/ ****************************************************************************/
/**************************************************************************** /****************************************************************************
@ -91,10 +90,20 @@
static void aio_read_worker(FAR void *arg) static void aio_read_worker(FAR void *arg)
{ {
FAR struct aiocb *aiocbp = (FAR struct aiocb *)arg; FAR struct aio_container_s *aioc = (FAR struct aio_container_s *)arg;
DEBUGASSERT(arg); FAR struct aiocb *aiocbp;
pid_t pid;
ssize_t nread; ssize_t nread;
/* Get the information from the container, decant the AIO control block,
* and free the container before starting any I/O. That will minimize
* the delays by any other threads waiting for a pre-allocated container.
*/
DEBUGASSERT(aioc && aioc->aioc_aiocbp);
pid = aioc->aioc_pid;
aiocbp = aioc_decant(aioc);
/* Perform the read using: /* Perform the read using:
* *
* aio_fildes - File descriptor * aio_fildes - File descriptor
@ -122,7 +131,7 @@ static void aio_read_worker(FAR void *arg)
/* Signal the client */ /* Signal the client */
(void)aio_signal(aiocbp); (void)aio_signal(pid, aiocbp);
} }
/**************************************************************************** /****************************************************************************
@ -247,6 +256,7 @@ static void aio_read_worker(FAR void *arg)
int aio_read(FAR struct aiocb *aiocbp) int aio_read(FAR struct aiocb *aiocbp)
{ {
FAR struct aio_container_s *aioc;
int ret; int ret;
DEBUGASSERT(aiocbp); DEBUGASSERT(aiocbp);
@ -256,13 +266,16 @@ int aio_read(FAR struct aiocb *aiocbp)
aiocbp->aio_result = -EINPROGRESS; aiocbp->aio_result = -EINPROGRESS;
aiocbp->aio_priv = NULL; aiocbp->aio_priv = NULL;
/* Save the ID of the calling, client thread */ /* Create a container for the AIO control block. This will not fail but
* may cause us to block if there are insufficient resources to satisfy
* the request.
*/
aiocbp->aio_pid = getpid(); aioc = aio_contain(aiocbp);
/* Defer the work to the worker thread */ /* Defer the work to the worker thread */
ret = work_queue(LPWORK, &aiocbp->aio_work, aio_read_worker, aiocbp, 0); ret = work_queue(LPWORK, &aioc->aioc_work, aio_read_worker, aioc, 0);
if (ret < 0) if (ret < 0)
{ {
aiocbp->aio_result = ret; aiocbp->aio_result = ret;

View File

@ -1,5 +1,5 @@
/**************************************************************************** /****************************************************************************
* libc/aio/aio_signal.c * fs/aio/aio_signal.c
* *
* Copyright (C) 2014 Gregory Nutt. All rights reserved. * Copyright (C) 2014 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org> * Author: Gregory Nutt <gnutt@nuttx.org>
@ -39,6 +39,7 @@
#include <nuttx/config.h> #include <nuttx/config.h>
#include <sys/types.h>
#include <sched.h> #include <sched.h>
#include <signal.h> #include <signal.h>
#include <aio.h> #include <aio.h>
@ -53,18 +54,17 @@
/**************************************************************************** /****************************************************************************
* Pre-processor Definitions * Pre-processor Definitions
****************************************************************************/ ****************************************************************************/
/* Configuration ************************************************************/
/**************************************************************************** /****************************************************************************
* Private Types * Private Types
****************************************************************************/ ****************************************************************************/
/**************************************************************************** /****************************************************************************
* Private Variables * Private Data
****************************************************************************/ ****************************************************************************/
/**************************************************************************** /****************************************************************************
* Public Variables * Public Data
****************************************************************************/ ****************************************************************************/
/**************************************************************************** /****************************************************************************
@ -81,6 +81,7 @@
* Signal the client that an I/O has completed. * Signal the client that an I/O has completed.
* *
* Input Parameters: * Input Parameters:
* pid - ID of the task to signal
* aiocbp - Pointer to the asynchronous I/O state structure that includes * aiocbp - Pointer to the asynchronous I/O state structure that includes
* information about how to signal the client * information about how to signal the client
* *
@ -93,7 +94,7 @@
* *
****************************************************************************/ ****************************************************************************/
int aio_signal(FAR struct aiocb *aiocbp) int aio_signal(pid_t pid, FAR struct aiocb *aiocbp)
{ {
int errcode; int errcode;
int status; int status;
@ -108,10 +109,10 @@ int aio_signal(FAR struct aiocb *aiocbp)
if (aiocbp->aio_sigevent.sigev_notify == SIGEV_SIGNAL) if (aiocbp->aio_sigevent.sigev_notify == SIGEV_SIGNAL)
{ {
#ifdef CONFIG_CAN_PASS_STRUCTS #ifdef CONFIG_CAN_PASS_STRUCTS
status = sigqueue(aiocbp->aio_pid, aiocbp->aio_sigevent.sigev_signo, status = sigqueue(pid, aiocbp->aio_sigevent.sigev_signo,
aiocbp->aio_sigevent.sigev_value); aiocbp->aio_sigevent.sigev_value);
#else #else
status = sigqueue(aiocbp->aio_pid, aiocbp->aio_sigevent.sigev_sign, status = sigqueue(pid, aiocbp->aio_sigevent.sigev_sign,
aiocbp->aio_sigevent.sigev_value.sival_ptr); aiocbp->aio_sigevent.sigev_value.sival_ptr);
#endif #endif
if (ret < 0) if (ret < 0)
@ -126,7 +127,7 @@ int aio_signal(FAR struct aiocb *aiocbp)
* on sig_suspend(); * on sig_suspend();
*/ */
status = kill(aiocbp->aio_pid, SIGPOLL); status = kill(pid, SIGPOLL);
if (status && ret == OK) if (status && ret == OK)
{ {
errcode = get_errno(); errcode = get_errno();

View File

@ -1,5 +1,5 @@
/**************************************************************************** /****************************************************************************
* libc/aio/aio_write.c * fs/aio/aio_write.c
* *
* Copyright (C) 2014 Gregory Nutt. All rights reserved. * Copyright (C) 2014 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org> * Author: Gregory Nutt <gnutt@nuttx.org>
@ -56,18 +56,17 @@
/**************************************************************************** /****************************************************************************
* Pre-processor Definitions * Pre-processor Definitions
****************************************************************************/ ****************************************************************************/
/* Configuration ************************************************************/
/**************************************************************************** /****************************************************************************
* Private Types * Private Types
****************************************************************************/ ****************************************************************************/
/**************************************************************************** /****************************************************************************
* Private Variables * Private Data
****************************************************************************/ ****************************************************************************/
/**************************************************************************** /****************************************************************************
* Public Variables * Public Data
****************************************************************************/ ****************************************************************************/
/**************************************************************************** /****************************************************************************
@ -92,11 +91,21 @@
static void aio_write_worker(FAR void *arg) static void aio_write_worker(FAR void *arg)
{ {
FAR struct aiocb *aiocbp = (FAR struct aiocb *)arg; FAR struct aio_container_s *aioc = (FAR struct aio_container_s *)arg;
DEBUGASSERT(arg); FAR struct aiocb *aiocbp;
pid_t pid;
ssize_t nwritten; ssize_t nwritten;
int oflags; int oflags;
/* Get the information from the container, decant the AIO control block,
* and free the container before starting any I/O. That will minimize
* the delays by any other threads waiting for a pre-allocated container.
*/
DEBUGASSERT(aioc && aioc->aioc_aiocbp);
pid = aioc->aioc_pid;
aiocbp = aioc_decant(aioc);
/* Call fcntl(F_GETFL) to get the file open mode. */ /* Call fcntl(F_GETFL) to get the file open mode. */
oflags = fcntl(aiocbp->aio_fildes, F_GETFL); oflags = fcntl(aiocbp->aio_fildes, F_GETFL);
@ -151,7 +160,7 @@ static void aio_write_worker(FAR void *arg)
/* Signal the client */ /* Signal the client */
(void)aio_signal(aiocbp); (void)aio_signal(pid, aiocbp);
} }
/**************************************************************************** /****************************************************************************
@ -278,6 +287,7 @@ static void aio_write_worker(FAR void *arg)
int aio_write(FAR struct aiocb *aiocbp) int aio_write(FAR struct aiocb *aiocbp)
{ {
FAR struct aio_container_s *aioc;
int ret; int ret;
DEBUGASSERT(aiocbp); DEBUGASSERT(aiocbp);
@ -287,13 +297,16 @@ int aio_write(FAR struct aiocb *aiocbp)
aiocbp->aio_result = -EINPROGRESS; aiocbp->aio_result = -EINPROGRESS;
aiocbp->aio_priv = NULL; aiocbp->aio_priv = NULL;
/* Save the ID of the calling, client thread */ /* Create a container for the AIO control block. This will not fail but
* may cause us to block if there are insufficient resources to satisfy
* the request.
*/
aiocbp->aio_pid = getpid(); aioc = aio_contain(aiocbp);
/* Defer the work to the worker thread */ /* Defer the work to the worker thread */
ret = work_queue(LPWORK, &aiocbp->aio_work, aio_write_worker, aiocbp, 0); ret = work_queue(LPWORK, &aioc->aioc_work, aio_write_worker, aioc, 0);
if (ret < 0) if (ret < 0)
{ {
aiocbp->aio_result = ret; aiocbp->aio_result = ret;