]> rtime.felk.cvut.cz Git - orte.git/commitdiff
Use CLOCK_MONOTONIC rather than CLOCK_REALTIME
authorMichal Sojka <sojkam1@fel.cvut.cz>
Sat, 14 Mar 2015 15:39:35 +0000 (16:39 +0100)
committerMichal Sojka <sojkam1@fel.cvut.cz>
Sat, 14 Mar 2015 15:44:05 +0000 (16:44 +0100)
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.

configure.ac
orte/include/orte/orte_config_omk_linux.h
orte/liborte/ORTEDomain.c
orte/liborte/RTPSCSTWriter.c
orte/liborte/htimerNtp.c

index 86f3c443691583fc6024f2189f32b769777cac27..a6b9b7f1db1160ebf15dc93c48a5070d2fc7fc8d 100644 (file)
@@ -143,6 +143,10 @@ if test -z "${CONFIG_ORTE_RT}" ; then
   )
 fi
 
+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],[
index 5562fca3c0111cc29c86588db9fe08320954ac0f..7e803118a828159cba693b0a0e9e1f8732026a77 100644 (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 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
 
@@ -73,6 +77,9 @@
 /* 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
 
@@ -91,6 +98,9 @@
 /* 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 <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 <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 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"
 
index 533cc738797652bb7993ff9477b38a43141af4d8..31c1a3f7a1a95a49fc5cc0ae06305b318765cd18 100644 (file)
@@ -193,6 +193,7 @@ ORTEDomainCreate(int domain, ORTEDomainProp *prop,
   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__);
@@ -220,11 +221,16 @@ ORTEDomainCreate(int domain, ORTEDomainProp *prop,
   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);
-  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;
@@ -757,6 +763,7 @@ err_domainProp:
   pthread_mutex_destroy(&d->objectEntry.htimSendMutex);
   pthread_rwlock_destroy(&d->objectEntry.htimRootLock);
   pthread_rwlock_destroy(&d->objectEntry.objRootLock);
+err_free:
   FREE(d);
   errno = errno_save;
   return NULL;
index 6f4dfba1aede195b984206b9ee027d71faa9ea77..df3d8feecc43798a379df04c443b4bcf2eae20f5 100644 (file)
@@ -70,7 +70,12 @@ CSTWriterInit(ORTEDomain *d, CSTWriter *cstWriter, ObjectEntryOID *object,
   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;
   }
index bf73b1de32846a7fe193f95b34a2fd358fcb40ed..57facaf6a6337015e49a5aecba21a095676209d4 100644 (file)
@@ -260,18 +260,26 @@ getActualNtpTime(void)
 {
   NtpTime               result;
 
+#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);
-#else
+#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);
-#endif
+#endif /* CONFIG_ORTE_RT */
+#endif /* HAVE_DECL_CLOCK_MONOTONIC */
   return result;
 }