int ADIOI_TESTFS_WriteDone(ADIO_Request *request, ADIO_Status *status, int *error_code) { int myrank, nprocs; *error_code = MPI_SUCCESS; if (*request == ADIO_REQUEST_NULL) { FPRINTF(stdout, "[%d/%d] ADIOI_TESTFS_WriteDone called on ADIO_REQUEST_NULL\n", myrank, nprocs); return 1; } MPI_Comm_size((*request)->fd->comm, &nprocs); MPI_Comm_rank((*request)->fd->comm, &myrank); FPRINTF(stdout, "[%d/%d] ADIOI_TESTFS_WriteDone called on %s\n", myrank, nprocs, (*request)->fd->filename); #ifdef HAVE_STATUS_SET_BYTES MPIR_Status_set_bytes(status, (*request)->datatype, (*request)->nbytes); #endif (*request)->fd->async_count--; ADIOI_Free_request((ADIOI_Req_node *) (*request)); *request = ADIO_REQUEST_NULL; return 1; }
void ADIOI_XFS_ReadComplete(ADIO_Request *request, ADIO_Status *status, int *error_code) { int err; static char myname[] = "ADIOI_XFS_READCOMPLETE"; if (*request == ADIO_REQUEST_NULL) { *error_code = MPI_SUCCESS; return; } if ((*request)->queued) { do { err = aio_suspend64((const aiocb64_t **) &((*request)->handle), 1, 0); } while ((err == -1) && (errno == EINTR)); if (err != -1) { err = aio_return64((aiocb64_t *) (*request)->handle); (*request)->nbytes = err; errno = aio_error64((aiocb64_t *) (*request)->handle); } else (*request)->nbytes = -1; if (err == -1) { *error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, myname, __LINE__, MPI_ERR_IO, "**io", "**io %s", strerror(errno)); } else *error_code = MPI_SUCCESS; } /* if ((*request)->queued) */ else *error_code = MPI_SUCCESS; #ifdef HAVE_STATUS_SET_BYTES if ((*request)->nbytes != -1) MPIR_Status_set_bytes(status, (*request)->datatype, (*request)->nbytes); #endif if ((*request)->queued != -1) { /* queued = -1 is an internal hack used when the request must be completed, but the request object should not be freed. This is used in ADIOI_Complete_async, because the user will call MPI_Wait later, which would require status to be filled. Ugly but works. queued = -1 should be used only in ADIOI_Complete_async. This should not affect the user in any way. */ /* if request is still queued in the system, it is also there on ADIOI_Async_list. Delete it from there. */ if ((*request)->queued) ADIOI_Del_req_from_list(request); (*request)->fd->async_count--; if ((*request)->handle) ADIOI_Free((*request)->handle); ADIOI_Free_request((ADIOI_Req_node *) (*request)); *request = ADIO_REQUEST_NULL; } }
void ADIOI_PVFS_ReadComplete(ADIO_Request *request, ADIO_Status *status, int *error_code) { if (*request == ADIO_REQUEST_NULL) { *error_code = MPI_SUCCESS; return; } #ifdef HAVE_STATUS_SET_BYTES MPIR_Status_set_bytes(status, (*request)->datatype, (*request)->nbytes); #endif (*request)->fd->async_count--; ADIOI_Free_request((ADIOI_Req_node *) (*request)); *request = ADIO_REQUEST_NULL; *error_code = MPI_SUCCESS; }
int ADIOI_PFS_ReadDone(ADIO_Request *request, ADIO_Status *status, int *error_code) { int done=0; static char myname[] = "ADIOI_PFS_READDONE"; if (*request == ADIO_REQUEST_NULL) { *error_code = MPI_SUCCESS; return 1; } if ((*request)->queued) done = _iodone(*((long *) (*request)->handle)); else done = 1; /* ADIOI_Complete_Async completed this request, but request object was not freed. */ #ifdef HAVE_STATUS_SET_BYTES if ((done >= 0) && ((*request)->nbytes != -1)) MPIR_Status_set_bytes(status, (*request)->datatype, (*request)->nbytes); #endif if (done >= 0) { /* if request is still queued in the system, it is also there on ADIOI_Async_list. Delete it from there. */ if ((*request)->queued) ADIOI_Del_req_from_list(request); (*request)->fd->async_count--; if ((*request)->handle) ADIOI_Free((*request)->handle); ADIOI_Free_request((ADIOI_Req_node *) (*request)); *request = ADIO_REQUEST_NULL; } if (done == -1 && errno != 0) { *error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, myname, __LINE__, MPI_ERR_IO, "**io", "**io %s", strerror(errno)); } else *error_code = MPI_SUCCESS; return done; }
int ADIOI_NTFS_ReadDone(ADIO_Request *request, ADIO_Status *status, int *error_code) { DWORD ret_val; int done = 0; static char myname[] = "ADIOI_NTFS_ReadDone"; if (*request == ADIO_REQUEST_NULL) { *error_code = MPI_SUCCESS; return 1; } if ((*request)->queued) { (*request)->nbytes = 0; ret_val = GetOverlappedResult((*request)->fd, (*request)->handle, &(*request)->nbytes, FALSE); if (!ret_val) { /* --BEGIN ERROR HANDLING-- */ ret_val = GetLastError(); if (ret_val == ERROR_IO_INCOMPLETE) { done = 0; *error_code = MPI_SUCCESS; } else { *error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, myname, __LINE__, MPI_ERR_IO, "**io", "**io %s", ADIOI_NTFS_Strerror(ret_val)); } /* --END ERROR HANDLING-- */ } else { done = 1; *error_code = MPI_SUCCESS; } } else { done = 1; *error_code = MPI_SUCCESS; } #ifdef HAVE_STATUS_SET_BYTES if (done && ((*request)->nbytes != -1)) MPIR_Status_set_bytes(status, (*request)->datatype, (*request)->nbytes); #endif if (done) { /* if request is still queued in the system, it is also there on ADIOI_Async_list. Delete it from there. */ if ((*request)->queued) ADIOI_Del_req_from_list(request); (*request)->fd->async_count--; if ((*request)->handle) { if (!CloseHandle(((OVERLAPPED*)((*request)->handle))->hEvent)) { ret_val = GetLastError(); *error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, myname, __LINE__, MPI_ERR_IO, "**io", "**io %s", ADIOI_NTFS_Strerror(ret_val)); } ADIOI_Free((*request)->handle); } ADIOI_Free_request((ADIOI_Req_node *) (*request)); *request = ADIO_REQUEST_NULL; } return done; }
/* ADIOI_GEN_IOComplete * * This code handles two distinct cases. If ROMIO_HAVE_WORKING_AIO is * not defined, then I/O was performed by a blocking call already. In * that case all we need to do is optionally set the bytes in the * status structure and free the request. * * If ROMIO_HAVE_WORKING_AIO is defined, then we may need to wait for I/O * to complete. */ void ADIOI_GEN_IOComplete(ADIO_Request *request, ADIO_Status *status, int *error_code) { #ifdef ROMIO_HAVE_WORKING_AIO int err; #ifdef ROMIO_HAVE_STRUCT_AIOCB_WITH_AIO_HANDLE struct aiocb *tmp1; #endif static char myname[] = "ADIOI_GEN_IOCOMPLETE"; #endif if (*request == ADIO_REQUEST_NULL) { *error_code = MPI_SUCCESS; return; } #ifdef ROMIO_HAVE_AIO_SUSPEND_TWO_ARGS /* old IBM */ if ((*request)->queued) { do { err = aio_suspend(1, (struct aiocb **) &((*request)->handle)); } while ((err == -1) && (errno == EINTR)); tmp1 = (struct aiocb *) (*request)->handle; if (err != -1) { err = aio_return(tmp1->aio_handle); (*request)->nbytes = err; errno = aio_error(tmp1->aio_handle); } else (*request)->nbytes = -1; /* on DEC, it is required to call aio_return to dequeue the request. IBM man pages don't indicate what function to use for dequeue. I'm assuming it is aio_return! POSIX says aio_return may be called only once on a given handle. */ if (err == -1) { *error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, myname, __LINE__, MPI_ERR_IO, "**io", "**io %s", strerror(errno)); return; } else *error_code = MPI_SUCCESS; } /* if ((*request)->queued) */ else *error_code = MPI_SUCCESS; #ifdef HAVE_STATUS_SET_BYTES if ((*request)->nbytes != -1) MPIR_Status_set_bytes(status, (*request)->datatype, (*request)->nbytes); #endif #elif defined(ROMIO_HAVE_WORKING_AIO) /* all other aio types */ if ((*request)->queued) { do { err = aio_suspend((const struct aiocb **) &((*request)->handle), 1, 0); } while ((err == -1) && (errno == EINTR)); if (err != -1) { err = aio_return((struct aiocb *) (*request)->handle); (*request)->nbytes = err; errno = aio_error((struct aiocb *) (*request)->handle); } else (*request)->nbytes = -1; if (err == -1) { *error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, myname, __LINE__, MPI_ERR_IO, "**io", "**io %s", strerror(errno)); return; } else *error_code = MPI_SUCCESS; } /* if ((*request)->queued) */ else *error_code = MPI_SUCCESS; #ifdef HAVE_STATUS_SET_BYTES if ((*request)->nbytes != -1) MPIR_Status_set_bytes(status, (*request)->datatype, (*request)->nbytes); #endif #endif #ifdef ROMIO_HAVE_WORKING_AIO if ((*request)->queued != -1) { /* queued = -1 is an internal hack used when the request must be completed, but the request object should not be freed. This is used in ADIOI_Complete_async, because the user will call MPI_Wait later, which would require status to be filled. Ugly but works. queued = -1 should be used only in ADIOI_Complete_async. This should not affect the user in any way. */ /* if request is still queued in the system, it is also there on ADIOI_Async_list. Delete it from there. */ if ((*request)->queued) ADIOI_Del_req_from_list(request); (*request)->fd->async_count--; if ((*request)->handle) ADIOI_Free((*request)->handle); ADIOI_Free_request((ADIOI_Req_node *) (*request)); *request = ADIO_REQUEST_NULL; } #else /* no aio */ #ifdef HAVE_STATUS_SET_BYTES MPIR_Status_set_bytes(status, (*request)->datatype, (*request)->nbytes); #endif (*request)->fd->async_count--; ADIOI_Free_request((ADIOI_Req_node *) (*request)); *request = ADIO_REQUEST_NULL; *error_code = MPI_SUCCESS; #endif }
int ADIOI_NTFS_ReadDone(ADIO_Request *request, ADIO_Status *status, int *error_code) { DWORD ret_val; int done=0; #ifndef PRINT_ERR_MSG static char myname[] = "ADIOI_NTFS_READDONE"; #endif if (*request == ADIO_REQUEST_NULL) { *error_code = MPI_SUCCESS; return 1; } if ((*request)->queued) { (*request)->nbytes = 0; ret_val = GetOverlappedResult((*request)->fd, (*request)->handle, &(*request)->nbytes, FALSE); //ret_val = WaitForSingleObject((*request)->handle, INFINITE); //ret_val = (ret_val == WAIT_OBJECT_0) ? TRUE : FALSE; if (!ret_val) { ret_val = GetLastError(); if (ret_val == ERROR_IO_INCOMPLETE) { done = 0; *error_code = MPI_SUCCESS; } } else { done = 1; *error_code = MPI_SUCCESS; } } else { done = 1; *error_code = MPI_SUCCESS; } #ifdef HAVE_STATUS_SET_BYTES if (done && ((*request)->nbytes != -1)) MPIR_Status_set_bytes(status, (*request)->datatype, (*request)->nbytes); #endif if (done) { /* if request is still queued in the system, it is also there on ADIOI_Async_list. Delete it from there. */ if ((*request)->queued) ADIOI_Del_req_from_list(request); (*request)->fd->async_count--; if ((*request)->handle) { CloseHandle(((OVERLAPPED*)((*request)->handle))->hEvent); ADIOI_Free((*request)->handle); } ADIOI_Free_request((ADIOI_Req_node *) (*request)); *request = ADIO_REQUEST_NULL; } return done; }
void ADIOI_UFS_ReadComplete(ADIO_Request *request, ADIO_Status *status, int *error_code) { #ifndef NO_AIO #ifndef PRINT_ERR_MSG static char myname[] = "ADIOI_UFS_READCOMPLETE"; #endif #ifdef AIO_SUN aio_result_t *result=0, *tmp; #else int err; #endif #ifdef AIO_HANDLE_IN_AIOCB struct aiocb *tmp1; #endif #endif if (*request == ADIO_REQUEST_NULL) { *error_code = MPI_SUCCESS; return; } #ifdef AIO_SUN if ((*request)->queued) { /* dequeue it */ tmp = (aio_result_t *) (*request)->handle; while (tmp->aio_return == AIO_INPROGRESS) usleep(1000); /* sleep for 1 ms., until done. Is 1 ms. a good number? */ /* when done, dequeue any one request */ result = (aio_result_t *) aiowait(0); (*request)->nbytes = tmp->aio_return; #ifdef PRINT_ERR_MSG *error_code = (tmp->aio_return == -1) ? MPI_ERR_UNKNOWN : MPI_SUCCESS; #else if (tmp->aio_return == -1) { *error_code = MPIR_Err_setmsg(MPI_ERR_IO, MPIR_ADIO_ERROR, myname, "I/O Error", "%s", strerror(tmp->aio_errno)); ADIOI_Error((*request)->fd, *error_code, myname); } else *error_code = MPI_SUCCESS; #endif /* aiowait only dequeues a request. The completion of a request can be checked by just checking the aio_return flag in the handle passed to the original aioread()/aiowrite(). Therefore, I need to ensure that aiowait() is called exactly once for each previous aioread()/aiowrite(). This is also taken care of in ADIOI_xxxDone */ } else *error_code = MPI_SUCCESS; #ifdef HAVE_STATUS_SET_BYTES if ((*request)->nbytes != -1) MPIR_Status_set_bytes(status, (*request)->datatype, (*request)->nbytes); #endif #endif #ifdef AIO_HANDLE_IN_AIOCB /* IBM */ if ((*request)->queued) { do { err = aio_suspend(1, (struct aiocb **) &((*request)->handle)); } while ((err == -1) && (errno == EINTR)); tmp1 = (struct aiocb *) (*request)->handle; if (err != -1) { err = aio_return(tmp1->aio_handle); (*request)->nbytes = err; errno = aio_error(tmp1->aio_handle); } else (*request)->nbytes = -1; /* on DEC, it is required to call aio_return to dequeue the request. IBM man pages don't indicate what function to use for dequeue. I'm assuming it is aio_return! POSIX says aio_return may be called only once on a given handle. */ #ifdef PRINT_ERR_MSG *error_code = (err == -1) ? MPI_ERR_UNKNOWN : MPI_SUCCESS; #else if (err == -1) { *error_code = MPIR_Err_setmsg(MPI_ERR_IO, MPIR_ADIO_ERROR, myname, "I/O Error", "%s", strerror(errno)); ADIOI_Error((*request)->fd, *error_code, myname); } else *error_code = MPI_SUCCESS; #endif } else *error_code = MPI_SUCCESS; #ifdef HAVE_STATUS_SET_BYTES if ((*request)->nbytes != -1) MPIR_Status_set_bytes(status, (*request)->datatype, (*request)->nbytes); #endif #elif (!defined(NO_AIO) && !defined(AIO_SUN)) /* DEC, SGI IRIX 5 and 6 */ if ((*request)->queued) { do { err = aio_suspend((const aiocb_t **) &((*request)->handle), 1, 0); } while ((err == -1) && (errno == EINTR)); if (err != -1) { err = aio_return((struct aiocb *) (*request)->handle); (*request)->nbytes = err; errno = aio_error((struct aiocb *) (*request)->handle); } else (*request)->nbytes = -1; #ifdef PRINT_ERR_MSG *error_code = (err == -1) ? MPI_ERR_UNKNOWN : MPI_SUCCESS; #else if (err == -1) { *error_code = MPIR_Err_setmsg(MPI_ERR_IO, MPIR_ADIO_ERROR, myname, "I/O Error", "%s", strerror(errno)); ADIOI_Error((*request)->fd, *error_code, myname); } else *error_code = MPI_SUCCESS; #endif } else *error_code = MPI_SUCCESS; #ifdef HAVE_STATUS_SET_BYTES if ((*request)->nbytes != -1) MPIR_Status_set_bytes(status, (*request)->datatype, (*request)->nbytes); #endif #endif #ifndef NO_AIO if ((*request)->queued != -1) { /* queued = -1 is an internal hack used when the request must be completed, but the request object should not be freed. This is used in ADIOI_Complete_async, because the user will call MPI_Wait later, which would require status to be filled. Ugly but works. queued = -1 should be used only in ADIOI_Complete_async. This should not affect the user in any way. */ /* if request is still queued in the system, it is also there on ADIOI_Async_list. Delete it from there. */ if ((*request)->queued) ADIOI_Del_req_from_list(request); (*request)->fd->async_count--; if ((*request)->handle) ADIOI_Free((*request)->handle); ADIOI_Free_request((ADIOI_Req_node *) (*request)); *request = ADIO_REQUEST_NULL; } #else /* HP, FreeBSD, Linux */ #ifdef HAVE_STATUS_SET_BYTES MPIR_Status_set_bytes(status, (*request)->datatype, (*request)->nbytes); #endif (*request)->fd->async_count--; ADIOI_Free_request((ADIOI_Req_node *) (*request)); *request = ADIO_REQUEST_NULL; *error_code = MPI_SUCCESS; #endif }