1
1
openmpi/opal/util/convert.c
George Bosilca 5e280cda19 Latest and greatest. Now OPAL is ready for the Windows prime-time.
The same treatement will happens on all sub-projects. The .h files
have to be C++ compatibles and all symbols with an external visibility
have to get the {PROJECT}_DECLSPEC in front of the prototype.

This commit was SVN r11340.
2006-08-23 00:29:35 +00:00

113 строки
3.0 KiB
C

/*
* Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana
* University Research and Technology
* Corporation. All rights reserved.
* Copyright (c) 2004-2006 The University of Tennessee and The University
* of Tennessee Research Foundation. All rights
* reserved.
* Copyright (c) 2004-2005 High Performance Computing Center Stuttgart,
* University of Stuttgart. All rights reserved.
* Copyright (c) 2004-2005 The Regents of the University of California.
* All rights reserved.
* $COPYRIGHT$
*
* Additional copyrights may follow
*
* $HEADER$
*/
#include "opal_config.h"
#include <stdio.h>
#include <stdlib.h>
#include "opal/util/convert.h"
#include "opal/constants.h"
#if SIZEOF_SIZE_T <= SIZEOF_INT
/*
* This is the [short] case where we can just cast and we're all good
*/
int opal_size2int(size_t in, int *out, bool want_check)
{
*out = (int)in;
return OPAL_SUCCESS;
}
#else
/*
* The rest of the file handles the case where
* sizeof(size_t)>sizeof(int).
*/
static bool init_done = false;
static unsigned int int_pos = 0;
static void opal_size2int_init(void);
static void warn(void);
int opal_size2int(size_t in, int *out, bool want_check)
{
int *pos = (int *) &in;
unsigned int i;
if (!init_done) {
opal_size2int_init();
}
*out = pos[int_pos];
if (want_check) {
/* Remember that size_t is unsigned, so we don't need to check
for when in < 0 (in which case the internal checks would be
slightly different) */
for (i = 0; i < (sizeof(in) / sizeof(*out)); ++i) {
if (i != int_pos) {
if (pos[i] != 0) {
warn();
return OPAL_ERR_NOT_IMPLEMENTED;
}
}
}
}
return OPAL_SUCCESS;
}
static void opal_size2int_init(void)
{
size_t bogus = 1;
int *i = (int *) &bogus;
for (int_pos = 0; int_pos < (sizeof(bogus) / sizeof(int)); ++int_pos) {
if (i[int_pos] == 1) {
break;
}
}
init_done = true;
}
static void warn(void)
{
#if OMPI_ENABLE_DEBUG
/* Developer builds */
fprintf(stderr, "WARNING: A size_t value was attempted to be cast to an int (sizeof(size_t) == %ld, sizeof(int) == %ld), but data was lost in the conversion. This should never happen (i.e., we should never try to convert a value that will be 'too big'). Since this is a developer build, I'm going to abort, and you can check the corefile. Enjoy.\n", (long) sizeof(size_t), (long) sizeof(int));
abort();
#else
static bool warned = false;
if (!warned) {
fprintf(stderr, "Open MPI WARNING: A bad cast (size_t->int) occurred.\n");
fprintf(stderr, "Please inform the Open MPI developers. This message will not repeat.\n");
fprintf(stderr, "Attempting to continue (no guarantees about correctness...\n");
warned = true;
}
#endif
}
#endif