gettimeofday vs. CLOCK_MONOTONIC

Prasanta Sadhukhan <[email protected]>
Newsgroups org.kernel.vger.linux-c-programming
Message-ID <[email protected]>
Hi All,

We are trying to see if changing the system date(hardware clock) during 
sleep time of a process causes the process to exit abruptly or not. It 
seems when we use gettimeofday(), the process hangs but when we use 
clock_gettime(...,CLOCK_MONOTONIC) by defining USE_MONOTONIC in the 
attached c file the program works.
Can anyone tell me why gettimeofday() will cause the process to hang and 
why clock_gettime() will work?

Thanks in advance
Regards
Prasanta
clocktest.c (text/x-csrc, 2.4 KB)
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <time.h>
#include <semaphore.h>
#include <errno.h>

#undef USE_MONOTONIC


sem_t sem_l1, sem_l2, sem_l3;

void
setclock(
	const char *d)
{
	char buf[256];

	sprintf(buf, "/bin/date %s", d);
	system(buf);

	sprintf(buf, "/sbin/hwclock -w");
	system(buf);
}


void *
thread1(
	void *data)
{
#ifdef USE_MONOTONIC
	pthread_condattr_t ca;
#endif
	pthread_cond_t cond  = PTHREAD_COND_INITIALIZER;
	pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
	struct timeval tp;
	struct timespec ts;
	int rc;

#ifdef USE_MONOTONIC
	if ((rc = pthread_condattr_init(&ca)) != 0) {
		printf("thread1: can't condattr_init, rc=%d\n", rc);
		exit(1);
	}

	if ((rc = pthread_condattr_setclock(&ca, CLOCK_MONOTONIC)) != 0) {
		printf("thread1: can't condattr_setclock, rc=%d\n", rc);
		exit(1);
	}

	if ((rc = pthread_cond_init(&cond, &ca)) != 0) {
		printf("thread1: can't cond_init, rc=%d\n", rc);
		exit(1);
	}
#endif

	if ((rc = pthread_mutex_lock(&mutex)) != 0) {
		printf("thread1: can't lock mutex, rc=%d\n", rc);
		exit(1);
	}

#ifdef USE_MONOTONIC
	if ((rc = clock_gettime(CLOCK_MONOTONIC, &ts)) != 0) {
		printf("thread1: can't gettime, rc=%d\n", rc);
	}
#else
	if ((rc = gettimeofday(&tp, NULL)) != 0) {
		printf("thread1: can't get time of day, rc=%d\n", rc);
		exit(1);
	}

	ts.tv_sec = tp.tv_sec;
	ts.tv_nsec = tp.tv_usec * 1000;
#endif

	ts.tv_sec += 10;			// wait for ten seconds

	sem_wait(&sem_l1);

	puts("thread1: calling pthread_cond_timedwait...");

	rc = pthread_cond_timedwait(&cond, &mutex, &ts);
	if (rc == ETIMEDOUT) {
		puts("thread1: ETIMEDOUT");
	} else {
		printf("thread1: timedwait result=%d\n", rc);
	}

	pthread_mutex_unlock(&mutex);

	puts("thread1: done");

	sem_post(&sem_l3);

	pthread_exit(NULL);
}

void *
thread2(
	void *data)
{
	puts("thread2: starting test");

	setclock("010100002009");

	sem_post(&sem_l1);

	sleep(2);

	setclock("010100002010");

	pthread_exit(NULL);
}


int
main(
	int argc,
	char *argv[])
{
	pthread_t t1, t2;
	int rc;

	sem_init(&sem_l1, 0, 0);
	sem_init(&sem_l2, 0, 0);
	sem_init(&sem_l3, 0, 0);

	puts("main: starting threads");

	if ((rc = pthread_create(&t1, NULL, thread1, NULL)) != 0) {
		printf("error creating thread1, rc=%d\n", rc);
		return 1;
	}

	if ((rc = pthread_create(&t2, NULL, thread2, NULL)) != 0) {
		printf("error creating thread2, rc=%d\n", rc);
		return 1;
	}

	sem_wait(&sem_l3);

	setclock("010100002009");

	puts("main: exiting");

	return 0;
}
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.