[Linux-ha-dev] Proposed patch
David Lee
t.d.lee at durham.ac.uk
Fri Mar 10 09:52:28 MST 2006
I propose applying the attached patch early next week. But I would very
much like someone who knows the area both to sanity-check it and to
run-time check it, please.
Axiom: Part of the heartbeat ethos is that compiler warnings should be
regarded as potential errors. Indeed, the default Linux compile actually
treats warnings as errors. On Solaris, however, we haven't yet got to
that stage, but we are trying to get there. And a new set of warnings
appeared about five weeks ago...
Problem: In "lib/clplumbing/GSource.c", Solaris (probably more accurately
sparc-architecture) compilations get multiple warnings of the form:
[...]/GSource.c:239: warning: cast increases required alignment of target type
caused by the use of " longclock_t detecttime" in structures. This is a
large type (typically "long long"), which, on some architectures, requires
the space to be similarly aligned. But the code cannot guarantee this
and this is detected at runtime.
Solution: Replace the declaration:
longclock_t detecttime;
by a char array (which doesn't apply alignment constraints):
char detecttime[sizeof(longclock_t)];
and replace references to such fields by two internal routines to store
and fetch the value (internally a "memcpy()" operation).
I think the patch is clean... no casts (always a potential source of
problems!) etc.
Comments? Screams of horror? Raptures of delight?
Incidentally, a casual eye reveals some code duplication: for instance
routines "G_SIG_prepare()" and "G_SIG_check()" look very similar.
Wouldn't it be better if these were merged as far as possible, perhaps
with one acting as a wrapper (+ a line or two of code) for the other?
--
: David Lee I.T. Service :
: Senior Systems Programmer Computer Centre :
: Durham University :
: http://www.dur.ac.uk/t.d.lee/ South Road :
: Durham DH1 3LE :
: Phone: +44 191 334 2752 U.K. :
-------------- next part --------------
--- lib/clplumbing/GSource.c.orig Fri Mar 3 10:35:48 2006
+++ lib/clplumbing/GSource.c Thu Mar 9 17:02:16 2006
@@ -64,12 +64,35 @@
unsigned magno; /* Magic number */ \
long maxdispatchms; /* Time limit for dispatch function */ \
long maxdispatchdelayms; /* Max delay before processing */ \
-longclock_t detecttime; /* Time last input detected */ \
+char detecttime[sizeof(longclock_t)]; \
+ /* Time last input detected */ \
void* udata; /* User-defined data */ \
guint gsourceid; /* Source id of this source */ \
const char * description; /* Description of this source */ \
GDestroyNotify dnotify
+/*
+ * On architectures with alignment constraints, our casting between
+ * "(GSource*)" and "(GFDSource_s*)" etc. causes trouble, because of
+ * the massive alignment requirements of "longclock_t".
+ *
+ * Use the following to store and fetch.
+ */
+static
+void
+lc_store(char *destptr, longclock_t value) {
+ longclock_t _ltt;
+ _ltt = value;
+ memcpy((destptr), &_ltt, sizeof(longclock_t));
+}
+
+static
+longclock_t
+lc_fetch(char *ptr) {
+ longclock_t _ltt;
+ memcpy(&_ltt, (ptr), sizeof(longclock_t));
+ return _ltt;
+}
struct GFDSource_s {
COMMON_STRUCTSTART;
@@ -140,12 +163,14 @@
#define CHECK_DISPATCH_DELAY(i) { \
unsigned long ms; \
+ longclock_t dettime; \
dispstart = time_longclock(); \
- ms = longclockto_ms(sub_longclock(dispstart,(i)->detecttime)); \
+ dettime = lc_fetch((i)->detecttime); \
+ ms = longclockto_ms(sub_longclock(dispstart,dettime)); \
if ((i)->maxdispatchdelayms > 0 \
&& ms > (i)->maxdispatchdelayms) { \
WARN_DELAY(ms, (i)); \
- EXPLAINDELAY(dispstart, (i)->detecttime); \
+ EXPLAINDELAY(dispstart, dettime); \
} \
}
@@ -156,7 +181,7 @@
if ((i)->maxdispatchms > 0 && ms > (i)->maxdispatchms) { \
WARN_TOOLONG(ms, (i)); \
} \
- (i)->detecttime = zero_longclock; \
+ lc_store(((i)->detecttime), zero_longclock); \
}
#define WARN_TOOMUCH(ms, input) cl_log(LOG_WARNING \
@@ -236,7 +261,7 @@
ret->gpfd.events = DEF_EVENTS;
ret->gpfd.revents = 0;
ret->dnotify = notify;
- ret->detecttime = zero_longclock;
+ lc_store((ret->detecttime), zero_longclock);
g_source_add_poll(source, &ret->gpfd);
@@ -310,7 +335,7 @@
GFDSource* fdp = (GFDSource*)source;
g_assert(IS_FDSOURCE(fdp));
if (fdp->gpfd.revents) {
- fdp->detecttime = time_longclock();
+ lc_store((fdp->detecttime), time_longclock());
return TRUE;
}
return FALSE;
@@ -421,7 +446,7 @@
chp->magno = MAG_GCHSOURCE;
chp->maxdispatchdelayms = DEFAULT_MAXDELAY;
chp->maxdispatchms = DEFAULT_MAXDISPATCH;
- chp->detecttime = zero_longclock;
+ lc_store((chp->detecttime), zero_longclock);
chp->ch = ch;
chp->dispatch = dispatch;
chp->udata=userdata;
@@ -550,7 +575,7 @@
}
ret = chp->ch->ops->is_message_pending(chp->ch);
if (ret) {
- chp->detecttime = time_longclock();
+ lc_store((chp->detecttime), time_longclock());
}
CHECKEND(chp);
return ret;
@@ -582,7 +607,7 @@
|| (!chp->fd_fdx && chp->outfd.revents != 0)
|| chp->ch->ops->is_message_pending(chp->ch));
if (ret) {
- chp->detecttime = time_longclock();
+ lc_store((chp->detecttime), time_longclock());
}
CHECKEND(chp);
return ret;
@@ -733,7 +758,7 @@
wcp->magno = MAG_GWCSOURCE;
wcp->maxdispatchdelayms = DEFAULT_MAXDELAY;
wcp->maxdispatchms = DEFAULT_MAXDISPATCH;
- wcp->detecttime = zero_longclock;
+ lc_store((wcp->detecttime), zero_longclock);
wcp->udata = userdata;
wcp->gpfd.fd = wch->ops->get_select_fd(wch);
wcp->gpfd.events = DEF_EVENTS;
@@ -809,7 +834,7 @@
g_assert(IS_WCSOURCE(wcp));
if (wcp->gpfd.revents != 0) {
- wcp->detecttime = time_longclock();
+ lc_store((wcp->detecttime), time_longclock());
return TRUE;
}
return FALSE;
@@ -1019,15 +1044,17 @@
clock_t diff;
/* detecttime is reset in the dispatch function */
- if (cmp_longclock(sig_src->detecttime, zero_longclock) != 0) {
+ if (cmp_longclock(lc_fetch(sig_src->detecttime), zero_longclock) != 0) {
cl_log(LOG_ERR, "%s: detecttime already set?", __FUNCTION__);
return TRUE;
}
/* Otherwise, this is when it was first detected */
now = times(&dummy_tms_struct);
diff = now - sig_src->sh_detecttime; /* How long since signal occurred? */
- sig_src->detecttime
- = sub_longclock(time_longclock(), (longclock_t)diff);
+ lc_store(
+ sig_src->detecttime,
+ sub_longclock(time_longclock(), (longclock_t)diff)
+ );
return TRUE;
}
return FALSE;
@@ -1049,14 +1076,16 @@
static struct tms dummy_tms_struct;
clock_t now;
clock_t diff;
- if (cmp_longclock(sig_src->detecttime, zero_longclock) != 0){
+ if (cmp_longclock(lc_fetch(sig_src->detecttime), zero_longclock) != 0){
return TRUE;
}
/* Otherwise, this is when it was first detected */
now = times(&dummy_tms_struct);
diff = now - sig_src->sh_detecttime;
- sig_src->detecttime
- = sub_longclock(time_longclock(), (longclock_t)diff);
+ lc_store(
+ sig_src->detecttime,
+ sub_longclock(time_longclock(), (longclock_t)diff)
+ );
return TRUE;
}
return FALSE;
@@ -1265,7 +1294,7 @@
trig_src->dispatch = dispatch;
trig_src->udata = userdata;
trig_src->dnotify = notify;
- trig_src->detecttime = zero_longclock;
+ lc_store((trig_src->detecttime), zero_longclock);
trig_src->manual_trigger = FALSE;
@@ -1303,7 +1332,7 @@
g_assert(IS_TRIGSOURCE(trig_src));
trig_src->manual_trigger = TRUE;
- trig_src->detecttime = time_longclock();
+ lc_store((trig_src->detecttime), time_longclock());
}
@@ -1335,8 +1364,8 @@
if (trig_src->manual_trigger
- && cmp_longclock(trig_src->detecttime, zero_longclock) == 0) {
- trig_src->detecttime = time_longclock();
+ && cmp_longclock(lc_fetch(trig_src->detecttime), zero_longclock) == 0) {
+ lc_store((trig_src->detecttime), time_longclock());
}
return trig_src->manual_trigger;
}
@@ -1353,8 +1382,8 @@
g_assert(IS_TRIGSOURCE(trig_src));
if (trig_src->manual_trigger
- && cmp_longclock(trig_src->detecttime, zero_longclock) == 0) {
- trig_src->detecttime = time_longclock();
+ && cmp_longclock(lc_fetch(trig_src->detecttime), zero_longclock) == 0) {
+ lc_store((trig_src->detecttime), time_longclock());
}
return trig_src->manual_trigger;
}
@@ -1383,7 +1412,7 @@
}
CHECK_DISPATCH_TIME(trig_src);
}
- trig_src->detecttime = zero_longclock;
+ lc_store((trig_src->detecttime), zero_longclock);
return TRUE;
}
@@ -1468,7 +1497,7 @@
append->maxdispatchms = DEFAULT_MAXDISPATCH;
append->maxdispatchdelayms = DEFAULT_MAXDELAY;
append->description = "(timeout)";
- append->detecttime = zero_longclock;
+ lc_store((append->detecttime), zero_longclock);
append->udata = NULL;
append->nexttime = add_longclock(time_longclock()
@@ -1549,7 +1578,7 @@
gboolean ret;
g_assert(IS_TIMEOUTSRC(append));
- append->detecttime = append->nexttime;
+ lc_store(append->detecttime, append->nexttime);
CHECK_DISPATCH_DELAY(append);
More information about the Linux-HA-Dev
mailing list