Ejemplo n.º 1
0
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;
}
Ejemplo n.º 2
0
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;
    }
}
Ejemplo n.º 3
0
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;
}
Ejemplo n.º 4
0
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;
}
Ejemplo n.º 5
0
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;
}
Ejemplo n.º 6
0
/* 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    
}
Ejemplo n.º 7
0
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;
}
Ejemplo n.º 8
0
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    
}