blob: 7ed66eb75a4296d0f97bf17d31c3424e8fec67bf [file] [log] [blame]
robbiew0dc07652005-06-03 16:29:48 +00001/*
2* Copyright (c) 2005, Bull S.A.. All rights reserved.
3* Created by: Sebastien Decugis
4
5* This program is free software; you can redistribute it and/or modify it
6* under the terms of version 2 of the GNU General Public License as
7* published by the Free Software Foundation.
8*
9* This program is distributed in the hope that it would be useful, but
10* WITHOUT ANY WARRANTY; without even the implied warranty of
11* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12*
13* You should have received a copy of the GNU General Public License along
14* with this program; if not, write the Free Software Foundation, Inc., 59
15* Temple Place - Suite 330, Boston MA 02111-1307, USA.
16
robbiew0dc07652005-06-03 16:29:48 +000017* This sample test aims to check the following assertion:
18*
Garrett Cooper2c282152010-12-16 00:55:50 -080019* If several threads are waiting for a signal and this signal is generated
20* for a specific thread, only this thread is unblocked.
robbiew0dc07652005-06-03 16:29:48 +000021
22* The steps are:
23* -> mask SIGUSR1
24* -> create several threads which sigwait for SIGUSR1
25* -> pthread_kill one of the threads
26* -> Check than this thread has been awaken.
27
28* The test fails if the thread is not awaken.
29
30*/
31
robbiew0dc07652005-06-03 16:29:48 +000032/* We are testing conformance to IEEE Std 1003.1, 2003 Edition */
33#define _POSIX_C_SOURCE 200112L
34
35/******************************************************************************/
36/*************************** standard includes ********************************/
37/******************************************************************************/
38#include <pthread.h>
39#include <stdarg.h>
40#include <stdio.h>
41#include <stdlib.h>
42#include <string.h>
43#include <unistd.h>
44
45#include <signal.h>
46#include <errno.h>
47
48/******************************************************************************/
49/*************************** Test framework *******************************/
50/******************************************************************************/
Wanlong Gao8d9c0842012-03-09 15:52:19 +080051#include "../testfrmw/testfrmw.h"
52#include "../testfrmw/testfrmw.c"
robbiew0dc07652005-06-03 16:29:48 +000053/* This header is responsible for defining the following macros:
Garrett Cooper2c282152010-12-16 00:55:50 -080054 * UNRESOLVED(ret, descr);
55 * where descr is a description of the error and ret is an int
robbiew0dc07652005-06-03 16:29:48 +000056 * (error code for example)
57 * FAILED(descr);
58 * where descr is a short text saying why the test has failed.
59 * PASSED();
60 * No parameter.
Garrett Cooper2c282152010-12-16 00:55:50 -080061 *
robbiew0dc07652005-06-03 16:29:48 +000062 * Both three macros shall terminate the calling process.
63 * The testcase shall not terminate in any other maneer.
Garrett Cooper2c282152010-12-16 00:55:50 -080064 *
robbiew0dc07652005-06-03 16:29:48 +000065 * The other file defines the functions
66 * void output_init()
67 * void output(char * string, ...)
Garrett Cooper2c282152010-12-16 00:55:50 -080068 *
robbiew0dc07652005-06-03 16:29:48 +000069 * Those may be used to output information.
70 */
71
72/******************************************************************************/
73/**************************** Configuration ***********************************/
74/******************************************************************************/
75#ifndef VERBOSE
76#define VERBOSE 1
77#endif
78
79#define NTHREADS 5
80
81/******************************************************************************/
82/*************************** Test case ***********************************/
83/******************************************************************************/
84
85int n_awaken = 0;
86pthread_t last_awaken;
87sigset_t setusr;
88
89/* Thread function */
Garrett Coopere9410df2010-12-08 08:43:16 -080090void * threaded(void * arg)
robbiew0dc07652005-06-03 16:29:48 +000091{
92 int ret;
93 int sig;
94
95 /* The signal is already masked, because inherited from the parent */
96
97 /* wait for the signal */
Garrett Coopere9410df2010-12-08 08:43:16 -080098 ret = sigwait(&setusr, &sig);
robbiew0dc07652005-06-03 16:29:48 +000099
Garrett Cooper8fb1cdb2010-11-28 22:56:35 -0800100 if (ret != 0)
robbiew0dc07652005-06-03 16:29:48 +0000101 {
Garrett Coopere9410df2010-12-08 08:43:16 -0800102 UNRESOLVED(ret, "failed to wait for signal in thread");
robbiew0dc07652005-06-03 16:29:48 +0000103 }
104
105 n_awaken++;
106
107 last_awaken = pthread_self();
108
109 /* quit */
110 return NULL;
111}
112
113/* The main test function. */
Garrett Coopere9410df2010-12-08 08:43:16 -0800114int main(int argc, char * argv[])
robbiew0dc07652005-06-03 16:29:48 +0000115{
116 int ret, i;
117 pthread_t ch[ NTHREADS ];
118
119 /* Initialize output */
120 output_init();
121
122 /* Set the signal mask */
Garrett Coopere9410df2010-12-08 08:43:16 -0800123 ret = sigemptyset(&setusr);
robbiew0dc07652005-06-03 16:29:48 +0000124
Garrett Cooper8fb1cdb2010-11-28 22:56:35 -0800125 if (ret != 0)
robbiew0dc07652005-06-03 16:29:48 +0000126 {
Garrett Coopere9410df2010-12-08 08:43:16 -0800127 UNRESOLVED(ret, "Failed to empty signal set");
robbiew0dc07652005-06-03 16:29:48 +0000128 }
129
Garrett Coopere9410df2010-12-08 08:43:16 -0800130 ret = sigaddset(&setusr, SIGUSR1);
robbiew0dc07652005-06-03 16:29:48 +0000131
Garrett Cooper8fb1cdb2010-11-28 22:56:35 -0800132 if (ret != 0)
robbiew0dc07652005-06-03 16:29:48 +0000133 {
Garrett Coopere9410df2010-12-08 08:43:16 -0800134 UNRESOLVED(ret, "failed to add SIGUSR1 to signal set");
robbiew0dc07652005-06-03 16:29:48 +0000135 }
136
Garrett Coopere9410df2010-12-08 08:43:16 -0800137 ret = pthread_sigmask(SIG_BLOCK, &setusr, NULL);
robbiew0dc07652005-06-03 16:29:48 +0000138
Garrett Cooper8fb1cdb2010-11-28 22:56:35 -0800139 if (ret != 0)
robbiew0dc07652005-06-03 16:29:48 +0000140 {
Garrett Coopere9410df2010-12-08 08:43:16 -0800141 UNRESOLVED(ret, "Failed to block SIGUSR1");
robbiew0dc07652005-06-03 16:29:48 +0000142 }
143
144 /* Create the children */
145
Garrett Cooper8fb1cdb2010-11-28 22:56:35 -0800146 for (i = 0; i < NTHREADS; i++)
robbiew0dc07652005-06-03 16:29:48 +0000147 {
Garrett Coopere9410df2010-12-08 08:43:16 -0800148 ret = pthread_create(&ch[ i ], NULL, threaded, NULL);
robbiew0dc07652005-06-03 16:29:48 +0000149
Garrett Cooper8fb1cdb2010-11-28 22:56:35 -0800150 if (ret != 0)
robbiew0dc07652005-06-03 16:29:48 +0000151 {
Garrett Coopere9410df2010-12-08 08:43:16 -0800152 UNRESOLVED(ret, "Failed to create a thread");
robbiew0dc07652005-06-03 16:29:48 +0000153 }
154 }
155
156 /* raise the signal */
Garrett Coopere9410df2010-12-08 08:43:16 -0800157 ret = pthread_kill(ch[ 0 ], SIGUSR1);
robbiew0dc07652005-06-03 16:29:48 +0000158
Garrett Cooper8fb1cdb2010-11-28 22:56:35 -0800159 if (ret != 0)
robbiew0dc07652005-06-03 16:29:48 +0000160 {
Garrett Coopere9410df2010-12-08 08:43:16 -0800161 UNRESOLVED(ret, "Failed to raise the signal");
robbiew0dc07652005-06-03 16:29:48 +0000162 }
163
Garrett Coopere9410df2010-12-08 08:43:16 -0800164 sleep(1);
robbiew0dc07652005-06-03 16:29:48 +0000165
Garrett Cooper8fb1cdb2010-11-28 22:56:35 -0800166 if (n_awaken != 1)
robbiew0dc07652005-06-03 16:29:48 +0000167 {
Garrett Coopere9410df2010-12-08 08:43:16 -0800168 output("%d threads were awaken\n", n_awaken);
169 FAILED("Unexpected number of threads awaken");
robbiew0dc07652005-06-03 16:29:48 +0000170 }
171
Garrett Cooper3b4d3ce2010-11-24 00:03:17 -0800172 if (!pthread_equal(last_awaken, ch[0]))
robbiew0dc07652005-06-03 16:29:48 +0000173 {
Garrett Coopere9410df2010-12-08 08:43:16 -0800174 FAILED("The awaken thread is not the signal target one.");
robbiew0dc07652005-06-03 16:29:48 +0000175 }
176
177 /* Wake other threads */
Garrett Cooper8fb1cdb2010-11-28 22:56:35 -0800178 for (i = 1; i < NTHREADS ; i++)
robbiew0dc07652005-06-03 16:29:48 +0000179 {
Garrett Coopere9410df2010-12-08 08:43:16 -0800180 ret = pthread_kill(ch[ i ], SIGUSR1);
robbiew0dc07652005-06-03 16:29:48 +0000181
Garrett Cooper8fb1cdb2010-11-28 22:56:35 -0800182 if (ret != 0)
robbiew0dc07652005-06-03 16:29:48 +0000183 {
Garrett Coopere9410df2010-12-08 08:43:16 -0800184 UNRESOLVED(ret, "Failed to raise the signal");
robbiew0dc07652005-06-03 16:29:48 +0000185 }
186 }
187
188 /* Wait for child thread termination */
Garrett Cooper8fb1cdb2010-11-28 22:56:35 -0800189 for (i = 0; i < NTHREADS; i++)
robbiew0dc07652005-06-03 16:29:48 +0000190 {
Garrett Coopere9410df2010-12-08 08:43:16 -0800191 ret = pthread_join(ch[ i ], NULL);
robbiew0dc07652005-06-03 16:29:48 +0000192
Garrett Cooper8fb1cdb2010-11-28 22:56:35 -0800193 if (ret != 0)
robbiew0dc07652005-06-03 16:29:48 +0000194 {
Garrett Coopere9410df2010-12-08 08:43:16 -0800195 UNRESOLVED(ret, "Failed to join the thread");
robbiew0dc07652005-06-03 16:29:48 +0000196 }
197 }
198
199 /* Test passed */
200#if VERBOSE > 0
201
Garrett Coopere9410df2010-12-08 08:43:16 -0800202 output("Test passed\n");
robbiew0dc07652005-06-03 16:29:48 +0000203
204#endif
205
206 PASSED;
Chris Dearmanec6edca2012-10-17 19:54:01 -0700207}