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
|
/* -*- Mode: C; c-basic-offset:4 ; -*- */
/*
* Copyright (c) 2018 Research Organization for Information Science
* and Technology (RIST). All rights reserved.
* Copyright (c) 2018-2019 The University of Tennessee and The University
* of Tennessee Research Foundation. All rights
* reserved.
* $COPYRIGHT$
*
* Additional copyrights may follow
*
* $HEADER$
*/
#include "opal_config.h"
#include <stddef.h>
#include "opal/constants.h"
#include "opal/datatype/opal_convertor.h"
#include "opal/datatype/opal_datatype.h"
#include "opal/datatype/opal_datatype_internal.h"
#define OPAL_DATATYPE_MAX_MONOTONIC_IOVEC 32
/**
* Check if the datatype describes a memory layout where the pointers to
* the contiguous pieces are always advancing in the same direction, i.e.
* there is no potential for overlap.
*/
int32_t opal_datatype_is_monotonic(opal_datatype_t *type)
{
struct iovec iov[OPAL_DATATYPE_MAX_MONOTONIC_IOVEC];
ptrdiff_t upper_limit = (ptrdiff_t) type->true_lb; /* as conversion base will be NULL the first
address is true_lb */
size_t max_data = 0x7FFFFFFF;
opal_convertor_t *pConv;
bool monotonic = true;
uint32_t iov_count;
int rc;
pConv = opal_convertor_create(opal_local_arch, 0);
if (OPAL_UNLIKELY(NULL == pConv)) {
return -1;
}
rc = opal_convertor_prepare_for_send(pConv, type, 1, NULL);
if (OPAL_UNLIKELY(OPAL_SUCCESS != rc)) {
OBJ_RELEASE(pConv);
return -1;
}
do {
iov_count = OPAL_DATATYPE_MAX_MONOTONIC_IOVEC;
rc = opal_convertor_raw(pConv, iov, &iov_count, &max_data);
for (uint32_t i = 0; i < iov_count; i++) {
if ((ptrdiff_t) iov[i].iov_base < upper_limit) {
monotonic = false;
goto cleanup;
}
/* The new upper bound is at the end of the iovec */
upper_limit = (ptrdiff_t) iov[i].iov_base + iov[i].iov_len;
}
} while (rc != 1);
cleanup:
OBJ_RELEASE(pConv);
return monotonic;
}
|