summaryrefslogtreecommitdiffstats
path: root/src/H5detect.c
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 /src/H5detect.c
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
Diffstat (limited to 'src/H5detect.c')
-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