memcheck/tests/sh-mem-random.c: Set huge_addr to 240GB
[valgrind.git] / drd / tests / pth_mutex_signal.c
blobc85c80a500ff4eb356c198f3052089bd20e14af9
1 /*
2 * Verify that pthread_mutex_lock() is not interrupted by a signal.
4 * See also https://bugs.kde.org/show_bug.cgi?id=445743.
5 */
7 #include <assert.h>
8 #include <pthread.h>
9 #include <signal.h>
10 #include <stdio.h>
11 #include <stdlib.h>
12 #include <string.h>
13 #include <unistd.h>
15 #define STACK_SIZE 1024 * 512
16 #define LONG_SLEEP_TIME 1000000
18 void long_sleep(void)
20 for (int i = 0; i < LONG_SLEEP_TIME; i += 1000)
22 usleep(1000);
26 void *contender_start(void *arg)
28 pthread_mutex_t *mutex = arg;
29 int ret;
31 ret = pthread_mutex_lock(mutex);
32 assert(ret == 0);
33 fprintf(stderr, "contender locked mutex\n");
34 fprintf(stderr, "contender unlocking mutex\n");
35 pthread_mutex_unlock(mutex);
36 fprintf(stderr, "contender unlocked mutex\n");
37 return NULL;
40 void nullHandler(int signal, siginfo_t *info, void *context)
42 static const char *msg = "nullHandler running\n";
44 write(STDERR_FILENO, msg, strlen(msg));
47 int main ()
49 pthread_mutex_t mutex;
50 pthread_mutexattr_t mutex_attr;
51 pthread_attr_t thread_attr_contender;
52 pthread_t contender;
53 struct sigaction signalAction;
55 // install signal handler
56 signalAction.sa_sigaction = nullHandler;
57 sigfillset(&signalAction.sa_mask);
58 signalAction.sa_flags = SA_SIGINFO;
59 sigaction(SIGINT, &signalAction, NULL);
61 // initialize the mutex
62 pthread_mutexattr_init(&mutex_attr);
63 pthread_mutexattr_setprotocol(&mutex_attr, PTHREAD_PRIO_INHERIT);
64 pthread_mutex_init(&mutex, &mutex_attr);
65 fprintf(stderr, "mutex initialized\n");
67 // lock mutex
68 pthread_mutex_lock(&mutex);
70 // init and create contender
71 pthread_attr_init(&thread_attr_contender);
72 pthread_attr_setstacksize(&thread_attr_contender, STACK_SIZE);
73 pthread_attr_setinheritsched(&thread_attr_contender, PTHREAD_EXPLICIT_SCHED);
74 fprintf(stderr, "thread attributes initialized\n");
75 if (pthread_create(&contender, &thread_attr_contender, &contender_start,
76 &mutex) != 0) {
77 fprintf(stderr, "failed to create thread\n");
78 return 1;
80 fprintf(stderr, "thread created\n");
81 pthread_attr_destroy(&thread_attr_contender);
83 // Block signals in the current thread such that signals are delivered to the
84 // 'contender' thread.
86 sigset_t mask;
87 sigfillset(&mask);
88 pthread_sigmask(SIG_BLOCK, &mask, NULL);
91 // wait until the thread is sleeping inside pthread_mutex_lock().
92 fprintf(stderr, "sleeping\n");
93 long_sleep();
95 // signal thread
96 fprintf(stderr, "signalling\n");
97 pthread_kill(contender, SIGINT);
99 fprintf(stderr, "sleeping\n");
100 long_sleep();
102 fprintf(stderr, "unlocking\n");
103 pthread_mutex_unlock(&mutex);
105 long_sleep();
107 // finally wait for the thread
108 fprintf(stderr, "joining thread\n");
109 pthread_join(contender, NULL);
111 return 0;