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

📄 libasync.c

📁 硬盘速度测试 linux下 源码 c/c
💻 C
📖 第 1 页 / 共 3 页
字号:
		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);	}/************************************************************************ * This routine allocates a cache_entry. It contains the  * aiocb block as well as linkage for use in the cache mechanism. * The space allocated here will be released after the cache entry * has been consumed. The routine takeoff_cache() will be called * after the data has been copied to user buffer or when the * cache is purged. The routine takeoff_cache() will also release * all memory associated with this cache entry. ************************************************************************/struct cache_ent *alloc_cache(gc,fd,offset,size,op)struct cache *gc;long long fd,size,op;off64_t offset;{	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);}/************************************************************************ * This routine checks to see if the requested data is in the * cache. *************************************************************************/struct cache_ent *incache(gc,fd,offset,size)struct cache *gc;long long fd,size;off64_t offset;{	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);}/************************************************************************ * This routine removes a specific cache entry from the cache, and * releases all memory associated witht the cache entry (if not direct).*************************************************************************/voidtakeoff_cache(gc,ce)struct cache *gc;struct cache_ent *ce;{	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--;}/************************************************************************ * This routine is used to purge the entire cache. This is called when * the cache contains data but the incomming read was not able to  * be satisfied from the cache. This indicates that the previous * async read-ahead was not correct and a new pattern is emerging.  ************************************************************************/voiddel_cache(gc)struct cache *gc;{	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 */	}}/************************************************************************ * Like its sister async_read() this function performs async I/O for  * all buffers but it differs in that it expects the caller to  * request a pointer to the data to be returned instead of handing * the function a location to put the data. This will allow the * async I/O to be performed and does not require any bcopy to be * done to put the data back into the location specified by the caller. ************************************************************************/intasync_read_no_copy(gc, fd, ubuffer, offset, size, stride, max, depth)struct cache *gc;long long fd;char **ubuffer;off64_t offset;long long size;long long stride;off64_t max;long long depth;{	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);

⌨️ 快捷键说明

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