[svn-r7084] Purpose:

Bug fix

Description:
    Alignment on Cray SV1 machine was not being detected correctly and was
not aligning integer types correctly for type conversion, nor was detecting the
proper internal offset of the data in a 'short' type.

Solution:
    Added more checks to detect way Cray aligns pointers in addition to current
checks.

    Corrected 'offset' detection on big-endian machines.

Platforms tested:
    FreeBSD 4.8 (sleipnir)
    h5committest
This commit is contained in:
Quincey Koziol 2003-06-23 09:22:19 -05:00
parent 2fa2bb4162
commit 38aa393e8a

View File

@ -112,14 +112,14 @@ precision (detected_t *d)
*/
for (n=0; n<d->size && d->perm[n]<0; n++) /*void*/;
d->precision = 8*(d->size-n);
d->offset = 0;
d->offset = 8*n;
} else if (d->perm[d->size - 1] < 0) {
/*
* Higher addresses are padded.
*/
for (n=0; n<d->size && d->perm[d->size-(n+1)]; n++) /*void*/;
d->precision = 8*(d->size-n);
d->offset = 8*n;
d->offset = 0;
} else {
/*
* No padding.
@ -179,13 +179,13 @@ precision (detected_t *d)
INFO.perm[_i] = _j; \
} \
INFO.sign = ('U'!=*(#VAR)); \
ALIGNMENT(TYPE, INFO.align); \
precision (&(INFO)); \
ALIGNMENT(TYPE, INFO); \
if(!strcmp(INFO.varname, "SCHAR") || !strcmp(INFO.varname, "SHORT") || \
!strcmp(INFO.varname, "INT") || !strcmp(INFO.varname, "LONG") || \
!strcmp(INFO.varname, "LLONG")) { \
COMP_ALIGNMENT(TYPE,INFO.comp_align); \
} \
precision (&(INFO)); \
}
/*-------------------------------------------------------------------------
@ -267,12 +267,12 @@ precision (detected_t *d)
\
_v1 = 1.0; \
INFO.bias = find_bias (INFO.epos, INFO.esize, INFO.perm, &_v1); \
ALIGNMENT(TYPE, INFO.align); \
precision (&(INFO)); \
ALIGNMENT(TYPE, INFO); \
if(!strcmp(INFO.varname, "FLOAT") || !strcmp(INFO.varname, "DOUBLE") || \
!strcmp(INFO.varname, "LDOUBLE")) { \
COMP_ALIGNMENT(TYPE,INFO.comp_align); \
} \
precision (&(INFO)); \
}
@ -309,21 +309,33 @@ precision (detected_t *d)
}
#if defined(H5_HAVE_LONGJMP) && defined(H5_HAVE_SIGNAL)
#define ALIGNMENT(TYPE,ALIGN) { \
#define ALIGNMENT(TYPE,INFO) { \
char *volatile _buf=NULL; \
volatile TYPE _val=0; \
volatile TYPE _val2; \
volatile size_t _ano=0; \
void (*_handler)(int) = signal(SIGBUS, sigbus_handler); \
void (*_handler2)(int) = signal(SIGSEGV, sigsegv_handler); \
void (*_handler2)(int) = signal(SIGSEGV, sigsegv_handler); \
\
_buf = malloc(sizeof(TYPE)+align_g[NELMTS(align_g)-1]); \
if (setjmp(jbuf_g)) _ano++; \
if (_ano<NELMTS(align_g)) { \
*((TYPE*)(_buf+align_g[_ano])) = _val; /*possible SIGBUS or SEGSEGV*/ \
_val = *((TYPE*)(_buf+align_g[_ano])); /*possible SIGBUS or SEGSEGV*/ \
(ALIGN)=align_g[_ano]; \
*((TYPE*)(_buf+align_g[_ano])) = _val; /*possible SIGBUS or SEGSEGV*/ \
_val2 = *((TYPE*)(_buf+align_g[_ano])); /*possible SIGBUS or SEGSEGV*/ \
/* Cray Check: This section helps detect alignment on Cray's */ \
/* vector machines (like the SV1) which mask off */ \
/* pointer values when pointing to non-word aligned */ \
/* locations with pointers that are supposed to be */ \
/* word aligned. -QAK */ \
memset(_buf, 0xff, sizeof(TYPE)+align_g[NELMTS(align_g)-1]); \
memcpy(_buf+align_g[_ano]+(INFO.offset/8),((char *)&_val)+(INFO.offset/8),(INFO.precision/8)); \
_val2 = *((TYPE*)(_buf+align_g[_ano])); \
if(_val!=_val2) \
longjmp(jbuf_g, 1); \
/* End Cray Check */ \
(INFO.align)=align_g[_ano]; \
} else { \
(ALIGN)=0; \
(INFO.align)=0; \
fprintf(stderr, "unable to calculate alignment for %s\n", #TYPE); \
} \
free(_buf); \
@ -331,12 +343,12 @@ precision (detected_t *d)
signal(SIGSEGV, _handler2); /*restore original handler*/ \
}
#else
#define ALIGNMENT(TYPE,ALIGN) (ALIGN)=0
#define ALIGNMENT(TYPE,INFO) (INFO.align)=0
#endif
#if 0
#if defined(H5_HAVE_FORK) && defined(H5_HAVE_WAITPID)
#define ALIGNMENT(TYPE,ALIGN) { \
#define ALIGNMENT(TYPE,INFO) { \
char *_buf; \
TYPE _val=0; \
size_t _ano; \
@ -362,7 +374,7 @@ precision (detected_t *d)
exit(1); \
} \
if (WIFEXITED(_status) && 0==WEXITSTATUS(_status)) { \
ALIGN=align_g[_ano]; \
INFO.align=align_g[_ano]; \
break; \
} \
if (WIFSIGNALED(_status) && SIGBUS==WTERMSIG(_status)) { \
@ -372,12 +384,12 @@ precision (detected_t *d)
break; \
} \
if (_ano>=NELMTS(align_g)) { \
ALIGN=0; \
INFO.align=0; \
fprintf(stderr, "unable to calculate alignment for %s\n", #TYPE); \
} \
}
#else
#define ALIGNMENT(TYPE,ALIGN) (ALIGN)=0
#define ALIGNMENT(TYPE,INFO) (INFO.align)=0
#endif
#endif