CLOCK_MONOTONIC

Since nobody anwser my last post titled “pthread_mutex_timedlock base on the
CLOCK_MONOTONIC”. Here my test program showing that pthread_muxtex_timedlock
is affected by change of the real time clock even if the CLOCK_MONOTONIC is
used. The semaphore should be block for one nimute, but the main thread
forward the time by 1 hour, the semaphore unblock immediately. Can soneone
comment on it and suggest a way to have a mutex not affected by the change
of the real time clock.

Thanks.

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <time.h>
#include <semaphore.h>
#include <sys/stat.h>
#include <pthread.h>
#include <fcntl.h>
#include <assert.h>
#include <errno.h>
// Thread that creates and locks on a semaphore
void* ThreadSemaphoreLock(void * ptr)
{
timespec timeout;

timespec timeStart;
timespec timeEnd;
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_mutexattr_t attr;
int rc;
clock_gettime( CLOCK_REALTIME, &timeStart );
clock_gettime( CLOCK_MONOTONIC, &timeout );

timeout.tv_sec += 60; // Timeout in 60 seconds
timeout.tv_nsec = 0;

// Initializes the semaphore
pthread_mutex_init(&mutex,&attr );

// Try to lock the semaphore with a timeout value of 60 seconds
pthread_mutex_timedlock( &mutex, &timeout );

clock_gettime( CLOCK_REALTIME, &timeEnd );

printf(“The sem_timedwait timeout elapsed after %lf seconds\n”,
(( timeEnd.tv_sec - timeStart.tv_sec ) +
(double)( timeEnd.tv_nsec - timeStart.tv_nsec ) / (double)1000000000L) );

return NULL;
}


int main(int argc, char *argv)
{
struct timespec currTime;
pthread_attr_t attrThread;
pthread_t thread;
int rc;
// Creates and starts a thread
pthread_attr_init( &attrThread );
pthread_attr_setdetachstate( &attrThread, PTHREAD_CREATE_JOINABLE );
pthread_create( &thread, &attrThread, &ThreadSemaphoreLock, NULL);

// Wait for the thread to create and initialize
sleep(3);

// Changes the system time
clock_gettime(CLOCK_REALTIME, &currTime);

// Add 1 hour to current time
currTime.tv_sec += 3600;
currTime.tv_nsec = 0;

clock_settime(CLOCK_REALTIME, &currTime);

// Wait for the thread to finish
assert(pthread_join(thread,NULL)==0);;

// Set the time back to what it was
currTime.tv_sec -= 3600;
currTime.tv_nsec = 0;

clock_settime(CLOCK_REALTIME, &currTime);

return 0;
}

“Rejean Senecal” <rsenecal@oerlikon.ca-no-spam> wrote in
news:ab64gu$kis$1@inn.qnx.com:

Since nobody anwser my last post titled “pthread_mutex_timedlock base
on the CLOCK_MONOTONIC”. Here my test program showing that
pthread_muxtex_timedlock is affected by change of the real time clock
even if the CLOCK_MONOTONIC is used. The semaphore should be block for
one nimute, but the main thread forward the time by 1 hour, the
semaphore unblock immediately. Can soneone comment on it and suggest a
way to have a mutex not affected by the change of the real time clock.

There are few things wrong with your source code (struct timespec and main
should take a char* argv[], not a char*). Also, your test itself is also
incorrect. The first error is that you allocated the mutex you wish to do
a timed block on, inside the thread itself - you’re going to immediately
unblock, since there is no contention on the mutex. You also make no
attempt to lock a mutex anywhere else in your code, so I don’t see how you
could use the time out for anything, since you thread is the only one that
locks the mutex.

Also, according to the Xopen docs and our docs, pthread_mutex_timedlock()
is based on CLOCK_REALTIME, not CLOCK_MONOTONIC, so it’s (CLOCK_MONOTONIC)
use isn’t supposed to be supported.

I’ve changed your test case around, and also include a “monotonic version”
of the timed out function that should help you develop your own.

Hope this help,


Cheers,
Adam

QNX Software Systems Ltd.
[ amallory@qnx.com ]

With a PC, I always felt limited by the software available.
On Unix, I am limited only by my knowledge.
–Peter J. Schoenster <pschon@baste.magibox.net>


----demo.c----
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <time.h>
#include <semaphore.h>
#include <sys/stat.h>
#include <pthread.h>
#include <fcntl.h>
#include <assert.h>
#include <errno.h>
#include <inttypes.h>
#include <sys/neutrino.h>
#include <sched.h>


pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;

int pthread_mutex_monotimedlock(pthread_mutex_t *m, const struct timespec
*mt)
{
uint64_t t;
int ret;

t=timespec2nsec(mt);
if ((ret = TimerTimeout(CLOCK_MONOTONIC, TIMER_ABSTIME |
_NTO_TIMEOUT_MUTEX, 0, &t, 0)) != EOK)
return(ret);

if ( (ret = pthread_mutex_lock(m)) != EOK)
return(ret);

return(EOK);
}

// Thread that creates and locks on a semaphore
void* ThreadSemaphoreLock(void * ptr)
{
struct timespec timeout;
struct timespec timeStart;
struct timespec timeEnd;

clock_gettime( CLOCK_REALTIME, &timeStart );
clock_gettime( CLOCK_MONOTONIC, &timeout );

timeout.tv_sec += 10; // Timeout in 60 seconds
timeout.tv_nsec = 0;

printf(“Thread 2 attempting to do timedlock on mutex…blocking\n”);
if ((pthread_mutex_monotimedlock(&mutex, &timeout)) != ETIMEDOUT)
{
perror(“pthread_mutex_monotimedlock should have timed out”);
exit(EXIT_FAILURE);
}

clock_gettime( CLOCK_REALTIME, &timeEnd );

printf(“The sem_timedwait timeout elapsed after %f seconds\n”,
(( timeEnd.tv_sec - timeStart.tv_sec ) +
(double)( timeEnd.tv_nsec - timeStart.tv_nsec ) /
(double)1000000000L) );

return NULL;
}


int main(int argc, char argv[])
{
struct timespec currTime;
pthread_attr_t attrThread;
pthread_t thread;


/
lock out mutex */
pthread_mutex_lock(&mutex);

// Creates and starts a thread
pthread_attr_init( &attrThread );
pthread_attr_setdetachstate( &attrThread, PTHREAD_CREATE_JOINABLE );
pthread_create( &thread, &attrThread, &ThreadSemaphoreLock, NULL);

// Wait for the thread to create and initialize

printf(“Sleeping to sync\n”);
sleep(3);

// Changes the system time
clock_gettime(CLOCK_REALTIME, &currTime);

// Add 1 hour to current time
currTime.tv_sec += 3600;
currTime.tv_nsec = 0;

printf(“Moving Time ahead…\n”);
clock_settime(CLOCK_REALTIME, &currTime);

printf(“Main: waiting for thread to end.\n”);
// Wait for the thread to finish
assert(pthread_join(thread,NULL)==0);

// Set the time back to what it was
currTime.tv_sec -= 3600;
currTime.tv_nsec = 0;

printf(“Moving Time back…\n”);
clock_settime(CLOCK_REALTIME, &currTime);

pthread_mutex_unlock(&mutex);
return 0;
}

Anyone wondering about QSSL tech support? Come and read this!!!

“Adam Mallory” <amallory@qnx.com> wrote in message
news:Xns9209DCDB43F11amalloryqnxcom@209.226.137.4

“Rejean Senecal” <> rsenecal@oerlikon.ca-no-spam> > wrote in
news:ab64gu$kis$> 1@inn.qnx.com> :

Since nobody anwser my last post titled “pthread_mutex_timedlock base
on the CLOCK_MONOTONIC”. Here my test program showing that
pthread_muxtex_timedlock is affected by change of the real time clock
even if the CLOCK_MONOTONIC is used. The semaphore should be block for
one nimute, but the main thread forward the time by 1 hour, the
semaphore unblock immediately. Can soneone comment on it and suggest a
way to have a mutex not affected by the change of the real time clock.

There are few things wrong with your source code (struct timespec and main
should take a char* argv[], not a char*). Also, your test itself is also
incorrect. The first error is that you allocated the mutex you wish to do
a timed block on, inside the thread itself - you’re going to immediately
unblock, since there is no contention on the mutex. You also make no
attempt to lock a mutex anywhere else in your code, so I don’t see how you
could use the time out for anything, since you thread is the only one that
locks the mutex.

Also, according to the Xopen docs and our docs, pthread_mutex_timedlock()
is based on CLOCK_REALTIME, not CLOCK_MONOTONIC, so it’s (CLOCK_MONOTONIC)
use isn’t supposed to be supported.

I’ve changed your test case around, and also include a “monotonic version”
of the timed out function that should help you develop your own.

Hope this help,


Cheers,
Adam

QNX Software Systems Ltd.
[ > amallory@qnx.com > ]

With a PC, I always felt limited by the software available.
On Unix, I am limited only by my knowledge.
–Peter J. Schoenster <> pschon@baste.magibox.net


----demo.c----
#include <stdio.h
#include <stdlib.h
#include <pthread.h
#include <time.h
#include <semaphore.h
#include <sys/stat.h
#include <pthread.h
#include <fcntl.h
#include <assert.h
#include <errno.h
#include <inttypes.h
#include <sys/neutrino.h
#include <sched.h


pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;

int pthread_mutex_monotimedlock(pthread_mutex_t *m, const struct timespec
*mt)
{
uint64_t t;
int ret;

t=timespec2nsec(mt);
if ((ret = TimerTimeout(CLOCK_MONOTONIC, TIMER_ABSTIME |
_NTO_TIMEOUT_MUTEX, 0, &t, 0)) != EOK)
return(ret);

if ( (ret = pthread_mutex_lock(m)) != EOK)
return(ret);

return(EOK);
}

// Thread that creates and locks on a semaphore
void* ThreadSemaphoreLock(void * ptr)
{
struct timespec timeout;
struct timespec timeStart;
struct timespec timeEnd;

clock_gettime( CLOCK_REALTIME, &timeStart );
clock_gettime( CLOCK_MONOTONIC, &timeout );

timeout.tv_sec += 10; // Timeout in 60 seconds
timeout.tv_nsec = 0;

printf(“Thread 2 attempting to do timedlock on mutex…blocking\n”);
if ((pthread_mutex_monotimedlock(&mutex, &timeout)) != ETIMEDOUT)
{
perror(“pthread_mutex_monotimedlock should have timed out”);
exit(EXIT_FAILURE);
}

clock_gettime( CLOCK_REALTIME, &timeEnd );

printf(“The sem_timedwait timeout elapsed after %f seconds\n”,
(( timeEnd.tv_sec - timeStart.tv_sec ) +
(double)( timeEnd.tv_nsec - timeStart.tv_nsec ) /
(double)1000000000L) );

return NULL;
}


int main(int argc, char argv[])
{
struct timespec currTime;
pthread_attr_t attrThread;
pthread_t thread;


/
lock out mutex */
pthread_mutex_lock(&mutex);

// Creates and starts a thread
pthread_attr_init( &attrThread );
pthread_attr_setdetachstate( &attrThread, PTHREAD_CREATE_JOINABLE );
pthread_create( &thread, &attrThread, &ThreadSemaphoreLock, NULL);

// Wait for the thread to create and initialize

printf(“Sleeping to sync\n”);
sleep(3);

// Changes the system time
clock_gettime(CLOCK_REALTIME, &currTime);

// Add 1 hour to current time
currTime.tv_sec += 3600;
currTime.tv_nsec = 0;

printf(“Moving Time ahead…\n”);
clock_settime(CLOCK_REALTIME, &currTime);

printf(“Main: waiting for thread to end.\n”);
// Wait for the thread to finish
assert(pthread_join(thread,NULL)==0);

// Set the time back to what it was
currTime.tv_sec -= 3600;
currTime.tv_nsec = 0;

printf(“Moving Time back…\n”);
clock_settime(CLOCK_REALTIME, &currTime);

pthread_mutex_unlock(&mutex);
return 0;
}