File: ad_nfs_iwrite.c

package info (click to toggle)
openmpi 5.0.8-3
  • links: PTS, VCS
  • area: main
  • in suites:
  • size: 201,692 kB
  • sloc: ansic: 613,078; makefile: 42,353; sh: 11,194; javascript: 9,244; f90: 7,052; java: 6,404; perl: 5,179; python: 1,859; lex: 740; fortran: 61; cpp: 20; tcl: 12
file content (139 lines) | stat: -rw-r--r-- 4,126 bytes parent folder | download | duplicates (7)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
/*
 * Copyright (C) by Argonne National Laboratory
 *     See COPYRIGHT in top-level directory
 */

#include "ad_nfs.h"

#include "../../mpi-io/mpioimpl.h"
#ifdef MPIO_BUILD_PROFILING
#include "../../mpi-io/mpioprof.h"
#endif
#include "mpiu_greq.h"

#include <string.h>

#ifdef ROMIO_HAVE_WORKING_AIO
static MPIX_Grequest_class ADIOI_GEN_greq_class = 0;
/* this routine is nearly identical to ADIOI_GEN_IwriteContig, except we lock
 * around I/O */
void ADIOI_NFS_IwriteContig(ADIO_File fd, void *buf, int count,
                            MPI_Datatype datatype, int file_ptr_type,
                            ADIO_Offset offset, ADIO_Request * request, int *error_code)
{
    MPI_Count len, typesize;
    int aio_errno = 0;
    static char myname[] = "ADIOI_NFS_IWRITECONTIG";

    MPI_Type_size_x(datatype, &typesize);
    len = count * typesize;

    if (file_ptr_type == ADIO_INDIVIDUAL)
        offset = fd->fp_ind;
    aio_errno = ADIOI_NFS_aio(fd, buf, len, offset, 1, request);
    if (file_ptr_type == ADIO_INDIVIDUAL)
        fd->fp_ind += len;

    fd->fp_sys_posn = -1;

    if (aio_errno != 0) {
        /* --BEGIN ERROR HANDLING-- */
        MPIO_ERR_CREATE_CODE_ERRNO(myname, aio_errno, error_code);
        return;
        /* --END ERROR HANDLING-- */
    } else
        *error_code = MPI_SUCCESS;
    return;
}
#endif

/* This function is for implementation convenience. It is not user-visible.
 * It takes care of the differences in the interface for nonblocking I/O
 * on various Unix machines! If wr==1 write, wr==0 read.
 *
 * Returns 0 on success, -errno on failure.
 */
#ifdef ROMIO_HAVE_WORKING_AIO
int ADIOI_NFS_aio(ADIO_File fd, void *buf, int len, ADIO_Offset offset,
                  int wr, MPI_Request * request)
{
    int err = -1, fd_sys;
    int error_code, this_errno;

    struct aiocb *aiocbp;
    ADIOI_AIO_Request *aio_req;
    MPI_Status status;

    fd_sys = fd->fd_sys;

    aio_req = (ADIOI_AIO_Request *) ADIOI_Calloc(sizeof(ADIOI_AIO_Request), 1);
    aiocbp = (struct aiocb *) ADIOI_Calloc(sizeof(struct aiocb), 1);
    aiocbp->aio_offset = offset;
    aiocbp->aio_buf = buf;
    aiocbp->aio_nbytes = len;

#ifdef HAVE_STRUCT_AIOCB_AIO_WHENCE
    aiocbp->aio_whence = SEEK_SET;
#endif
#ifdef HAVE_STRUCT_AIOCB_AIO_FILDES
    aiocbp->aio_fildes = fd_sys;
#endif
#ifdef HAVE_STRUCT_AIOCB_AIO_SIGEVENT
#ifdef AIO_SIGNOTIFY_NONE
    aiocbp->aio_sigevent.sigev_notify = SIGEV_NONE;
#endif
    aiocbp->aio_sigevent.sigev_signo = 0;
#endif
#ifdef HAVE_STRUCT_AIOCB_AIO_REQPRIO
#ifdef AIO_PRIO_DFL
    aiocbp->aio_reqprio = AIO_PRIO_DFL; /* not needed in DEC Unix 4.0 */
#else
    aiocbp->aio_reqprio = 0;
#endif
#endif

    if (wr)
        ADIOI_WRITE_LOCK(fd, offset, SEEK_SET, len);
    else
        ADIOI_READ_LOCK(fd, offset, SEEK_SET, len);

#ifndef ROMIO_HAVE_AIO_CALLS_NEED_FILEDES
    if (wr)
        err = aio_write(aiocbp);
    else
        err = aio_read(aiocbp);
#else
    /* Broken IBM interface */
    if (wr)
        err = aio_write(fd_sys, aiocbp);
    else
        err = aio_read(fd_sys, aiocbp);
#endif

    this_errno = errno;
    ADIOI_UNLOCK(fd, offset, SEEK_SET, len);

    if (err == -1) {
        if (this_errno == EAGAIN) {
            /* exceeded the max. no. of outstanding requests.
             * complete all previous async. requests and try again. */
            ADIO_WriteContig(fd, buf, len, MPI_BYTE, ADIO_EXPLICIT_OFFSET,
                             offset, &status, &error_code);
            MPIO_Completed_request_create(&fd, len, &error_code, request);
            return 0;
        } else {
            return -this_errno;
        }
    }
    aio_req->aiocbp = aiocbp;
    if (ADIOI_GEN_greq_class == 0) {
        MPIX_Grequest_class_create(ADIOI_GEN_aio_query_fn,
                                   ADIOI_GEN_aio_free_fn, MPIU_Greq_cancel_fn,
                                   ADIOI_GEN_aio_poll_fn, ADIOI_GEN_aio_wait_fn,
                                   &ADIOI_GEN_greq_class);
    }
    MPIX_Grequest_class_allocate(ADIOI_GEN_greq_class, aio_req, request);
    memcpy(&(aio_req->req), request, sizeof(MPI_Request));
    return 0;
}
#endif