PAPI  5.0.1.0
libasync.c File Reference
Include dependency graph for libasync.c:

Go to the source code of this file.

Data Structures

struct  cache_ent
struct  cache

Typedefs

typedef long long off64_t

Functions

void mbcopy (char *source, char *dest, size_t len)
struct cache_entalloc_cache ()
struct cache_entincache ()
void async_init ()
void end_async ()
int async_suspend ()
int async_read ()
void takeoff_cache ()
void del_cache ()
void async_release ()
void putoninuse ()
void takeoffinuse ()
struct cache_entallocate_write_buffer ()
size_t async_write ()
void async_wait_for_write ()
void async_put_on_write_queue ()
void async_write_finish ()
void async_init (struct cache **gc, int fd, int flag)
void end_async (struct cache *gc)
int async_suspend (struct cache_ent *ce)
int async_read (struct cache *gc, long long fd, char *ubuffer, off64_t offset, long long size, long long stride, off64_t max, long long depth)
struct cache_entalloc_cache (struct cache *gc, long long fd, off64_t offset, long long size, long long op)
struct cache_entincache (struct cache *gc, long long fd, off64_t offset, long long size)
void takeoff_cache (struct cache *gc, struct cache_ent *ce)
void del_cache (struct cache *gc)
int async_read_no_copy (struct cache *gc, long long fd, char **ubuffer, off64_t offset, long long size, long long stride, off64_t max, long long depth)
void async_release (struct cache *gc)
void putoninuse (struct cache *gc, struct cache_ent *entry)
void takeoffinuse (struct cache *gc)
size_t async_write (struct cache *gc, long long fd, char *buffer, long long size, off64_t offset, long long depth)
struct cache_entallocate_write_buffer (struct cache *gc, long long fd, off64_t offset, long long size, long long op, long long w_depth, long long direct, char *buffer, char *free_addr)
void async_put_on_write_queue (struct cache *gc, struct cache_ent *ce)
void async_write_finish (struct cache *gc)
void async_wait_for_write (struct cache *gc)
size_t async_write_no_copy (struct cache *gc, long long fd, char *buffer, long long size, off64_t offset, long long depth, char *free_addr)

Variables

long long page_size
int one
char version [] = "Libasync Version $Revision$"
long long max_depth
int errno

Typedef Documentation

typedef long long off64_t

Definition at line 139 of file libasync.c.


Function Documentation

struct cache_ent* alloc_cache ( ) [read]

Here is the caller graph for this function:

struct cache_ent* alloc_cache ( struct cache gc,
long long  fd,
off64_t  offset,
long long  size,
long long  op 
) [read]

Definition at line 598 of file libasync.c.

{
    struct cache_ent *ce;
    long temp;
    ce=(struct cache_ent *)malloc((size_t)sizeof(struct cache_ent));
    if(ce == (struct cache_ent *)0)
    {
        printf("Malloc failed\n");
        exit(175);
    }
    bzero(ce,sizeof(struct cache_ent));
#ifdef _LARGEFILE64_SOURCE 
#ifdef __LP64__
    ce->myaiocb.aio_fildes=(int)fd;
    ce->myaiocb.aio_offset=(off64_t)offset;
    ce->real_address = (char *)malloc((size_t)(size+page_size));
    temp=(long)ce->real_address;
    temp = (temp+page_size) & ~(page_size-1);
    ce->myaiocb.aio_buf=(volatile void *)temp;
    if(ce->myaiocb.aio_buf == 0)
#else
    ce->myaiocb64.aio_fildes=(int)fd;
    ce->myaiocb64.aio_offset=(off64_t)offset;
    ce->real_address = (char *)malloc((size_t)(size+page_size));
    temp=(long)ce->real_address;
    temp = (temp+page_size) & ~(page_size-1);
    ce->myaiocb64.aio_buf=(volatile void *)temp;
    if(ce->myaiocb64.aio_buf == 0)
#endif
#else
    ce->myaiocb.aio_fildes=(int)fd;
    ce->myaiocb.aio_offset=(off_t)offset;
    ce->real_address = (char *)malloc((size_t)(size+page_size));
    temp=(long)ce->real_address;
    temp = (temp+page_size) & ~(page_size-1);
    ce->myaiocb.aio_buf=(volatile void *)temp;
    if(ce->myaiocb.aio_buf == 0)
#endif
    {
        printf("Malloc failed\n");
        exit(176);
    }
    /*bzero(ce->myaiocb.aio_buf,(size_t)size);*/
#ifdef _LARGEFILE64_SOURCE 
#ifdef __LP64__
    ce->myaiocb.aio_reqprio=0;
    ce->myaiocb.aio_nbytes=(size_t)size;
    ce->myaiocb.aio_sigevent.sigev_notify=SIGEV_NONE;
    ce->myaiocb.aio_lio_opcode=(int)op;
#else
    ce->myaiocb64.aio_reqprio=0;
    ce->myaiocb64.aio_nbytes=(size_t)size;
    ce->myaiocb64.aio_sigevent.sigev_notify=SIGEV_NONE;
    ce->myaiocb64.aio_lio_opcode=(int)op;
#endif
#else
    ce->myaiocb.aio_reqprio=0;
    ce->myaiocb.aio_nbytes=(size_t)size;
    ce->myaiocb.aio_sigevent.sigev_notify=SIGEV_NONE;
    ce->myaiocb.aio_lio_opcode=(int)op;
#endif
    ce->fd=(int)fd;
    ce->forward=0;
    ce->back=gc->tail;
    if(gc->tail)
        gc->tail->forward = ce;
    gc->tail= ce;
    if(!gc->head)
        gc->head=ce;
    gc->count++;
    return(ce);
}

Here is the call graph for this function:

struct cache_ent* allocate_write_buffer ( ) [read]

Here is the caller graph for this function:

struct cache_ent* allocate_write_buffer ( struct cache gc,
long long  fd,
off64_t  offset,
long long  size,
long long  op,
long long  w_depth,
long long  direct,
char *  buffer,
char*  free_addr 
) [read]

Definition at line 1282 of file libasync.c.

{
    struct cache_ent *ce;
    long temp;
    if(fd==0LL)
    {
        printf("Setting up write buffer insane\n");
        exit(178);
    }
    if(gc->w_count > w_depth)
        async_wait_for_write(gc);
    ce=(struct cache_ent *)malloc((size_t)sizeof(struct cache_ent));
    if(ce == (struct cache_ent *)0)
    {
        printf("Malloc failed 1\n");
        exit(179);
    }
    bzero(ce,sizeof(struct cache_ent));
#ifdef _LARGEFILE64_SOURCE 
#ifdef __LP64__
    ce->myaiocb.aio_fildes=(int)fd;
    ce->myaiocb.aio_offset=(off64_t)offset;
    if(!direct)
    {
        ce->real_address = (char *)malloc((size_t)(size+page_size));
        temp=(long)ce->real_address;
        temp = (temp+page_size) & ~(page_size-1);
        ce->myaiocb.aio_buf=(volatile void *)temp;
    }else
    {
        ce->myaiocb.aio_buf=(volatile void *)buffer;
        ce->real_address=(char *)free_addr;
    }
    if(ce->myaiocb.aio_buf == 0)
#else
    ce->myaiocb64.aio_fildes=(int)fd;
    ce->myaiocb64.aio_offset=(off64_t)offset;
    if(!direct)
    {
        ce->real_address = (char *)malloc((size_t)(size+page_size));
        temp=(long)ce->real_address;
        temp = (temp+page_size) & ~(page_size-1);
        ce->myaiocb64.aio_buf=(volatile void *)temp;
    }
    else
    {
        ce->myaiocb64.aio_buf=(volatile void *)buffer;
        ce->real_address=(char *)free_addr;
    }
    if(ce->myaiocb64.aio_buf == 0)
#endif
#else
    ce->myaiocb.aio_fildes=(int)fd;
    ce->myaiocb.aio_offset=(off_t)offset;
    if(!direct)
    {
        ce->real_address = (char *)malloc((size_t)(size+page_size));
        temp=(long)ce->real_address;
        temp = (temp+page_size) & ~(page_size-1);
        ce->myaiocb.aio_buf=(volatile void *)temp;
    }
    else
    {
        ce->myaiocb.aio_buf=(volatile void *)buffer;
        ce->real_address=(char *)free_addr;
    }
    if(ce->myaiocb.aio_buf == 0)
#endif
    {
        printf("Malloc failed 2\n");
        exit(180);
    }
#ifdef _LARGEFILE64_SOURCE 
#ifdef __LP64__
    ce->myaiocb.aio_reqprio=0;
    ce->myaiocb.aio_nbytes=(size_t)size;
    ce->myaiocb.aio_sigevent.sigev_notify=SIGEV_NONE;
    ce->myaiocb.aio_lio_opcode=(int)op;
#else
    ce->myaiocb64.aio_reqprio=0;
    ce->myaiocb64.aio_nbytes=(size_t)size;
    ce->myaiocb64.aio_sigevent.sigev_notify=SIGEV_NONE;
    ce->myaiocb64.aio_lio_opcode=(int)op;
#endif
#else
    ce->myaiocb.aio_reqprio=0;
    ce->myaiocb.aio_nbytes=(size_t)size;
    ce->myaiocb.aio_sigevent.sigev_notify=SIGEV_NONE;
    ce->myaiocb.aio_lio_opcode=(int)op;
#endif
    ce->fd=(int)fd;
    return(ce);
}

Here is the call graph for this function:

void async_init ( )

Definition at line 19044 of file iozone.c.

{
    printf("Your system does not support async I/O\n");
    exit(172);
}

Here is the call graph for this function:

Here is the caller graph for this function:

void async_init ( struct cache **  gc,
int  fd,
int  flag 
)

Definition at line 227 of file libasync.c.

{
#ifdef VXFS
    if(flag)
        ioctl(fd,VX_SETCACHE,VX_DIRECT);
#endif
    if(*gc)
    {
        printf("Warning calling async_init two times ?\n");
        return;
    }
    *gc=(struct cache *)malloc((size_t)sizeof(struct cache));
    if(*gc == 0)
    {
        printf("Malloc failed\n");
        exit(174);
    }
    bzero(*gc,sizeof(struct cache));
#if defined(__AIX__) || defined(SCO_Unixware_gcc)
    max_depth=500;
#else
    max_depth=sysconf(_SC_AIO_MAX);
#endif
}

Here is the call graph for this function:

Here is the caller graph for this function:

void async_put_on_write_queue ( struct cache gc,
struct cache_ent ce 
)

Definition at line 1387 of file libasync.c.

{
    ce->forward=0;
    ce->back=gc->w_tail;
    if(gc->w_tail)
        gc->w_tail->forward = ce;
    gc->w_tail= ce;
    if(!gc->w_head)
        gc->w_head=ce;
    gc->w_count++;
    return;
}
int async_read ( )

Definition at line 19026 of file iozone.c.

{
    printf("Your system does not support async I/O\n");
    exit(169);
}

Here is the call graph for this function:

Here is the caller graph for this function:

int async_read ( struct cache gc,
long long  fd,
char *  ubuffer,
off64_t  offset,
long long  size,
long long  stride,
off64_t  max,
long long  depth 
)

Definition at line 324 of file libasync.c.

{
    off64_t a_offset,r_offset;
    long long a_size;
    struct cache_ent *ce,*first_ce=0;
    long long i;
    ssize_t retval=0;
    ssize_t ret;
    long long start = 0;
    long long del_read=0;

    a_offset=offset;
    a_size = size;
    /*
     * Check to see if it can be completed from the cache
     */
    if((ce=(struct cache_ent *)incache(gc,fd,offset,size)))
    {
#ifdef _LARGEFILE64_SOURCE 
#ifdef __LP64__
        while((ret=aio_error(&ce->myaiocb))== EINPROGRESS)
        {
            async_suspend(ce);
        }
#else
        while((ret=aio_error64(&ce->myaiocb64))== EINPROGRESS)
        {
            async_suspend(ce);
        }
#endif
#else
        while((ret=aio_error(&ce->myaiocb))== EINPROGRESS)
        {
            async_suspend(ce);
        }
#endif
        if(ret)
        {
            printf("aio_error 1: ret %d %d\n",ret,errno);
        }
#ifdef _LARGEFILE64_SOURCE 
#ifdef __LP64__
        retval=aio_return(&ce->myaiocb);
#else
#if defined(__CrayX1__)
        retval=aio_return64((aiocb64_t *)&ce->myaiocb64);
#else
        retval=aio_return64((struct aiocb64 *)&ce->myaiocb64);
#endif

#endif
#else
        retval=aio_return(&ce->myaiocb);
#endif
        if(retval > 0)
        {
#ifdef _LARGEFILE64_SOURCE 
#ifdef __LP64__
            mbcopy((char *)ce->myaiocb.aio_buf,(char *)ubuffer,(size_t)retval);
#else
            mbcopy((char *)ce->myaiocb64.aio_buf,(char *)ubuffer,(size_t)retval);
#endif
#else
            mbcopy((char *)ce->myaiocb.aio_buf,(char *)ubuffer,(size_t)retval);
#endif
        }
#ifdef _LARGEFILE64_SOURCE 
#ifdef __LP64__
        if(retval < ce->myaiocb.aio_nbytes)
#else
        if(retval < ce->myaiocb64.aio_nbytes)
#endif
#else
        if(retval < ce->myaiocb.aio_nbytes)
#endif
        {
            printf("aio_return error1: ret %d %d\n",retval,errno);
#ifdef _LARGEFILE64_SOURCE 
#ifdef __LP64__
            printf("aio_return error1: fd %d offset %ld buffer %lx size %d Opcode %d\n",
                ce->myaiocb.aio_fildes,
                ce->myaiocb.aio_offset,
                (long)(ce->myaiocb.aio_buf),
                ce->myaiocb.aio_nbytes,
                ce->myaiocb.aio_lio_opcode
#else
            printf("aio_return error1: fd %d offset %lld buffer %lx size %d Opcode %d\n",
                ce->myaiocb64.aio_fildes,
                ce->myaiocb64.aio_offset,
                (long)(ce->myaiocb64.aio_buf),
                ce->myaiocb64.aio_nbytes,
                ce->myaiocb64.aio_lio_opcode
#endif
#else
            printf("aio_return error1: fd %d offset %d buffer %lx size %d Opcode %d\n",
                ce->myaiocb.aio_fildes,
                ce->myaiocb.aio_offset,
                (long)(ce->myaiocb.aio_buf),
                ce->myaiocb.aio_nbytes,
                ce->myaiocb.aio_lio_opcode
#endif
                );
        }
        ce->direct=0;
        takeoff_cache(gc,ce);
    }else
    {
        /*
         * Clear the cache and issue the first request async()
         */
        del_cache(gc);
        del_read++;
        first_ce=alloc_cache(gc,fd,offset,size,(long long)LIO_READ);
again:
#ifdef _LARGEFILE64_SOURCE 
#ifdef __LP64__
        ret=aio_read(&first_ce->myaiocb);
#else
        ret=aio_read64(&first_ce->myaiocb64);
#endif
#else
        ret=aio_read(&first_ce->myaiocb);
#endif
        if(ret!=0)
        {
            if(errno==EAGAIN)
                goto again;
            else
                printf("error returned from aio_read(). Ret %d errno %d\n",ret,errno);
        }
    }
    if(stride==0)    /* User does not want read-ahead */
        goto out;
    if(a_offset<0)  /* Before beginning of file */
        goto out;
    if(a_offset+size>max)   /* After end of file */
        goto out;
    if(depth >=(max_depth-1))
        depth=max_depth-1;
    if(depth==0)
        goto out;
    if(gc->count > 1)
        start=depth-1;
    for(i=start;i<depth;i++)    /* Issue read-aheads for the depth specified */
    {
        r_offset=a_offset+((i+1)*(stride*a_size));
        if(r_offset<0)
            continue;
        if(r_offset+size > max)
            continue;
        if((ce=incache(gc,fd,r_offset,a_size)))
            continue;
        ce=alloc_cache(gc,fd,r_offset,a_size,(long long)LIO_READ);
#ifdef _LARGEFILE64_SOURCE 
#ifdef __LP64__
        ret=aio_read(&ce->myaiocb);
#else
        ret=aio_read64(&ce->myaiocb64);
#endif
#else
        ret=aio_read(&ce->myaiocb);
#endif
        if(ret!=0)
        {
            takeoff_cache(gc,ce);
            break;
        }
    }           
out:
    if(del_read)    /* Wait for the first read to complete */
    {
#ifdef _LARGEFILE64_SOURCE 
#ifdef __LP64__
        while((ret=aio_error(&first_ce->myaiocb))== EINPROGRESS)
        {
            async_suspend(first_ce);
        }
#else
        while((ret=aio_error64(&first_ce->myaiocb64))== EINPROGRESS)
        {
            async_suspend(first_ce);
        }
#endif
#else
        while((ret=aio_error(&first_ce->myaiocb))== EINPROGRESS)
        {
            async_suspend(first_ce);
        }
#endif
        if(ret)
            printf("aio_error 2: ret %d %d\n",ret,errno);
#ifdef _LARGEFILE64_SOURCE 
#ifdef __LP64__
        retval=aio_return(&first_ce->myaiocb);
#else
        retval=aio_return64(&first_ce->myaiocb64);
#endif
#else
        retval=aio_return(&first_ce->myaiocb);
#endif
#ifdef _LARGEFILE64_SOURCE 
#ifdef __LP64__
        if(retval < first_ce->myaiocb.aio_nbytes)
#else
        if(retval < first_ce->myaiocb64.aio_nbytes)
#endif
#else
        if(retval < first_ce->myaiocb.aio_nbytes)
#endif
        {
            printf("aio_return error2: ret %d %d\n",retval,errno);
#ifdef _LARGEFILE64_SOURCE 
#ifdef __LP64__
            printf("aio_return error2: fd %d offset %lld buffer %lx size %d Opcode %d\n",
                first_ce->myaiocb.aio_fildes,
                first_ce->myaiocb.aio_offset,
                (long)(first_ce->myaiocb.aio_buf),
                first_ce->myaiocb.aio_nbytes,
                first_ce->myaiocb.aio_lio_opcode
#else
            printf("aio_return error2: fd %d offset %lld buffer %lx size %d Opcode %d\n",
                first_ce->myaiocb64.aio_fildes,
                first_ce->myaiocb64.aio_offset,
                (long)(first_ce->myaiocb64.aio_buf),
                first_ce->myaiocb64.aio_nbytes,
                first_ce->myaiocb64.aio_lio_opcode
#endif
#else
            printf("aio_return error2: fd %d offset %d buffer %lx size %d Opcode %d\n",
                first_ce->myaiocb.aio_fildes,
                first_ce->myaiocb.aio_offset,
                (long)(first_ce->myaiocb.aio_buf),
                first_ce->myaiocb.aio_nbytes,
                first_ce->myaiocb.aio_lio_opcode
#endif
                );
        }
        if(retval > 0)
        {
#ifdef _LARGEFILE64_SOURCE 
#ifdef __LP64__
            mbcopy((char *)first_ce->myaiocb.aio_buf,(char *)ubuffer,(size_t)retval);
#else
            mbcopy((char *)first_ce->myaiocb64.aio_buf,(char *)ubuffer,(size_t)retval);
#endif
#else
            mbcopy((char *)first_ce->myaiocb.aio_buf,(char *)ubuffer,(size_t)retval);
#endif
        }
        first_ce->direct=0;
        takeoff_cache(gc,first_ce);
    }
    return((int)retval);    
}

Here is the call graph for this function:

int async_read_no_copy ( struct cache gc,
long long  fd,
char **  ubuffer,
off64_t  offset,
long long  size,
long long  stride,
off64_t  max,
long long  depth 
)

Definition at line 841 of file libasync.c.

{
    off64_t a_offset,r_offset;
    long long a_size;
    struct cache_ent *ce,*first_ce=0;
    long long i;
    ssize_t retval=0;
    ssize_t ret;
    long long del_read=0;
    long long start=0;

    a_offset=offset;
    a_size = size;
    /*
     * Check to see if it can be completed from the cache
     */
    if((ce=(struct cache_ent *)incache(gc,fd,offset,size)))
    {
#ifdef _LARGEFILE64_SOURCE 
#ifdef __LP64__
        while((ret=aio_error(&ce->myaiocb))== EINPROGRESS)
        {
            async_suspend(ce);
        }
#else
        while((ret=aio_error64(&ce->myaiocb64))== EINPROGRESS)
        {
            async_suspend(ce);
        }
#endif
#else
        while((ret=aio_error(&ce->myaiocb))== EINPROGRESS)
        {
            async_suspend(ce);
        }
#endif
        if(ret)
            printf("aio_error 3: ret %d %d\n",ret,errno);
#ifdef _LARGEFILE64_SOURCE 
#ifdef __LP64__
        if(ce->oldbuf != ce->myaiocb.aio_buf ||
            ce->oldfd != ce->myaiocb.aio_fildes ||
            ce->oldsize != ce->myaiocb.aio_nbytes) 
#else
        if(ce->oldbuf != ce->myaiocb64.aio_buf ||
            ce->oldfd != ce->myaiocb64.aio_fildes ||
            ce->oldsize != ce->myaiocb64.aio_nbytes) 
#endif
#else
        if(ce->oldbuf != ce->myaiocb.aio_buf ||
            ce->oldfd != ce->myaiocb.aio_fildes ||
            ce->oldsize != ce->myaiocb.aio_nbytes) 
#endif
            printf("It changed in flight\n");
            
#ifdef _LARGEFILE64_SOURCE 
#ifdef __LP64__
        retval=aio_return(&ce->myaiocb);
#else
        retval=aio_return64(&ce->myaiocb64);
#endif
#else
        retval=aio_return(&ce->myaiocb);
#endif
        if(retval > 0)
        {
#ifdef _LARGEFILE64_SOURCE 
#ifdef __LP64__
            *ubuffer=(char *)ce->myaiocb.aio_buf;
#else
            *ubuffer=(char *)ce->myaiocb64.aio_buf;
#endif
#else
            *ubuffer=(char *)ce->myaiocb.aio_buf;
#endif
        }else
            *ubuffer=0;
#ifdef _LARGEFILE64_SOURCE 
#ifdef __LP64__
        if(retval < ce->myaiocb.aio_nbytes)
#else
        if(retval < ce->myaiocb64.aio_nbytes)
#endif
#else
        if(retval < ce->myaiocb.aio_nbytes)
#endif
        {
            printf("aio_return error4: ret %d %d\n",retval,errno);
#ifdef _LARGEFILE64_SOURCE 
#ifdef __LP64__
            printf("aio_return error4: fd %d offset %lld buffer %lx size %d Opcode %d\n",
                ce->myaiocb.aio_fildes,
                ce->myaiocb.aio_offset,
                (long)(ce->myaiocb.aio_buf),
                ce->myaiocb.aio_nbytes,
                ce->myaiocb.aio_lio_opcode
#else
            printf("aio_return error4: fd %d offset %lld buffer %lx size %d Opcode %d\n",
                ce->myaiocb64.aio_fildes,
                ce->myaiocb64.aio_offset,
                (long)(ce->myaiocb64.aio_buf),
                ce->myaiocb64.aio_nbytes,
                ce->myaiocb64.aio_lio_opcode
#endif
#else
            printf("aio_return error4: fd %d offset %d buffer %lx size %d Opcode %d\n",
                ce->myaiocb.aio_fildes,
                ce->myaiocb.aio_offset,
                (long)(ce->myaiocb.aio_buf),
                ce->myaiocb.aio_nbytes,
                ce->myaiocb.aio_lio_opcode
#endif
                );
        }
        ce->direct=1;
        takeoff_cache(gc,ce); /* do not delete buffer*/
        putoninuse(gc,ce);
    }else
    {
        /*
         * Clear the cache and issue the first request async()
         */
        del_cache(gc);
        del_read++;
        first_ce=alloc_cache(gc,fd,offset,size,(long long)LIO_READ); /* allocate buffer */
        /*printf("allocated buffer/read %x offset %d\n",first_ce->myaiocb.aio_buf,offset);*/
again:
#ifdef _LARGEFILE64_SOURCE 
#ifdef __LP64__
        first_ce->oldbuf=first_ce->myaiocb.aio_buf;
        first_ce->oldfd=first_ce->myaiocb.aio_fildes;
        first_ce->oldsize=first_ce->myaiocb.aio_nbytes;
        ret=aio_read(&first_ce->myaiocb);
#else
        first_ce->oldbuf=first_ce->myaiocb64.aio_buf;
        first_ce->oldfd=first_ce->myaiocb64.aio_fildes;
        first_ce->oldsize=first_ce->myaiocb64.aio_nbytes;
        ret=aio_read64(&first_ce->myaiocb64);
#endif
#else
        first_ce->oldbuf=first_ce->myaiocb.aio_buf;
        first_ce->oldfd=first_ce->myaiocb.aio_fildes;
        first_ce->oldsize=first_ce->myaiocb.aio_nbytes;
        ret=aio_read(&first_ce->myaiocb);
#endif
        if(ret!=0)
        {
            if(errno==EAGAIN)
                goto again;
            else
                printf("error returned from aio_read(). Ret %d errno %d\n",ret,errno);
        }
    }
    if(stride==0)    /* User does not want read-ahead */
        goto out;
    if(a_offset<0)  /* Before beginning of file */
        goto out;
    if(a_offset+size>max)   /* After end of file */
        goto out;
    if(depth >=(max_depth-1))
        depth=max_depth-1;
    if(depth==0)
        goto out;
    if(gc->count > 1)
        start=depth-1;
    for(i=start;i<depth;i++)    /* Issue read-aheads for the depth specified */
    {
        r_offset=a_offset+((i+1)*(stride*a_size));
        if(r_offset<0)
            continue;
        if(r_offset+size > max)
            continue;
        if((ce=incache(gc,fd,r_offset,a_size)))
            continue;
        ce=alloc_cache(gc,fd,r_offset,a_size,(long long)LIO_READ);
#ifdef _LARGEFILE64_SOURCE 
#ifdef __LP64__
        ce->oldbuf=ce->myaiocb.aio_buf;
        ce->oldfd=ce->myaiocb.aio_fildes;
        ce->oldsize=ce->myaiocb.aio_nbytes;
        ret=aio_read(&ce->myaiocb);
#else
        ce->oldbuf=ce->myaiocb64.aio_buf;
        ce->oldfd=ce->myaiocb64.aio_fildes;
        ce->oldsize=ce->myaiocb64.aio_nbytes;
        ret=aio_read64(&ce->myaiocb64);
#endif
#else
        ce->oldbuf=ce->myaiocb.aio_buf;
        ce->oldfd=ce->myaiocb.aio_fildes;
        ce->oldsize=ce->myaiocb.aio_nbytes;
        ret=aio_read(&ce->myaiocb);
#endif
        if(ret!=0)
        {
            takeoff_cache(gc,ce);
            break;
        }
    }           
out:
    if(del_read)    /* Wait for the first read to complete */
    {
#ifdef _LARGEFILE64_SOURCE 
#ifdef __LP64__
        while((ret=aio_error(&first_ce->myaiocb))== EINPROGRESS)
        {
            async_suspend(first_ce);
        }
#else
        while((ret=aio_error64(&first_ce->myaiocb64))== EINPROGRESS)
        {
            async_suspend(first_ce);
        }
#endif
#else
        while((ret=aio_error(&first_ce->myaiocb))== EINPROGRESS)
        {
            async_suspend(first_ce);
        }
#endif
        if(ret)
            printf("aio_error 4: ret %d %d\n",ret,errno);
#ifdef _LARGEFILE64_SOURCE 
#ifdef __LP64__
        if(first_ce->oldbuf != first_ce->myaiocb.aio_buf ||
            first_ce->oldfd != first_ce->myaiocb.aio_fildes ||
            first_ce->oldsize != first_ce->myaiocb.aio_nbytes) 
            printf("It changed in flight2\n");
        retval=aio_return(&first_ce->myaiocb);
#else
        if(first_ce->oldbuf != first_ce->myaiocb64.aio_buf ||
            first_ce->oldfd != first_ce->myaiocb64.aio_fildes ||
            first_ce->oldsize != first_ce->myaiocb64.aio_nbytes) 
            printf("It changed in flight2\n");
        retval=aio_return64(&first_ce->myaiocb64);
#endif
#else
        if(first_ce->oldbuf != first_ce->myaiocb.aio_buf ||
            first_ce->oldfd != first_ce->myaiocb.aio_fildes ||
            first_ce->oldsize != first_ce->myaiocb.aio_nbytes) 
            printf("It changed in flight2\n");
        retval=aio_return(&first_ce->myaiocb);
#endif
#ifdef _LARGEFILE64_SOURCE 
#ifdef __LP64__
        if(retval < first_ce->myaiocb.aio_nbytes)
#else
        if(retval < first_ce->myaiocb64.aio_nbytes)
#endif
#else
        if(retval < first_ce->myaiocb.aio_nbytes)
#endif
        {
            printf("aio_return error5: ret %d %d\n",retval,errno);
#ifdef _LARGEFILE64_SOURCE 
#ifdef __LP64__
            printf("aio_return error5: fd %d offset %lld buffer %lx size %d Opcode %d\n",
                first_ce->myaiocb.aio_fildes,
                first_ce->myaiocb.aio_offset,
                (long)(first_ce->myaiocb.aio_buf),
                first_ce->myaiocb.aio_nbytes,
                first_ce->myaiocb.aio_lio_opcode
#else
            printf("aio_return error5: fd %d offset %lld buffer %lx size %d Opcode %d\n",
                first_ce->myaiocb64.aio_fildes,
                first_ce->myaiocb64.aio_offset,
                (long)(first_ce->myaiocb64.aio_buf),
                first_ce->myaiocb64.aio_nbytes,
                first_ce->myaiocb64.aio_lio_opcode
#endif
#else
            printf("aio_return error5: fd %d offset %ld buffer %lx size %d Opcode %d\n",
                first_ce->myaiocb.aio_fildes,
                first_ce->myaiocb.aio_offset,
                (long)(first_ce->myaiocb.aio_buf),
                first_ce->myaiocb.aio_nbytes,
                first_ce->myaiocb.aio_lio_opcode
#endif
                );
        }
        if(retval > 0)
        {
#ifdef _LARGEFILE64_SOURCE 
#ifdef __LP64__
            *ubuffer=(char *)first_ce->myaiocb.aio_buf;
#else
            *ubuffer=(char *)first_ce->myaiocb64.aio_buf;
#endif
#else
            *ubuffer=(char *)first_ce->myaiocb.aio_buf;
#endif
        }else
            *ubuffer=(char *)0;
        first_ce->direct=1;  /* do not delete the buffer */
        takeoff_cache(gc,first_ce);
        putoninuse(gc,first_ce);
    }
    return((int)retval);    
}

Here is the call graph for this function:

void async_release ( )

Definition at line 19056 of file iozone.c.

{
    printf("Your system does not support async I/O\n");
    exit(173);
}

Here is the call graph for this function:

Here is the caller graph for this function:

void async_release ( struct cache gc)

Definition at line 1155 of file libasync.c.

{
    takeoffinuse(gc);
}

Here is the call graph for this function:

int async_suspend ( )

Here is the caller graph for this function:

int async_suspend ( struct cache_ent ce)

Definition at line 271 of file libasync.c.

{
#ifdef _LARGEFILE64_SOURCE 
#ifdef __LP64__
    const struct aiocb * const cblist[1] = {&ce->myaiocb};
#else
    const struct aiocb64 * const cblist[1] = {&ce->myaiocb64};
#endif
#else
    const struct aiocb * const cblist[1] = {&ce->myaiocb};
#endif

#ifdef _LARGEFILE64_SOURCE 
#ifdef __LP64__
    return aio_suspend(cblist, 1, NULL);
#else
    return aio_suspend64(cblist, 1, NULL);
#endif
#else
    return aio_suspend(cblist, 1, NULL);
#endif
}

Here is the caller graph for this function:

void async_wait_for_write ( struct cache gc)

Definition at line 1421 of file libasync.c.

{
    struct cache_ent *ce;
    size_t ret,retval;
    if(gc->w_head==0)
        return;
    ce=gc->w_head;
    gc->w_head=ce->forward;
    gc->w_count--;
    ce->forward=0;
    if(ce==gc->w_tail)
        gc->w_tail=0;
    /*printf("Wait for buffer %x  offset %lld  size %d to finish\n",
        ce->myaiocb64.aio_buf,
        ce->myaiocb64.aio_offset,
        ce->myaiocb64.aio_nbytes);
    printf("write count %lld \n",gc->w_count);
    */
#ifdef _LARGEFILE64_SOURCE 
#ifdef __LP64__
    while((ret=aio_error(&ce->myaiocb))== EINPROGRESS)
    {
        async_suspend(ce);
    }
#else
    while((ret=aio_error64(&ce->myaiocb64))== EINPROGRESS)
    {
        async_suspend(ce);
    }
#endif
#else
    while((ret=aio_error(&ce->myaiocb))== EINPROGRESS)
    {
        async_suspend(ce);
    }
#endif
    if(ret)
    {
        printf("aio_error 5: ret %d %d\n",ret,errno);
#ifdef _LARGEFILE64_SOURCE 
#ifdef __LP64__
        printf("fd %d offset %lld size %d\n",
            ce->myaiocb.aio_fildes,
            ce->myaiocb.aio_offset,
            ce->myaiocb.aio_nbytes);
#else
        printf("fd %d offset %lld size %d\n",
            ce->myaiocb64.aio_fildes,
            ce->myaiocb64.aio_offset,
            ce->myaiocb64.aio_nbytes);
#endif
#else
        printf("fd %d offset %lld size %d\n",
            ce->myaiocb.aio_fildes,
            ce->myaiocb.aio_offset,
            ce->myaiocb.aio_nbytes);
#endif
        exit(181);
    }

#ifdef _LARGEFILE64_SOURCE 
#ifdef __LP64__
    retval=aio_return(&ce->myaiocb);
#else
#if defined(__CrayX1__)
    retval=aio_return64((aiocb64_t *)&ce->myaiocb64);
#else
    retval=aio_return64((struct aiocb64 *)&ce->myaiocb64);
#endif

#endif
#else
    retval=aio_return(&ce->myaiocb);
#endif
    if((int)retval < 0)
    {
        printf("aio_return error: %d\n",errno);
    }

    if(!ce->direct)
    {
        /* printf("Freeing buffer %x\n",ce->real_address);*/
        free((void *)(ce->real_address));
        free((void *)ce);
    }

}

Here is the call graph for this function:

Definition at line 19038 of file iozone.c.

{
    printf("Your system does not support async I/O\n");
    exit(171);
}

Here is the call graph for this function:

Here is the caller graph for this function:

size_t async_write ( struct cache gc,
long long  fd,
char *  buffer,
long long  size,
off64_t  offset,
long long  depth 
)

Definition at line 1209 of file libasync.c.

{
    struct cache_ent *ce;
    size_t ret;
    ce=allocate_write_buffer(gc,fd,offset,size,(long long)LIO_WRITE,depth,0LL,(char *)0,(char *)0);
    ce->direct=0;    /* not direct. Lib supplies buffer and must free it */
#ifdef _LARGEFILE64_SOURCE 
#ifdef __LP64__
    mbcopy(buffer,(char *)(ce->myaiocb.aio_buf),(size_t)size);
#else
    mbcopy(buffer,(char *)(ce->myaiocb64.aio_buf),(size_t)size);
#endif
#else
    mbcopy(buffer,(char *)(ce->myaiocb.aio_buf),(size_t)size);
#endif
    async_put_on_write_queue(gc,ce);
    /*
    printf("asw: fd %d offset %lld, size %d\n",ce->myaiocb64.aio_fildes,
        ce->myaiocb64.aio_offset,
        ce->myaiocb64.aio_nbytes);
    */  

again:
#ifdef _LARGEFILE64_SOURCE 
#ifdef __LP64__
    ret=aio_write(&ce->myaiocb);
#else
    ret=aio_write64(&ce->myaiocb64);
#endif
#else
    ret=aio_write(&ce->myaiocb);
#endif
    if(ret==-1)
    {
        if(errno==EAGAIN)
        {
            async_wait_for_write(gc);
            goto again;
        }
        if(errno==0)
        {
            /* Compensate for bug in async library */
            async_wait_for_write(gc);
            goto again;
        }
        else
        {
            printf("Error in aio_write: ret %d errno %d count %lld\n",ret,errno,gc->w_count);
            /*
            printf("aio_write_no_copy: fd %d buffer %x offset %lld size %d\n",
                ce->myaiocb64.aio_fildes,
                ce->myaiocb64.aio_buf,
                ce->myaiocb64.aio_offset,
                ce->myaiocb64.aio_nbytes);
            */
            exit(177);
        }
    } 
    return((ssize_t)size);
}

Here is the call graph for this function:

Here is the caller graph for this function:

void async_write_finish ( struct cache gc)

Definition at line 1406 of file libasync.c.

{
    while(gc->w_head)
    {
        /*printf("async_write_finish: Waiting for buffer %x to finish\n",gc->w_head->myaiocb64.aio_buf);*/
        async_wait_for_write(gc);
    }
}

Here is the call graph for this function:

size_t async_write_no_copy ( struct cache gc,
long long  fd,
char *  buffer,
long long  size,
off64_t  offset,
long long  depth,
char *  free_addr 
)

Definition at line 1521 of file libasync.c.

{
    struct cache_ent *ce;
    size_t ret;
    long long direct = 1;
    ce=allocate_write_buffer(gc,fd,offset,size,(long long)LIO_WRITE,depth,direct,buffer,free_addr);
    ce->direct=0;   /* have library de-allocate the buffer */
    async_put_on_write_queue(gc,ce);
    /*
    printf("awnc: fd %d offset %lld, size %d\n",ce->myaiocb64.aio_fildes,
        ce->myaiocb64.aio_offset,
        ce->myaiocb64.aio_nbytes);
    */

again:
#ifdef _LARGEFILE64_SOURCE 
#ifdef __LP64__
    ret=aio_write(&ce->myaiocb);
#else
    ret=aio_write64(&ce->myaiocb64);
#endif
#else
    ret=aio_write(&ce->myaiocb);
#endif
    if(ret==-1)
    {
        if(errno==EAGAIN)
        {
            async_wait_for_write(gc);
            goto again;
        }
        if(errno==0)
        {
            /* Compensate for bug in async library */
            async_wait_for_write(gc);
            goto again;
        }
        else
        {
            printf("Error in aio_write: ret %d errno %d\n",ret,errno);
#ifdef _LARGEFILE64_SOURCE 
#ifdef __LP64__
            printf("aio_write_no_copy: fd %d buffer %lx offset %lld size %d\n",
                ce->myaiocb.aio_fildes,
                (long)(ce->myaiocb.aio_buf),
                ce->myaiocb.aio_offset,
                ce->myaiocb.aio_nbytes);
#else
            printf("aio_write_no_copy: fd %d buffer %lx offset %lld size %d\n",
                ce->myaiocb64.aio_fildes,
                (long)(ce->myaiocb64.aio_buf),
                ce->myaiocb64.aio_offset,
                ce->myaiocb64.aio_nbytes);
#endif
#else
            printf("aio_write_no_copy: fd %d buffer %lx offset %ld size %d\n",
                ce->myaiocb.aio_fildes,
                (long)(ce->myaiocb.aio_buf),
                ce->myaiocb.aio_offset,
                ce->myaiocb.aio_nbytes);
#endif
            exit(182);
        }
    } 
    else    
    {
        return((ssize_t)size);
    }
}

Here is the call graph for this function:

void del_cache ( )

Here is the caller graph for this function:

void del_cache ( struct cache gc)

Definition at line 796 of file libasync.c.

{
    struct cache_ent *ce;
    ssize_t ret;
    ce=gc->head;
    while(1)
    {
        ce=gc->head;
        if(ce==0)
            return;
#ifdef _LARGEFILE64_SOURCE 
#ifdef __LP64__
        while((ret = aio_cancel(0,&ce->myaiocb))==AIO_NOTCANCELED)
#else
        while((ret = aio_cancel64(0,&ce->myaiocb64))==AIO_NOTCANCELED)
#endif
#else
        while((ret = aio_cancel(0,&ce->myaiocb))==AIO_NOTCANCELED)
#endif
            ; 

#ifdef _LARGEFILE64_SOURCE 
#ifdef __LP64__
        ret = aio_return(&ce->myaiocb);
#else
        ret = aio_return64(&ce->myaiocb64);
#endif
#else
        ret = aio_return(&ce->myaiocb);
#endif
        ce->direct=0;
        takeoff_cache(gc,ce);     /* remove from cache */
    }
}

Here is the call graph for this function:

void end_async ( )

Here is the caller graph for this function:

void end_async ( struct cache gc)

Definition at line 259 of file libasync.c.

{
    del_cache(gc);
    async_write_finish(gc);
    free((void *)gc);
}

Here is the call graph for this function:

struct cache_ent* incache ( ) [read]

Here is the caller graph for this function:

struct cache_ent* incache ( struct cache gc,
long long  fd,
off64_t  offset,
long long  size 
) [read]

Definition at line 679 of file libasync.c.

{
    struct cache_ent *move;
    if(gc->head==0)
    {
        return(0);
    }
    move=gc->head;
#ifdef _LARGEFILE64_SOURCE 
#ifdef __LP64__
    while(move)
    {
        if((move->fd == fd) && (move->myaiocb.aio_offset==(off64_t)offset) &&
            ((size_t)size==move->myaiocb.aio_nbytes))
            {
                return(move);
            }
        move=move->forward;
    }
#else
    while(move)
    {
        if((move->fd == fd) && (move->myaiocb64.aio_offset==(off64_t)offset) &&
            ((size_t)size==move->myaiocb64.aio_nbytes))
            {
                return(move);
            }
        move=move->forward;
    }
#endif
#else
    while(move)
    {
        if((move->fd == fd) && (move->myaiocb.aio_offset==(off_t)offset) &&
            ((size_t)size==move->myaiocb.aio_nbytes))
            {
                return(move);
            }
        move=move->forward;
    }
#endif
    return(0);
}
void mbcopy ( char *  source,
char *  dest,
size_t  len 
)

Definition at line 1597 of file libasync.c.

{
    int i;
    for(i=0;i<len;i++)
        *dest++=*source++;
}

Here is the caller graph for this function:

void putoninuse ( )

Here is the caller graph for this function:

void putoninuse ( struct cache gc,
struct cache_ent entry 
)

Definition at line 1168 of file libasync.c.

{
    if(gc->inuse_head)
        entry->forward=gc->inuse_head;
    else
        entry->forward=0;
    gc->inuse_head=entry;
}
void takeoff_cache ( )

Here is the caller graph for this function:

void takeoff_cache ( struct cache gc,
struct cache_ent ce 
)

Definition at line 732 of file libasync.c.

{
    struct cache_ent *move;
    long long found;
    move=gc->head;
    if(move==ce) /* Head of list */
    {

        gc->head=ce->forward;
        if(gc->head)
            gc->head->back=0;
        else
            gc->tail = 0;
        if(!ce->direct)
        {
            free((void *)(ce->real_address));
            free((void *)ce);
        }
        gc->count--;
        return;
    }
    found=0;
    while(move)
    {
        if(move==ce)
        {
            if(move->forward)
            {
                move->forward->back=move->back;
            }
            if(move->back)
            {
                move->back->forward=move->forward;
            }
            found=1;
            break;
        }
        else
        {
            move=move->forward;
        }
    }
    if(gc->head == ce)
        gc->tail = ce;
    if(!found)
        printf("Internal Error in takeoff cache\n");
    move=gc->head;
    if(!ce->direct)
    {
        free((void *)(ce->real_address));
        free((void *)ce);
    }
    gc->count--;
}
void takeoffinuse ( )

Here is the caller graph for this function:

void takeoffinuse ( struct cache gc)

Definition at line 1184 of file libasync.c.

{
    struct cache_ent *ce;
    if(gc->inuse_head==0)
        printf("Takeoffinuse error\n");
    ce=gc->inuse_head;
    gc->inuse_head=gc->inuse_head->forward;
    
    if(gc->inuse_head !=0)
        printf("Error in take off inuse\n");
    free((void*)(ce->real_address));
    free(ce);
}

Variable Documentation

int errno
long long max_depth

Definition at line 192 of file libasync.c.

int one
long long page_size

Definition at line 428 of file iozone.c.

char version[] = "Libasync Version $Revision$"

Definition at line 153 of file libasync.c.

 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines