libaio-oracle-0.3.0

来源:互联网 发布:excel数组求和 编辑:程序博客网 时间:2024/05/01 23:25

目前oracle公布的异步IO的实现与glibc的结构体有一些类似,只不过没有多线程,而是直接调用了libaio中的函数

 

/*
 * we always use a 64bit off_t when communicating
 * with userland.  its up to libraries to do the
 * proper padding and aio_error abstraction
 *
 * FIXME: this must change from glibc's definition
 * as we do *not* use the sigevent structure which
 * is big and bloated.
 */
struct aiocb64 {
  int aio_fildes;               /* File desriptor.  */
  short aio_lio_opcode;           /* Operation to be performed.  */
  short aio_reqprio;              /* Request priority offset.  */
  void *aio_buf;          /* Location of buffer.  */
  size_t aio_nbytes;            /* Length of transfer.  */
  loff_t aio_offset;  /* File offset.  */
  /* these are internal to the kernel/libc. */
  long __aio_key; // kernel sets this to -1 if completed 存的是执行的状态
       // otherwise >= 0 (the request#)
  void * __aio_data;  // pointer to be returned in event's data  指向_AIORequest
  int __error_code;
};

这就是存放数据的结构

 

/*
 * Structures
 */
struct _AIORequest
{
    struct iocb iocb;                /* Control block sent to kernel */
    struct aiocb64 *aiocb;      /* User's control block */
    AIORequest *next;           /* Next in request list */
    AIORequest *prev;           /* Previous in request list  next,prev是构成双向链表,连入_AIORequestQueue那四个List之  中

                                             的一个*/
};

 

struct _AIORequestQueue
{
    pid_t pid;                  /* Current PID */
    io_context_t ctxt;          /* Kernel IO context */
    unsigned long max_requests; /* Maxinum number of requests */
    AIORequest *requests;       /* Allocated requests */
    AIORequest *complete;       /* List of complete requests */
    AIORequest *current;        /* List of outstanding requests */
    AIORequest *free;           /* List of free requests */
};

 

 

/* Global for the library */
static AIORequestQueue *r_queue = NULL;

全局变量,初始分配固定大小的_AIORequest,连入_AIORequestQueue->free

 

 

int aio_read64(struct aiocb64 *aiocbp)

int aio_write64(struct aiocb64 *aiocbp)

这两个函数把数据放入r_queue 里面,之后调用io_submit;当返回时是不知道是否执行成功的

 

static long aior_get_events(struct timespec *timeout)

最终还是调用io_getevents,返回后,修改_AIORequest->aiocb->__error_code 和 _AIORequest->aiocb->__aio_key 的状态

 

int aio_error64(struct aiocb64 *aiocbp)

ssize_t aio_return64(struct aiocb64 *aiocbp)

还是根据aiocb64 ->__aio_key的状态来确定返回结果,并决定是否需要调用aior_get_events来获取最新的状态

 

 

int aio_suspend64(const struct aiocb64 * const list[], int nent, const struct timespec *timeout)

int aio_reap64(struct timespec *timeout, int waitfor, struct aiocb *out_list[], int listsize, int *completed_count)

里面都有

int done = 0;

while (done == 0)
{

...

ret = aior_get_events(timeout);

...

}

这样的轮循操作,其实也是通过这种方式来获得执行结果的

 

总的来说,libaio-oracle,是对libaio的又一层简单封装,多了一个全局变量_AIORequestQueue *r_queue ,通过它可方便批量io_submit,和glibc的区别,一是,还没有实现执行完信号量的通知,只能通过轮循获得最终状态;二是,没有多线程分别对不同的文件进行处理,而是把所有的执行,全局提交给了操作系统的底层实现,由操作系统来接手。

 

 

 

原创粉丝点击