summary |
shortlog |
log |
commit | commitdiff |
tree
raw |
patch |
inline | side by side (from parent 1:
9a1a325)
This changes the clock used internally by ORTE for timestamps in the
protocol and for timing of internal operations. Previously,
CLOCK_REALTIME was used, probably because it is the default clock used
by pthread_cond_timedwait(). Using CLOCK_REALTIME has the disadvantage
that the time can "jump", e.g. when the clock is adjusted by ntpdate.
This causes the applications to stop publishing, which results in them
disappearing from the domain even through their processes still run.
The solution implemented in this commit is to switch the clock to
CLOCK_MONOTONIC, which does not jump. This should have no effect at the
protocol level, because the semantic of timestamps is not defined in the
spec. This was also tested by running the implementations with and
without this change against each other.
In future, it might be a good idea to use different clocks for
timestamps in the protocol and for timing of internal operations (e.g.
ORTEAppSendThread()). I'm not sure what happens in the following two
cases:
1) When one node is suspended to RAM/disk, CLOCK_MONOTONIC stops for the
time of suspension and it is not clear to me what other nodes that
run continuously do when the suspended node resumes.
2) When a node is rebooted, the monotonic clock starts from zero, i.e.
there is a "jump". I'm not sure, whether IDs of the application
before and after reboot will be different. UDP ports, that are a part
of the ID should be randomized, but the question is how good this
randomization is. If the ID is the same before and after reboot some
problems might also appear.
+AC_CHECK_FUNCS([pthread_condattr_setclock])
+AC_CHECK_LIB([rt], [clock_gettime])
+AC_CHECK_DECLS([CLOCK_MONOTONIC], [], [], [[#include <time.h>]])
+
###############################
# enable GNU source
AH_VERBATIM([_GNU_SOURCE],[
###############################
# enable GNU source
AH_VERBATIM([_GNU_SOURCE],[
/* #undef HAVE_ASM_BYTEORDER_H */
/* Define to 1 if you have the <byteswap.h> header file. */
/* #undef HAVE_ASM_BYTEORDER_H */
/* Define to 1 if you have the <byteswap.h> header file. */
-/* #undef HAVE_BYTESWAP_H */
+#define HAVE_BYTESWAP_H 1
/* Define to 1 if you have the <ctype.h> header file. */
#define HAVE_CTYPE_H 1
/* Define to 1 if you have the <ctype.h> header file. */
#define HAVE_CTYPE_H 1
+/* Define to 1 if you have the declaration of `CLOCK_MONOTONIC', and to 0 if
+ you don't. */
+#define HAVE_DECL_CLOCK_MONOTONIC 1
+
/* Define to 1 if you have the <dlfcn.h> header file. */
#define HAVE_DLFCN_H 1
/* Define to 1 if you have the <dlfcn.h> header file. */
#define HAVE_DLFCN_H 1
/* Define for ORTE getopt_long self implemetation */
/* #undef HAVE_GETPOT_LONG_ORTE */
/* Define for ORTE getopt_long self implemetation */
/* #undef HAVE_GETPOT_LONG_ORTE */
+/* Define to 1 if you have the `gettimeofday' function. */
+/* #undef HAVE_GETTIMEOFDAY */
+
/* Define to 1 if you have the <ifaddrs.h> header file. */
#define HAVE_IFADDRS_H 1
/* Define to 1 if you have the <ifaddrs.h> header file. */
#define HAVE_IFADDRS_H 1
/* Define to 1 if you have the `pthread' library (-lpthread). */
#define HAVE_LIBPTHREAD 1
/* Define to 1 if you have the `pthread' library (-lpthread). */
#define HAVE_LIBPTHREAD 1
+/* Define to 1 if you have the `rt' library (-lrt). */
+#define HAVE_LIBRT 1
+
/* Define to 1 if you have the `socket' library (-lsocket). */
/* #undef HAVE_LIBSOCKET */
/* Define to 1 if you have the `socket' library (-lsocket). */
/* #undef HAVE_LIBSOCKET */
/* Define to 1 if you have the <onetd.h> header file. */
/* #undef HAVE_ONETD_H */
/* Define to 1 if you have the <onetd.h> header file. */
/* #undef HAVE_ONETD_H */
+/* Define to 1 if you have the `pthread_condattr_setclock' function. */
+#define HAVE_PTHREAD_CONDATTR_SETCLOCK 1
+
/* Define to 1 if you have the <pthread.h> header file. */
#define HAVE_PTHREAD_H 1
/* Define to 1 if you have the <pthread.h> header file. */
#define HAVE_PTHREAD_H 1
/* Define to 1 if you have the <signal.h> header file. */
#define HAVE_SIGNAL_H 1
/* Define to 1 if you have the <signal.h> header file. */
#define HAVE_SIGNAL_H 1
+/* Define to 1 if you have the `sigwaitinfo' function. */
+#define HAVE_SIGWAITINFO 1
+
/* Define to 1 if you have the <stdarg.h> header file. */
#define HAVE_STDARG_H 1
/* Define to 1 if you have the <stdarg.h> header file. */
#define HAVE_STDARG_H 1
*/
#define LT_OBJDIR ".libs/"
*/
#define LT_OBJDIR ".libs/"
-/* Define to 1 if your C compiler doesn't accept -c and -o together. */
-/* #undef NO_MINUS_C_MINUS_O */
-
/* Define to the address where bug reports for this package should be sent. */
#define ORTE_PACKAGE_BUGREPORT "orte@rtime.felk.cvut.cz"
/* Define to the address where bug reports for this package should be sent. */
#define ORTE_PACKAGE_BUGREPORT "orte@rtime.felk.cvut.cz"
int i;
uint16_t port = 0;
int errno_save = 0;
int i;
uint16_t port = 0;
int errno_save = 0;
+ pthread_condattr_t attr;
debug(30, 2) ("ORTEDomainCreate: %s compiled: %s,%s\n",
ORTE_PACKAGE_STRING, __DATE__, __TIME__);
debug(30, 2) ("ORTEDomainCreate: %s compiled: %s,%s\n",
ORTE_PACKAGE_STRING, __DATE__, __TIME__);
d->taskRecvMulticastUserdata.sock.port = 0;
d->taskSend.sock.port = 0;
//init structure objectEntry
d->taskRecvMulticastUserdata.sock.port = 0;
d->taskSend.sock.port = 0;
//init structure objectEntry
+ pthread_condattr_init(&attr);
+#if defined HAVE_PTHREAD_CONDATTR_SETCLOCK && HAVE_DECL_CLOCK_MONOTONIC
+ if (pthread_condattr_setclock(&attr, CLOCK_MONOTONIC) != 0)
+ goto err_free;
+#endif
ObjectEntryHID_init_root_field(&d->objectEntry);
pthread_rwlock_init(&d->objectEntry.objRootLock, NULL);
htimerRoot_init_queue(&d->objectEntry);
pthread_rwlock_init(&d->objectEntry.htimRootLock, NULL);
ObjectEntryHID_init_root_field(&d->objectEntry);
pthread_rwlock_init(&d->objectEntry.objRootLock, NULL);
htimerRoot_init_queue(&d->objectEntry);
pthread_rwlock_init(&d->objectEntry.htimRootLock, NULL);
- pthread_cond_init(&d->objectEntry.htimSendCond, NULL);
+ pthread_cond_init(&d->objectEntry.htimSendCond, &attr);
pthread_mutex_init(&d->objectEntry.htimSendMutex, NULL);
d->objectEntry.htimSendCondValue = 0;
d->objectEntry.htimNeedWakeUp = ORTE_TRUE;
pthread_mutex_init(&d->objectEntry.htimSendMutex, NULL);
d->objectEntry.htimSendCondValue = 0;
d->objectEntry.htimNeedWakeUp = ORTE_TRUE;
pthread_mutex_destroy(&d->objectEntry.htimSendMutex);
pthread_rwlock_destroy(&d->objectEntry.htimRootLock);
pthread_rwlock_destroy(&d->objectEntry.objRootLock);
pthread_mutex_destroy(&d->objectEntry.htimSendMutex);
pthread_rwlock_destroy(&d->objectEntry.htimRootLock);
pthread_rwlock_destroy(&d->objectEntry.objRootLock);
FREE(d);
errno = errno_save;
return NULL;
FREE(d);
errno = errno_save;
return NULL;
cstWriter->domain = d;
cstWriter->typeRegister = typeRegister;
if ((cstWriter->guid.oid & 0x07) == OID_PUBLICATION) {
cstWriter->domain = d;
cstWriter->typeRegister = typeRegister;
if ((cstWriter->guid.oid & 0x07) == OID_PUBLICATION) {
- pthread_cond_init(&cstWriter->condCSChangeDestroyed, NULL);
+ pthread_condattr_t attr;
+ pthread_condattr_init(&attr);
+#if defined HAVE_PTHREAD_CONDATTR_SETCLOCK && HAVE_DECL_CLOCK_MONOTONIC
+ pthread_condattr_setclock(&attr, CLOCK_MONOTONIC);
+#endif
+ pthread_cond_init(&cstWriter->condCSChangeDestroyed, &attr);
pthread_mutex_init(&cstWriter->mutexCSChangeDestroyed, NULL);
cstWriter->condValueCSChangeDestroyed = 0;
}
pthread_mutex_init(&cstWriter->mutexCSChangeDestroyed, NULL);
cstWriter->condValueCSChangeDestroyed = 0;
}
+#if HAVE_DECL_CLOCK_MONOTONIC
+ struct timespec time;
+
+ clock_gettime(CLOCK_MONOTONIC, &time);
+ /* FIXME: Introduce NtpTimeAssembFromNs ather than using division. */
+ NtpTimeAssembFromUs(result, time.tv_sec, time.tv_nsec / 1000);
+#else /* !HAVE_DECL_CLOCK_MONOTONIC */
#ifndef CONFIG_ORTE_RT
struct timeval time;
gettimeofday(&time, NULL);
NtpTimeAssembFromUs(result, time.tv_sec, time.tv_usec);
NtpTimeAssembFromUs(result, time.tv_sec, time.tv_usec);
#ifndef CONFIG_ORTE_RT
struct timeval time;
gettimeofday(&time, NULL);
NtpTimeAssembFromUs(result, time.tv_sec, time.tv_usec);
NtpTimeAssembFromUs(result, time.tv_sec, time.tv_usec);
+#else /* !CONFIG_ORTE_RT */
struct timespec time;
clock_gettime(CLOCK_REALTIME, &time);
time.tv_nsec /= 1000; //conver to us
NtpTimeAssembFromUs(result, time.tv_sec, time.tv_nsec);
struct timespec time;
clock_gettime(CLOCK_REALTIME, &time);
time.tv_nsec /= 1000; //conver to us
NtpTimeAssembFromUs(result, time.tv_sec, time.tv_nsec);
+#endif /* CONFIG_ORTE_RT */
+#endif /* HAVE_DECL_CLOCK_MONOTONIC */