static int issue_aio_calls (void) { // Setup AIOCB. aiocb1.aio_fildes = file_handle; aiocb1.aio_offset = 0; aiocb1.aio_buf = mb1.wr_ptr (); aiocb1.aio_nbytes = BUFSIZ; aiocb1.aio_reqprio = 0; aiocb1.aio_sigevent.sigev_notify = SIGEV_SIGNAL; aiocb1.aio_sigevent.sigev_signo = SIGRTMIN; aiocb1.aio_sigevent.sigev_value.sival_ptr = (void *) &aiocb1; // Fire off the aio read. if (aio_read (&aiocb1) == -1) // Queueing failed. ACE_ERROR_RETURN ((LM_ERROR, "Error: %p\n", "Asynch_Read_Stream: aio_read queueing failed"), -1); // Setup AIOCB. aiocb2.aio_fildes = file_handle; aiocb2.aio_offset = BUFSIZ + 1; aiocb2.aio_buf = mb2.wr_ptr (); aiocb2.aio_nbytes = BUFSIZ; aiocb2.aio_reqprio = 0; aiocb2.aio_sigevent.sigev_notify = SIGEV_SIGNAL; aiocb2.aio_sigevent.sigev_signo = SIGRTMIN; aiocb2.aio_sigevent.sigev_value.sival_ptr = (void *) &aiocb2; // Fire off the aio read. if (aio_read (&aiocb2) == -1) // Queueing failed. ACE_ERROR_RETURN ((LM_ERROR, "Error: %p\n", "Asynch_Read_Stream: aio_read queueing failed"), -1); // Setup sigval. aiocb3.aio_fildes = ACE_INVALID_HANDLE; aiocb3.aio_offset = 0; aiocb3.aio_buf = 0; aiocb3.aio_nbytes = 0; aiocb3.aio_reqprio = 0; aiocb3.aio_sigevent.sigev_notify = SIGEV_SIGNAL; aiocb3.aio_sigevent.sigev_signo = SIGRTMIN; aiocb3.aio_sigevent.sigev_value.sival_ptr = (void *) &aiocb3; sigval value; value.sival_ptr = reinterpret_cast<void *> (&aiocb3); // Queue this one for completion right now. if (sigqueue (ACE_OS::getpid (), SIGRTMIN, value) == -1) // Queueing failed. ACE_ERROR_RETURN ((LM_ERROR, "Error: %p\n", "sigqueue"), -1); return 0; }
void char_ready_handler(int signo, siginfo_t* siginfo, void *dummy) { char answer; Tmeas *temp = (Tmeas*)(((struct aiocb*)siginfo->si_value.sival_ptr)->aio_buf); int ptemp = ((struct aiocb*)siginfo->si_value.sival_ptr) - &aiocb[0]; int intemp = (int)(((struct aiocb*)siginfo->si_value.sival_ptr)->aio_fildes); if (aio_error(((struct aiocb*)siginfo->si_value.sival_ptr)) != 0) printf("ERROR\n"); if( signo == SIGIO ) { /* printf("i/o complete signal is received. Char was %d \n", *((struct Tmeas*)(((struct aiocb*)siginfo->si_value.sival_ptr)->aio_buf)))->value; //start a new read*/ clock_gettime(CLOCK_REALTIME, ¤t_time); lag = diff_timespec(¤t_time, &temp->moment ); printf("# Measurement value of %d sensor is %d, it took %d\n", ptemp+1, temp->value, lag.tv_nsec); increment_timespec(&total_lag, &lag); if (aio_return(((struct aiocb*)siginfo->si_value.sival_ptr)) > 0 ) aio_read(((struct aiocb*)siginfo->si_value.sival_ptr)); else printf("-------------EOF in sensor #%d, %d remaining--------------------\n", ptemp+1, --NSENS); } }
int main(int argc, char *argv[]) { tty_mode(0); set_cr_noecho_mode(); initscr(); clear(); signal(SIGINT, sigint_handler); signal(SIGIO, on_input); /* install input handler */ setup_aio_buffer(); /* initialize aio ctrl buff */ aio_read(&kbcbuf); /* place a read request */ signal(SIGALRM, on_alarm); /* install alarm handler */ set_ticker(delay); /* start ticking */ move(row, col); addstr(MSG); while (!done) { pause(); } tty_mode(1); endwin(); return 0; }
int test_aio() { int ret; struct aiocb cb, *pcb = &cb; char buf[100] = ""; cb.aio_fildes = STDIN_FILENO; cb.aio_offset = 0; cb.aio_buf = buf; cb.aio_nbytes = 10; cb.aio_reqprio = 0; cb.aio_sigevent.sigev_notify = SIGEV_NONE; ret = aio_read(&cb); if (ret < 0) err_sys("aio_read"); for (;;) { ret = aio_suspend(&pcb, 1, NULL); if (ret != 0) { if (ret == -1) { if (errno != EINTR) err_sys("aio_error"); else continue; } } ret = aio_return(&cb); printf("read %d bytes, buf: %s\n", ret, buf); break; } return 0; }
// gcc 5_async.c -o async -lrt 비동기 io를 하려면 rt라이브러리와 링크해야 함 int main() { int fd = open("file.txt", O_RDONLY); // 비동기 io를 위한 작업들 struct aiocb myaiocb; // = {0}; // async io control block memset (&myaiocb, 0, sizeof(myaiocb)); myaiocb.aio_buf = malloc(sizeof(char)*10); // 읽어올 버퍼(힙에 할당해야 한다) myaiocb.aio_fildes = fd; // 파일 번호 myaiocb.aio_nbytes = 10; // 버퍼 크기 myaiocb.aio_offset = 0; // 파일 offset int ret = aio_read(&myaiocb); // 비동기 읽기 요청 printf("비동기 읽기 시작 : %d\n", ret); // 비동기 작업이 종료되는것을 대기한다. struct aiocb* aio_list[1]; memset( aio_list, 0, sizeof(aio_list)); aio_list[0] = &myaiocb; ret = aio_suspend( aio_list, 1, 0); printf("ret : %d \n" , ret); // 비동기 작업의 결과를 얻어온다. ret = aio_return(&myaiocb); printf("ret : %d\n", ret); printf("buff: %s \n", myaiocb.aio_buf); }
static struct aiocb *wrapper_aio(int fd, volatile char *buf, size_t bytes, off_t offset, int opcode) { struct aiocb *cb = (struct aiocb *)malloc(sizeof(struct aiocb)); if (cb == NULL) return NULL; memset(cb, 0, sizeof(struct aiocb)); cb->aio_nbytes = bytes; cb->aio_fildes = fd; cb->aio_offset = offset; cb->aio_buf = buf; int ret; switch (opcode) { case WORMUP_READ: if ((ret = aio_read(cb)) == -1) { free(cb); return NULL; } break; case WORMUP_WRITE: if ((ret = aio_write(cb)) == -1) { free(cb); return NULL; } break; default: return NULL; } return cb; }
static void handle_aio_events(struct fs_mount *mount) { int fd, ret, count, i, notify; evtchn_port_t port; /* AIO control block for the evtchn file destriptor */ struct aiocb evtchn_cb; const struct aiocb * cb_list[mount->nr_entries]; int request_ids[mount->nr_entries]; /* Prepare the AIO control block for evtchn */ fd = xc_evtchn_fd(mount->evth); bzero(&evtchn_cb, sizeof(struct aiocb)); evtchn_cb.aio_fildes = fd; evtchn_cb.aio_nbytes = sizeof(port); evtchn_cb.aio_buf = &port; assert(aio_read(&evtchn_cb) == 0); wait_again: /* Create list of active AIO requests */ count = 0; for(i=0; i<mount->nr_entries; i++) if(mount->requests[i].active) { cb_list[count] = &mount->requests[i].aiocb; request_ids[count] = i; count++; } /* Add the event channel at the end of the list. Event channel needs to be * handled last as it exits this function. */ cb_list[count] = &evtchn_cb; request_ids[count] = -1; count++; /* Block till an AIO requset finishes, or we get an event */ while(1) { int ret = aio_suspend(cb_list, count, NULL); if (!ret) break; assert(errno == EINTR); } for(i=0; i<count; i++) if(aio_error(cb_list[i]) != EINPROGRESS) { if(request_ids[i] >= 0) dispatch_response(mount, request_ids[i]); else goto read_event_channel; } RING_PUSH_RESPONSES_AND_CHECK_NOTIFY(&mount->ring, notify); printf("Pushed responces and notify=%d\n", notify); if(notify) xc_evtchn_notify(mount->evth, mount->local_evtchn); goto wait_again; read_event_channel: assert(aio_return(&evtchn_cb) == sizeof(evtchn_port_t)); assert(xc_evtchn_unmask(mount->evth, mount->local_evtchn) >= 0); }
int main(void) { struct aiocb cb; char sbuf[100]; int ret; struct sigaction act; sigemptyset(&act.sa_mask); act.sa_flags = SA_RESTART | SA_SIGINFO; act.sa_sigaction = async_read; sigaction(SIGUSR1, &act, NULL); bzero(&cb, sizeof(cb)); cb.aio_fildes = 0; cb.aio_buf = sbuf; cb.aio_nbytes = 100; cb.aio_offset = 0; cb.aio_sigevent.sigev_value.sival_ptr = &cb; cb.aio_sigevent.sigev_notify = SIGEV_SIGNAL; cb.aio_sigevent.sigev_signo = SIGUSR1; ret = aio_read(&cb); if (ret == -1) { perror("aio_read"); exit(1); } while (1) { sleep(3); } return 0; }
int main() { int fd = open("file.txt", O_RDONLY); struct aiocb myaiocb; memset (&myaiocb, 0, sizeof(myaiocb)); myaiocb.aio_buf = malloc(sizeof(char)*10); myaiocb.aio_fildes = fd; // 파일 번호 myaiocb.aio_nbytes = 10; // 버퍼 크기 myaiocb.aio_offset = 0; // 파일 offset // 비동기 작업이 마무리 되면 호출될 함수를 지정한다. myaiocb.aio_sigevent.sigev_notify = SIGEV_THREAD; myaiocb.aio_sigevent.sigev_notify_function = foo; myaiocb.aio_sigevent.sigev_notify_attributes = 0; myaiocb.aio_sigevent.sigev_value.sival_ptr = &myaiocb; int ret = aio_read(&myaiocb); // 비동기 읽기 요청 printf("비동기 읽기 시작 : %d\n", ret); while(1); // 다른작업 }
Status Issue(aiocb& cb, size_t queueDepth) { #if CONFIG2_FILE_ENABLE_AIO if(queueDepth > 1) { const int ret = (cb.aio_lio_opcode == LIO_WRITE)? aio_write(&cb): aio_read(&cb); if(ret != 0) WARN_RETURN(StatusFromErrno()); } else #else UNUSED2(queueDepth); #endif { ENSURE(lseek(cb.aio_fildes, cb.aio_offset, SEEK_SET) == cb.aio_offset); void* buf = (void*)cb.aio_buf; // cast from volatile void* const ssize_t bytesTransferred = (cb.aio_lio_opcode == LIO_WRITE)? write(cb.aio_fildes, buf, cb.aio_nbytes) : read(cb.aio_fildes, buf, cb.aio_nbytes); if(bytesTransferred < 0) WARN_RETURN(StatusFromErrno()); cb.aio_nbytes = (size_t)bytesTransferred; } return INFO::OK; }
static int bs_paio_cmd_submit(struct scsi_cmd *cmd) { struct scsi_lu *lu = cmd->dev; struct aiocb *io=NULL; int ret = 0; switch (cmd->scb[0]) { case SYNCHRONIZE_CACHE: case SYNCHRONIZE_CACHE_16: break; case WRITE_6: case WRITE_10: case WRITE_12: case WRITE_16: io=calloc(1, sizeof(*io)+sizeof(cmd)); io->aio_fildes=lu->fd; io->aio_buf=scsi_get_out_buffer(cmd); io->aio_offset=cmd->offset; io->aio_nbytes=scsi_get_out_length(cmd); io->aio_sigevent.sigev_notify=SIGEV_THREAD; io->aio_sigevent.sigev_notify_function=paio_done; io->aio_sigevent.sigev_notify_attributes=NULL; io->aio_sigevent.sigev_value.sival_ptr=io; *(struct scsi_cmd **)(io+1)=cmd; ret=aio_write(io); if(ret==0){ set_cmd_async(cmd); return 0; } break; case READ_6: case READ_10: case READ_12: case READ_16: io=calloc(1, sizeof(*io)+sizeof(cmd)); io->aio_fildes=lu->fd; io->aio_buf=scsi_get_in_buffer(cmd); io->aio_offset=cmd->offset; io->aio_nbytes=scsi_get_in_length(cmd); io->aio_sigevent.sigev_notify=SIGEV_THREAD; io->aio_sigevent.sigev_notify_function=paio_done; io->aio_sigevent.sigev_notify_attributes=NULL; io->aio_sigevent.sigev_value.sival_ptr=io; *(struct scsi_cmd **)(io+1)=cmd; ret=aio_read(io); if(ret==0){ set_cmd_async(cmd); return 0; } break; default: break; } if(ret!=0){ sense_data_build(cmd, MEDIUM_ERROR, 0); ret = SAM_STAT_CHECK_CONDITION; } return ret; }
ssize_t read(client_ctx_ptr ctx, const std::string &filename, void *buf, size_t nbytes, off_t offset) { ssize_t r; giocb aio; aio.aio_buf = buf; aio.aio_nbytes = nbytes; aio.aio_offset = offset; if (ctx == nullptr) { errno = EINVAL; return (r = -1); } if ((r = aio_read(ctx, filename, &aio)) < 0) { return r; } r = aio_suspend(ctx, &aio, nullptr); if (r == 0) { r = aio_return(ctx, &aio); } aio_finish(ctx, &aio); return r; }
int lio_listio(int mode, struct aiocb *const apv[], int nent, struct sigevent *sigevp) { int i; #ifndef notyet if (sigevp && (sigevp->sigev_notify != SIGEV_NONE) && (sigevp->sigev_notify != SIGEV_THREAD)) return (ENOSYS); #endif for (i = 0; i < nent; i++) switch (apv[i]->aio_lio_opcode) { case LIO_READ: aio_read(apv[i]); break; case LIO_WRITE: aio_write(apv[i]); break; case LIO_NOP: break; } if (sigevp && (mode == LIO_NOWAIT) ) { _aio_notify(sigevp); } return (0); }
ssize_t read_wrap(int fd, void* buf, size_t count){ struct aiocb* my_aiocb = malloc(sizeof(struct aiocb)); memset(my_aiocb, 0, sizeof(struct aiocb)); // set up aiocb vars my_aiocb->aio_fildes = fd; if(my_aiocb->aio_fildes == -1) return -1; else if(my_aiocb->aio_fildes == 0) my_aiocb->aio_offset = 0; else my_aiocb->aio_offset = lseek(fd, 0, SEEK_CUR); my_aiocb->aio_buf = buf; my_aiocb->aio_nbytes = count; my_aiocb->aio_sigevent.sigev_notify = SIGEV_NONE; // start to read int read_return = aio_read(my_aiocb); while(aio_error(my_aiocb) == EINPROGRESS){ yield(); } int value_return = aio_return(my_aiocb); if(value_return >= 0) my_aiocb->aio_offset = lseek(fd, my_aiocb->aio_offset + value_return , SEEK_SET); return value_return; }
int main(int argc, char * argv[]) { struct aiocb rd; int fd, ret, counter; fd = open("/dev/vdb", O_RDWR); if(fd < 0) { perror("/dev/vdb"); } bzero(&rd, sizeof(rd)); rd.aio_buf = malloc(BUFFER_SIZE + 1); rd.aio_fildes = fd; rd.aio_nbytes = BUFFER_SIZE; rd.aio_offset = 0; ret = aio_read(&rd); if(ret < 0) { perror("aio_read"); exit(1); } counter = 0; #if 0 while(aio_error(&rd)== EINPROGRESS) { printf("第%d次\n", ++counter); } #endif ret = aio_return(&rd); printf("\n\n 返回值为:%d\n",ret); return 0; }
int main(int argc, char *argv[]) { int fd = 0; struct aiocb aiocb = {0}; if (argc != 2) { fprintf(stderr, "Usage: ./a.out filename1 filename2 ...\n"); return EXIT_FAILURE; } register_signal(SIGIO); fd = open(argv[1], O_RDONLY); if (fd < 0) { fprintf(stderr, "open failure\n"); return EXIT_FAILURE; } aiocb.aio_fildes = fd; aiocb.aio_buf = (volatile void *)malloc(BUFSIZ+1); aiocb.aio_nbytes = BUFSIZ; aiocb.aio_sigevent.sigev_notify = SIGEV_SIGNAL; aiocb.aio_sigevent.sigev_signo = SIGIO; aiocb.aio_sigevent.sigev_value.sival_ptr = &aiocb; memset((void *)aiocb.aio_buf, 0, BUFSIZ+1); aiocb.aio_offset = offset; aio_read(&aiocb); sleep(1); return EXIT_SUCCESS; }
int main(int argc,char **argv) { int fd,ret; struct aiocb rd; fd = open("test.txt",O_RDONLY); if(fd < 0) { perror("test.txt"); } bzero(&rd,sizeof(rd)); rd.aio_fildes = fd; rd.aio_buf = (char *)malloc(sizeof(BUFFER_SIZE + 1)); rd.aio_nbytes = BUFFER_SIZE; rd.aio_offset = 0; rd.aio_sigevent.sigev_notify = SIGEV_THREAD;//使用线程回调通知 rd.aio_sigevent.sigev_notify_function = aio_completion_handler;//设置回调函数 rd.aio_sigevent.sigev_notify_attributes = NULL;//使用默认属性 rd.aio_sigevent.sigev_value.sival_ptr = &rd;//在aiocb控制块中加入自己的引用 ret = aio_read(&rd); if(ret < 0) { perror("aio_read"); } printf("异步读以开始\n"); sleep(1); printf("异步读结束\n"); return 0; }
int aioperf_aio_read(aioperf_io_task_t *io_task) { aioperf_repository_t *repository = NULL; aioperf_conf_info_t *conf_info = NULL; unsigned long left_size = 0; repository = io_task->repository; conf_info = repository->conf_info; left_size = io_task->file_size - io_task->offset; if (left_size > conf_info->buf_size) { io_task->aio_req.aio_nbytes = conf_info->buf_size; } else { io_task->aio_req.aio_nbytes = left_size; } io_task->aio_req.aio_fildes = io_task->fd; io_task->aio_req.aio_buf = io_task->repository->buf; io_task->aio_req.aio_offset = io_task->offset; io_task->aio_req.aio_sigevent.sigev_notify = SIGEV_THREAD; io_task->aio_req.aio_sigevent.sigev_notify_function = aioperf_aio_callback; io_task->aio_req.aio_sigevent.sigev_notify_attributes = NULL; io_task->aio_req.aio_sigevent.sigev_value.sival_ptr = io_task; if (aio_read(&io_task->aio_req) < 0) { printf("aio write error\n"); return AIOPERF_ERROR; } return AIOPERF_OK; }
static int swAioGcc_aio_read(int fd, void *outbuf, size_t size, off_t offset) { swAio_gcc_t *aiocb = sw_malloc(sizeof(swAio_gcc_t)); if (aiocb == NULL) { swWarn("malloc failed."); return SW_ERR; } bzero(aiocb, sizeof(swAio_gcc_t)); aiocb->next = NULL; if (swAioGcc_request == NULL) { swAioGcc_request = aiocb; } else { swAioGcc_request->next = aiocb; } aiocb->aiocb.aio_fildes = fd; aiocb->aiocb.aio_buf = outbuf; aiocb->aiocb.aio_nbytes = size; aiocb->aiocb.aio_lio_opcode = LIO_READ; aiocb->aiocb.aio_sigevent.sigev_notify = SIGEV_SIGNAL; aiocb->aiocb.aio_sigevent.sigev_signo = SIGIO; if (aio_read(&aiocb->aiocb) < 0) { swWarn("aio_read failed. Error: %s[%d]", strerror(errno), errno); return SW_ERR; } return SW_OK; }
int main(void) { struct aiocb cb; char buf[256] = {0}; int ret; memset(&cb, 0, sizeof(cb)); cb.aio_fildes = 0; cb.aio_nbytes = 256; cb.aio_buf = buf; cb.aio_sigevent.sigev_value.sival_ptr = &cb; cb.aio_sigevent.sigev_notify = SIGEV_THREAD; cb.aio_sigevent.sigev_notify_attributes = NULL; cb.aio_sigevent.sigev_notify_function=async_process; ret = aio_read(&cb); if (-1 == ret) { perror("aio_read"); exit(1); } printf("Aio read task!\n"); while (1) { sleep(1); // printf("I am running!\n"); } return 0; }
int main() { int s; static struct aiocb readrq; static const struct aiocb *readrqv[2]={&readrq, NULL}; char buf[4096]; char buf2[4096]; size_t size; struct sockaddr_in addr; struct hostent *srv; s=socket(PF_INET, SOCK_STREAM, 0); srv=gethostbyname("www.nsu.ru"); addr.sin_family=AF_INET; addr.sin_port=htons(80); if (srv) { addr.sin_addr.s_addr=*((unsigned long*)srv->h_addr); } else { inet_aton("193.124.215.195", &addr.sin_addr); } if (connect(s, (struct sockaddr*)&addr, sizeof addr)) { perror("connecting to server"); exit(1); } memset(&readrq, 0, sizeof readrq); readrq.aio_fildes=s; readrq.aio_buf=buf; readrq.aio_nbytes=sizeof buf; if (aio_read(&readrq)) { perror("aio_read"); exit(1); } write(s, req, (sizeof req)-1); while(1) { aio_suspend(readrqv, 1, NULL); size=aio_return(&readrq); if (size>0) { write(1, buf, size); aio_read(&readrq); } else if (size==0) { break; } else { perror("reading from socket"); } } }
int InputDriverAbstract::readEvents() { ssize_t numBytes; struct aiocb *mAIOCB = (struct aiocb *) mAsyncIOControlBlock; if (0 == mAsyncIOStatus) { memset(mAIOCB, 0, sizeof (*mAIOCB)); mAIOCB->aio_nbytes = mAsyncIOEventBufferSize; mAIOCB->aio_fildes = mFileDescriptor; mAIOCB->aio_offset = 0; mAIOCB->aio_buf = mAsyncIOEventBuffer; if (aio_read(mAIOCB) == -1) { return -1; } } mAsyncIOStatus = aio_error(mAIOCB); switch (mAsyncIOStatus) { case 0: // Всё прочитано, продолжаем... break; case EINPROGRESS: // Ещё не готово return 1; case ECANCELED: // Отменено пользователем return 2; case ENODEV: // Устройство было отключено InputDriverEventDisconnected evDisconnect; evDisconnect.error = ENODEV; gettimeofday(&evDisconnect.time, NULL); fireDisconnetedEventCallback(&evDisconnect); return 2; default: perror("aio_error"); error_printf("aio_error returns %d!\n", mAsyncIOStatus); return -1; } numBytes = aio_return(mAIOCB); if (numBytes < 0) return -1; if ((size_t)numBytes != mAIOCB->aio_nbytes) return -5; mLastInputEventTriggered = false; memset(&mLastInputEvent, 0, sizeof(mLastInputEvent)); int ret = processEvent(); if (ret < 0) { return -1; } if (mLastInputEventTriggered) { fireInputEventCallback(&mLastInputEvent); mLastInputEventTriggered = false; } return 0; }
int main() { char tmpfname[256]; #define BUF_SIZE 111 char buf[BUF_SIZE]; int fd; int ret; struct aiocb aiocb; if (sysconf(_SC_ASYNCHRONOUS_IO) < 200112L) return PTS_UNSUPPORTED; snprintf(tmpfname, sizeof(tmpfname), "/tmp/pts_aio_read_3_1_%d", getpid()); unlink(tmpfname); fd = open(tmpfname, O_CREAT | O_RDWR | O_EXCL, S_IRUSR | S_IWUSR); if (fd == -1) { printf(TNAME " Error at open(): %s\n", strerror(errno)); exit(PTS_UNRESOLVED); } unlink(tmpfname); if (write(fd, buf, BUF_SIZE) != BUF_SIZE) { printf(TNAME " Error at write(): %s\n", strerror(errno)); exit(PTS_UNRESOLVED); } memset(&aiocb, 0, sizeof(struct aiocb)); aiocb.aio_fildes = fd; aiocb.aio_buf = buf; aiocb.aio_nbytes = BUF_SIZE; if (aio_read(&aiocb) == -1) { printf(TNAME " Error at aio_read(): %s\n", strerror(errno)); exit(PTS_FAIL); } /* Wait for request completion */ do { usleep(10000); ret = aio_error(&aiocb); } while (ret == EINPROGRESS); /* error status shall be 0 and return status shall be BUF_SIZE */ if (ret != 0) { printf(TNAME " Error at aio_error()\n"); exit(PTS_FAIL); } if (aio_return(&aiocb) != BUF_SIZE) { printf(TNAME " Error at aio_return()\n"); exit(PTS_FAIL); } close(fd); printf("Test PASSED\n"); return PTS_PASS; }
void sig_hand(int signo) { if(signo == SIGIO) { // We check which read was ready if(aio_error(&aiocb1) != EINPROGRESS) { write(1, &chr1, 1); aio_read(&aiocb1); return; } if(aio_error(&aiocb2) != EINPROGRESS) { write(1, &chr2, 1); aio_read(&aiocb2); return; } } return; }
/* Launch the current matrix read, write, and add procedure */ void matrix_run(int block_size, int scalar, int size){ int curBuffer[block_size], previous[block_size]; int next[block_size]; int offset = 0; //Keep the current file offset int writeOffset = 0, count=0, readOffset = 0; time_t diffTime = time(NULL); //Create the request object struct aiocb* request = malloc(sizeof(struct aiocb)); request->aio_buf = next; request->aio_fildes = 0; request->aio_nbytes = block_size; request->aio_offset = 0; //Create the response object struct aiocb* response = malloc(sizeof(struct aiocb)); response->aio_buf = previous; response->aio_fildes = 1; response->aio_nbytes = block_size; response->aio_offset = 0; //Get the return from the read request do{ memcpy(curBuffer,next,block_size); request->aio_offset = offset; // Set the offset //Create a read request if(aio_read(request)!=0){ //perror("Read Error"); } //Change the offsets offset = offset + readOffset; matrix_add(curBuffer,block_size,scalar,previous); //Write the results currently stored to a file response->aio_offset = writeOffset; response->aio_nbytes = readOffset; aio_write(response); while(aio_error(response)==EINPROGRESS); aio_return(response); writeOffset= writeOffset + readOffset; //Wait for progress //while(aio_error(request)==EINPROGRESS); readOffset= aio_return(request); }while(readOffset>0 && offset<=size); //Print end time diffTime = time(NULL)-diffTime; fprintf(stderr,"Time Difference: %d\n",(int)diffTime); }
Promise<ssize_t> readAsync(int fd, boost::shared_array<char> buffer, size_t length, off_t offset) { CompleteData *crData = new CompleteData(fd, buffer, length, offset); if(0 == aio_read(&crData->m_aiocb)) { return crData->promise(); } delete crData; return false; }
int main(){ int fd, ret; struct aiocb my_aiocb; fd = open( "file.txt", O_RDONLY ); if (fd < 0) perror("open"); struct sigaction sig_act; sigemptyset(&sig_act.sa_mask); sig_act.sa_flags = SA_SIGINFO; sig_act.sa_sigaction = aio_completion_handler; /* Zero out the aiocb structure (recommended) */ bzero( (char *)&my_aiocb, sizeof(struct aiocb) ); /* Allocate a data buffer for the aiocb request */ my_aiocb.aio_buf = malloc(BUFSIZE+1); if (!my_aiocb.aio_buf) perror("malloc"); /* Initialize the necessary fields in the aiocb */ my_aiocb.aio_fildes = fd; my_aiocb.aio_nbytes = BUFSIZE; my_aiocb.aio_offset = 0; my_aiocb.aio_sigevent.sigev_notify = SIGEV_SIGNAL; my_aiocb.aio_sigevent.sigev_signo = SIGIO; my_aiocb.aio_sigevent.sigev_value.sival_ptr = &my_aiocb; ret = sigaction( SIGIO, &sig_act, NULL ); if( ret ){ perror("sigaction"); } aio_read( &my_aiocb ); // if( ret == 0 ){ // printf("EOF\n"); // printf("Total read %zd bytes\n", total); // } // else{ // perror("aio_read2"); // } const struct aiocb *const cblist[1] = { &my_aiocb }; while(1){ aio_suspend( cblist, 1, NULL ); if( done ){ break; } } return 0; }
static int queue_rx(int fd, void *buf, size_t len) { memset(&rxaio, 0, sizeof(rxaio)); rxaio.aio_fildes = fd; rxaio.aio_buf = buf; rxaio.aio_nbytes = len; rxaio.aio_offset = 0; return aio_read(&rxaio); }
int main() { int ret; ///1 使用 aio_read 需要初始化 aiocb struct aiocb my_aiocb; bzero(&my_aiocb, sizeof my_aiocb); // allocate data buf my_aiocb.aio_buf = malloc(AIO_BUF_SIZE+1); if (my_aiocb.aio_buf == NULL) perror("malloc failed"); // initialize the necessary fields // 每次读不会超过 buf 的大小 my_aiocb.aio_nbytes = AIO_BUF_SIZE; int fd ; EV_TEST(-1, fd, open("README.md", O_RDONLY)); my_aiocb.aio_fildes = fd; /// EE 设置读取的偏移量 read的时候 偏移量是在fd中维护的 //但在异步情况下要为每次读操作都指定偏移量 //aio_read 后kernel不会改变aio_offset 的值 my_aiocb.aio_offset = 0; next: E_TEST(-1, aio_read(&my_aiocb)); ///EE 使用 aio_error 来查询aiocb的状态 //如果是 EINPROGRESS //就一直忙等待,直到状态发生变化为止 while (aio_error(&my_aiocb) == EINPROGRESS) { printf("aio_error is EINPROGRESS\n"); } if ((ret = aio_return(&my_aiocb)) > 0) { // read ret B data printf("aio_return :%d\n", ret); ((char*)my_aiocb.aio_buf)[ret] = '\0'; printf("%s\n", (char*)my_aiocb.aio_buf); //updata aio_offset for next read my_aiocb.aio_offset += ret; goto next; } else if ( ret == 0) { printf("aio_return :%d\n", ret); //read EOF } else { printf("aio_return :%d\n", ret); perror("aio_return failed"); //error occued } E_TEST(-1, close(fd)); return 0; }
void double_buffering_read( double_buffering *b, which_buffer wh_buff, size_t nbytes, off_t offset ) { // Buffer aiocb_list *buff = wh_buff == IO_BUFF ? b->io_l : b->comp_l; // Number of chunks to read int chunks_to_read = size_t_ceil( nbytes, (size_t)MAX_AIO_SIZE ); #if DEBUG printf("Reading %d chunks\n", chunks_to_read); fflush(stdout); #endif int i; struct aiocb *tmp_cb; // First n-1 chunks are full ( MAX_AIO_SIZE ) for ( i = 0; i < chunks_to_read - 1; i++ ) { tmp_cb = (struct aiocb *)buff->aiocb_l[i]; // fildes and buffer already set up in the initialization tmp_cb->aio_nbytes = (size_t)MAX_AIO_SIZE; tmp_cb->aio_offset = offset + (i * (off_t)MAX_AIO_SIZE); if ( aio_read( tmp_cb ) != 0 ) { perror("[ERROR] Enqueuing aio_read request"); exit( EXIT_FAILURE ); } } if (chunks_to_read) { i = chunks_to_read - 1; tmp_cb = (struct aiocb *)buff->aiocb_l[i]; tmp_cb->aio_nbytes = nbytes - (i * (size_t)MAX_AIO_SIZE); tmp_cb->aio_offset = offset + (i * (off_t)MAX_AIO_SIZE); if ( aio_read( tmp_cb ) != 0 ) { perror("[ERROR] Enqueuing aio_read request"); exit( EXIT_FAILURE ); } } buff->issued = chunks_to_read; }