summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorQuincey Koziol <koziol@hdfgroup.org>2003-06-23 14:22:19 (GMT)
committerQuincey Koziol <koziol@hdfgroup.org>2003-06-23 14:22:19 (GMT)
commit38aa393e8acbf0d05d704e48694873d4b351ea3d (patch)
treea7286901027d94dcfbff30e34ea2791721915c2a
parent2fa2bb41625ed55a898eb59826a6cb8720c66416 (diff)
downloadhdf5-38aa393e8acbf0d05d704e48694873d4b351ea3d.zip
hdf5-38aa393e8acbf0d05d704e48694873d4b351ea3d.tar.gz
hdf5-38aa393e8acbf0d05d704e48694873d4b351ea3d.tar.bz2
[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
-rw-r--r--src/H5detect.c46
1 files changed, 29 insertions, 17 deletions
diff --git a/src/H5detect.c b/src/H5detect.c
index fb11322..eb8f9ac 100644
--- a/src/H5detect.c
+++ b/src/H5detect.c
@@ -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