summaryrefslogtreecommitdiffstats
path: root/unix/tclUnixThrd.c
diff options
context:
space:
mode:
Diffstat (limited to 'unix/tclUnixThrd.c')
-rwxr-xr-x[-rw-r--r--]unix/tclUnixThrd.c33
1 files changed, 33 insertions, 0 deletions
diff --git a/unix/tclUnixThrd.c b/unix/tclUnixThrd.c
index 554a2dc..90ac379 100644..100755
--- a/unix/tclUnixThrd.c
+++ b/unix/tclUnixThrd.c
@@ -520,6 +520,9 @@ Tcl_ConditionWait(
pthread_cond_t *pcondPtr;
pthread_mutex_t *pmutexPtr;
struct timespec ptime;
+#if defined(HAVE_CLOCK_GETTIME) && defined(HAVE_PTHREAD_CONDATTR_SETCLOCK)
+ int *flagPtr;
+#endif
if (*condPtr == NULL) {
pthread_mutex_lock(&masterLock);
@@ -530,8 +533,26 @@ Tcl_ConditionWait(
*/
if (*condPtr == NULL) {
+#if defined(HAVE_CLOCK_GETTIME) && defined(HAVE_PTHREAD_CONDATTR_SETCLOCK)
+ pthread_condattr_t attr;
+
+ pcondPtr = ckalloc(sizeof(pthread_cond_t) + sizeof(int));
+ flagPtr = (int *) (pcondPtr + 1);
+ pthread_condattr_init(&attr);
+ *flagPtr = pthread_condattr_setclock(&attr, CLOCK_MONOTONIC) == 0;
+ if (*flagPtr) {
+ if (pthread_cond_init(pcondPtr, &attr)) {
+ *flagPtr = 0;
+ pthread_cond_init(pcondPtr, NULL);
+ }
+ } else {
+ pthread_cond_init(pcondPtr, NULL);
+ }
+ pthread_condattr_destroy(&attr);
+#else
pcondPtr = ckalloc(sizeof(pthread_cond_t));
pthread_cond_init(pcondPtr, NULL);
+#endif
*condPtr = (Tcl_Condition) pcondPtr;
TclRememberCondition(condPtr);
}
@@ -542,6 +563,17 @@ Tcl_ConditionWait(
if (timePtr == NULL) {
pthread_cond_wait(pcondPtr, pmutexPtr);
} else {
+#if defined(HAVE_CLOCK_GETTIME) && defined(HAVE_PTHREAD_CONDATTR_SETCLOCK)
+ flagPtr = (int *) (pcondPtr + 1);
+ if (*flagPtr) {
+ clock_gettime(CLOCK_MONOTONIC, &ptime);
+ } else {
+ clock_gettime(CLOCK_REALTIME, &ptime);
+ }
+ ptime.tv_sec += timePtr->sec +
+ (timePtr->usec * 1000 + ptime.tv_nsec) / 1000000000;
+ ptime.tv_nsec = (timePtr->usec * 1000 + ptime.tv_nsec) % 1000000000;
+#else
Tcl_Time now;
/*
@@ -553,6 +585,7 @@ Tcl_ConditionWait(
ptime.tv_sec = timePtr->sec + now.sec +
(timePtr->usec + now.usec) / 1000000;
ptime.tv_nsec = 1000 * ((timePtr->usec + now.usec) % 1000000);
+#endif
pthread_cond_timedwait(pcondPtr, pmutexPtr, &ptime);
}
}