mirror of
https://github.com/HDFGroup/hdf5.git
synced 2025-03-31 17:10:47 +08:00
[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:
parent
2fa2bb4162
commit
38aa393e8a
@ -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
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user