summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
authorMatthias Liertzer <matthias@liertzer.at>2017-12-31 02:23:56 +0100
committerMatthias Liertzer <matthias@liertzer.at>2018-01-02 02:22:59 +0100
commitfb91c4fcde6a622a8ab799fa1ca4e4d09f854d8b (patch)
tree33450213354787a13b4334d24787281d7f4198f7 /test
parentab7a2302f2fa19b96c3597946be9e67b6b286d72 (diff)
downloadlibfaketime-fb91c4fcde6a622a8ab799fa1ca4e4d09f854d8b.tar.gz
Implement a fix for pthread_cond_timedwait with faketime
pthread_cond_timedwait takes an absolute time as an argument, which the function directly passes on to the kernel via the futex syscall. In an application this absolute time argument is calculated via the fake times provided by libfaketime. Since the kernel has no knowledge of the fake time, pthread_cond_timedwait must be redefined such that it converts the fake time back to real time before passing it on.
Diffstat (limited to 'test')
-rw-r--r--test/Makefile2
-rw-r--r--test/timetest.c67
2 files changed, 68 insertions, 1 deletions
diff --git a/test/Makefile b/test/Makefile
index f2d2f92..94d1a2e 100644
--- a/test/Makefile
+++ b/test/Makefile
@@ -1,7 +1,7 @@
CC = gcc
CFLAGS = -std=gnu99 -Wall -DFAKE_STAT -Werror -Wextra
-LDFLAGS = -lrt
+LDFLAGS = -lrt -lpthread
SRC = timetest.c
OBJ = ${SRC:.c=.o}
diff --git a/test/timetest.c b/test/timetest.c
index 79597b0..4e3515c 100644
--- a/test/timetest.c
+++ b/test/timetest.c
@@ -18,6 +18,7 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
+#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
@@ -31,6 +32,8 @@
#endif
#ifndef __APPLE__
+#include <pthread.h>
+#include <errno.h>
#include <signal.h>
#define VERBOSE 0
@@ -49,6 +52,64 @@ handler(int sig, siginfo_t *si, void *uc)
printf("Caught signal %d\n", sig);
}
}
+
+void* pthread_test(void* args)
+{
+ pthread_mutex_t fakeMutex = PTHREAD_MUTEX_INITIALIZER;
+ pthread_cond_t fakeCond = PTHREAD_COND_INITIALIZER;
+
+ pthread_cond_t monotonic_cond;
+ pthread_condattr_t attr;
+
+ struct timespec timeToWait, now;
+ int rt;
+
+ args = args; // silence compiler warning about unused argument
+
+ clock_gettime(CLOCK_REALTIME, &now);
+ timeToWait.tv_sec = now.tv_sec+1;
+ timeToWait.tv_nsec = now.tv_nsec;
+
+ printf("pthread_cond_timedwait: CLOCK_REALTIME test\n");
+ printf("(Intentionally sleeping 1 second...)\n");
+ fflush(stdout);
+
+ pthread_mutex_lock(&fakeMutex);
+ rt = pthread_cond_timedwait(&fakeCond, &fakeMutex, &timeToWait);
+ if (rt != ETIMEDOUT)
+ {
+ printf("pthread_cond_timedwait failed\n");
+ exit(EXIT_FAILURE);
+ }
+ pthread_mutex_unlock(&fakeMutex);
+
+
+ pthread_condattr_init(&attr);
+ pthread_condattr_setclock(&attr, CLOCK_MONOTONIC);
+ pthread_cond_init(&monotonic_cond, &attr);
+
+ clock_gettime(CLOCK_MONOTONIC, &now);
+ timeToWait.tv_sec = now.tv_sec+1;
+ timeToWait.tv_nsec = now.tv_nsec;
+
+ printf("pthread_cond_timedwait: CLOCK_MONOTONIC test\n");
+ printf("(Intentionally sleeping 1 second...)\n");
+ fflush(stdout);
+
+ pthread_mutex_lock(&fakeMutex);
+ rt = pthread_cond_timedwait(&monotonic_cond, &fakeMutex, &timeToWait);
+ if (rt != ETIMEDOUT)
+ {
+ printf("pthread_cond_timedwait failed\n");
+ exit(EXIT_FAILURE);
+ }
+ pthread_mutex_unlock(&fakeMutex);
+
+ pthread_cond_destroy(&monotonic_cond);
+
+ return NULL;
+}
+
#endif
int main (int argc, char **argv)
@@ -69,6 +130,12 @@ int main (int argc, char **argv)
#endif
#ifndef __APPLE__
+ pthread_t thread;
+ void *ret;
+
+ pthread_create(&thread, NULL, pthread_test, NULL);
+ pthread_join(thread, &ret);
+
sa.sa_flags = SA_SIGINFO;
sa.sa_sigaction = handler;
sigemptyset(&sa.sa_mask);