1 /* -*- Mode: C; c-basic-offset:4 ; -*- */
3 * Copyright (C) 1997 University of Chicago.
4 * See COPYRIGHT notice in top-level directory.
9 #include "../../mpi-io/mpioimpl.h"
10 #include "../../mpi-io/mpioprof.h"
11 #include "mpiu_greq.h"
15 #ifdef ROMIO_HAVE_WORKING_AIO
16 static MPIX_Grequest_class ADIOI_GEN_greq_class
= 0;
17 /* this routine is nearly identical to ADIOI_GEN_IwriteContig, except we lock
19 void ADIOI_NFS_IwriteContig(ADIO_File fd
, void *buf
, int count
,
20 MPI_Datatype datatype
, int file_ptr_type
,
21 ADIO_Offset offset
, ADIO_Request
*request
, int *error_code
)
25 static char myname
[] = "ADIOI_NFS_IWRITECONTIG";
27 MPI_Type_size(datatype
, &typesize
);
28 len
= count
* typesize
;
30 if (file_ptr_type
== ADIO_INDIVIDUAL
) offset
= fd
->fp_ind
;
31 aio_errno
= ADIOI_NFS_aio(fd
, buf
, len
, offset
, 1, request
);
32 if (file_ptr_type
== ADIO_INDIVIDUAL
) fd
->fp_ind
+= len
;
37 /* --BEGIN ERROR HANDLING-- */
38 MPIO_ERR_CREATE_CODE_ERRNO(myname
, aio_errno
, error_code
);
40 /* --END ERROR HANDLING-- */
42 else *error_code
= MPI_SUCCESS
;
47 /* This function is for implementation convenience. It is not user-visible.
48 * It takes care of the differences in the interface for nonblocking I/O
49 * on various Unix machines! If wr==1 write, wr==0 read.
51 * Returns 0 on success, -errno on failure.
53 #ifdef ROMIO_HAVE_WORKING_AIO
54 int ADIOI_NFS_aio(ADIO_File fd
, void *buf
, int len
, ADIO_Offset offset
,
55 int wr
, MPI_Request
*request
)
58 int error_code
, this_errno
;
61 ADIOI_AIO_Request
*aio_req
;
66 aio_req
= (ADIOI_AIO_Request
*)ADIOI_Calloc(sizeof(ADIOI_AIO_Request
), 1);
67 aiocbp
= (struct aiocb
*) ADIOI_Calloc(sizeof(struct aiocb
), 1);
68 aiocbp
->aio_offset
= offset
;
69 aiocbp
->aio_buf
= buf
;
70 aiocbp
->aio_nbytes
= len
;
72 #ifdef ROMIO_HAVE_STRUCT_AIOCB_WITH_AIO_WHENCE
73 aiocbp
->aio_whence
= SEEK_SET
;
75 #ifdef ROMIO_HAVE_STRUCT_AIOCB_WITH_AIO_FILDES
76 aiocbp
->aio_fildes
= fd_sys
;
78 #ifdef ROMIO_HAVE_STRUCT_AIOCB_WITH_AIO_SIGEVENT
79 # ifdef AIO_SIGNOTIFY_NONE
80 aiocbp
->aio_sigevent
.sigev_notify
= SIGEV_NONE
;
82 aiocbp
->aio_sigevent
.sigev_signo
= 0;
84 #ifdef ROMIO_HAVE_STRUCT_AIOCB_WITH_AIO_REQPRIO
86 aiocbp
->aio_reqprio
= AIO_PRIO_DFL
; /* not needed in DEC Unix 4.0 */
88 aiocbp
->aio_reqprio
= 0;
92 if (wr
) ADIOI_WRITE_LOCK(fd
, offset
, SEEK_SET
, len
);
93 else ADIOI_READ_LOCK(fd
, offset
, SEEK_SET
, len
);
95 #ifndef ROMIO_HAVE_AIO_CALLS_NEED_FILEDES
96 if (wr
) err
= aio_write(aiocbp
);
97 else err
= aio_read(aiocbp
);
99 /* Broken IBM interface */
100 if (wr
) err
= aio_write(fd_sys
, aiocbp
);
101 else err
= aio_read(fd_sys
, aiocbp
);
105 ADIOI_UNLOCK(fd
, offset
, SEEK_SET
, len
);
108 if (this_errno
== EAGAIN
) {
109 /* exceeded the max. no. of outstanding requests.
110 complete all previous async. requests and try again. */
111 ADIO_WriteContig(fd
, buf
, len
, MPI_BYTE
, ADIO_EXPLICIT_OFFSET
,
112 offset
, &status
, &error_code
);
113 MPIO_Completed_request_create(&fd
, len
, &error_code
, request
);
119 aio_req
->aiocbp
= aiocbp
;
120 if (ADIOI_GEN_greq_class
== 0) {
121 MPIX_Grequest_class_create(ADIOI_GEN_aio_query_fn
,
122 ADIOI_GEN_aio_free_fn
, MPIU_Greq_cancel_fn
,
123 ADIOI_GEN_aio_poll_fn
, ADIOI_GEN_aio_wait_fn
,
124 &ADIOI_GEN_greq_class
);
126 MPIX_Grequest_class_allocate(ADIOI_GEN_greq_class
, aio_req
, request
);
127 memcpy(&(aio_req
->req
), request
, sizeof(MPI_Request
));