1f08c3bdfSopenharmony_ci/* 2f08c3bdfSopenharmony_ci * Copyright (C) Bull S.A. 2001 3f08c3bdfSopenharmony_ci * Copyright (c) International Business Machines Corp., 2001 4f08c3bdfSopenharmony_ci * 5f08c3bdfSopenharmony_ci * This program is free software; you can redistribute it and/or modify 6f08c3bdfSopenharmony_ci * it under the terms of the GNU General Public License as published by 7f08c3bdfSopenharmony_ci * the Free Software Foundation; either version 2 of the License, or 8f08c3bdfSopenharmony_ci * (at your option) any later version. 9f08c3bdfSopenharmony_ci * 10f08c3bdfSopenharmony_ci * This program is distributed in the hope that it will be useful, 11f08c3bdfSopenharmony_ci * but WITHOUT ANY WARRANTY; without even the implied warranty of 12f08c3bdfSopenharmony_ci * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See 13f08c3bdfSopenharmony_ci * the GNU General Public License for more details. 14f08c3bdfSopenharmony_ci * 15f08c3bdfSopenharmony_ci * You should have received a copy of the GNU General Public License 16f08c3bdfSopenharmony_ci * along with this program; if not, write to the Free Software 17f08c3bdfSopenharmony_ci * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 18f08c3bdfSopenharmony_ci */ 19f08c3bdfSopenharmony_ci 20f08c3bdfSopenharmony_ci/******************************************************************************/ 21f08c3bdfSopenharmony_ci/* */ 22f08c3bdfSopenharmony_ci/* Dec-03-2001 Created: Jacky Malcles & Jean Noel Cordenner */ 23f08c3bdfSopenharmony_ci/* These tests are adapted from AIX float PVT tests. */ 24f08c3bdfSopenharmony_ci/* */ 25f08c3bdfSopenharmony_ci/******************************************************************************/ 26f08c3bdfSopenharmony_ci#include "tfloat.h" 27f08c3bdfSopenharmony_ci 28f08c3bdfSopenharmony_ci#include "test.h" 29f08c3bdfSopenharmony_ci 30f08c3bdfSopenharmony_ci#define SAFE_FREE(p) { if (p) { free(p); (p)=NULL; } } 31f08c3bdfSopenharmony_ci/* LTP status reporting */ 32f08c3bdfSopenharmony_cichar *TCID; /* Test program identifier. */ 33f08c3bdfSopenharmony_ciint TST_TOTAL = 1; /* Total number of test cases. */ 34f08c3bdfSopenharmony_ci 35f08c3bdfSopenharmony_ci/* To avoid extensive modifications to the code, use this bodge */ 36f08c3bdfSopenharmony_ci#define exit(x) myexit(x) 37f08c3bdfSopenharmony_ci 38f08c3bdfSopenharmony_civoid myexit(int x) 39f08c3bdfSopenharmony_ci{ 40f08c3bdfSopenharmony_ci if (x) 41f08c3bdfSopenharmony_ci tst_resm(TFAIL, "Test failed"); 42f08c3bdfSopenharmony_ci else 43f08c3bdfSopenharmony_ci tst_resm(TPASS, "Test passed"); 44f08c3bdfSopenharmony_ci tst_exit(); 45f08c3bdfSopenharmony_ci} 46f08c3bdfSopenharmony_ci 47f08c3bdfSopenharmony_ciTH_DATA *pcom; 48f08c3bdfSopenharmony_ciTH_DATA **tabcom; 49f08c3bdfSopenharmony_ciTH_DATA **tabcour; 50f08c3bdfSopenharmony_ci#ifndef PATH_MAX 51f08c3bdfSopenharmony_ci#define PATH_MAX 1024 52f08c3bdfSopenharmony_ci#endif 53f08c3bdfSopenharmony_cichar datadir[PATH_MAX]; /* DATA directory */ 54f08c3bdfSopenharmony_ci 55f08c3bdfSopenharmony_ci#ifndef PTHREAD_THREADS_MAX 56f08c3bdfSopenharmony_ci#define PTHREAD_THREADS_MAX 1024 57f08c3bdfSopenharmony_ci#endif 58f08c3bdfSopenharmony_ci#define DEFAULT_NUM_THREADS 20 59f08c3bdfSopenharmony_ciint num_threads = DEFAULT_NUM_THREADS; 60f08c3bdfSopenharmony_ciint num_loops = 500; 61f08c3bdfSopenharmony_ci 62f08c3bdfSopenharmony_ciint sig_cancel = 0; /* flag set by handle_signals to tell initial thread 63f08c3bdfSopenharmony_ci to stop creating new threads (signal caught) */ 64f08c3bdfSopenharmony_ci 65f08c3bdfSopenharmony_ciint indice = 0; /* # of threads created, to be canceled by handle_signals 66f08c3bdfSopenharmony_ci or waited for by initial thread */ 67f08c3bdfSopenharmony_ci 68f08c3bdfSopenharmony_cipthread_mutex_t sig_mutex; 69f08c3bdfSopenharmony_cipthread_t *threads; 70f08c3bdfSopenharmony_ci 71f08c3bdfSopenharmony_ciint debug = 0; 72f08c3bdfSopenharmony_ciint true = 1; 73f08c3bdfSopenharmony_ci 74f08c3bdfSopenharmony_cistatic void *handle_signals(void *); 75f08c3bdfSopenharmony_ci 76f08c3bdfSopenharmony_cistatic void sys_error(const char *, int); 77f08c3bdfSopenharmony_ci 78f08c3bdfSopenharmony_ciconst double EPS = 0.1e-300; 79f08c3bdfSopenharmony_ci 80f08c3bdfSopenharmony_ciconst int nb_func = NB_FUNC; 81f08c3bdfSopenharmony_ci 82f08c3bdfSopenharmony_ciint generate(char *datadir, char *bin_path) 83f08c3bdfSopenharmony_ci{ 84f08c3bdfSopenharmony_ci char *cmdline; 85f08c3bdfSopenharmony_ci char *fmt = "cd %s; %s/%s %s"; 86f08c3bdfSopenharmony_ci 87f08c3bdfSopenharmony_ci cmdline = malloc(2 * strlen(bin_path) + strlen(datadir) + strlen(GENERATOR) + strlen(fmt)); 88f08c3bdfSopenharmony_ci if (cmdline == NULL) 89f08c3bdfSopenharmony_ci return (1); 90f08c3bdfSopenharmony_ci sprintf(cmdline, fmt, datadir, bin_path, GENERATOR, bin_path); 91f08c3bdfSopenharmony_ci system(cmdline); 92f08c3bdfSopenharmony_ci free(cmdline); 93f08c3bdfSopenharmony_ci return (0); 94f08c3bdfSopenharmony_ci} 95f08c3bdfSopenharmony_ci 96f08c3bdfSopenharmony_cistatic void cleanup(void) 97f08c3bdfSopenharmony_ci{ 98f08c3bdfSopenharmony_ci tst_rmdir(); 99f08c3bdfSopenharmony_ci} 100f08c3bdfSopenharmony_ci 101f08c3bdfSopenharmony_ciint main(int argc, char *argv[]) 102f08c3bdfSopenharmony_ci{ 103f08c3bdfSopenharmony_ci int opt = 0; 104f08c3bdfSopenharmony_ci pid_t pid; 105f08c3bdfSopenharmony_ci 106f08c3bdfSopenharmony_ci char *bin_path, *ltproot; 107f08c3bdfSopenharmony_ci void *exit_value; 108f08c3bdfSopenharmony_ci pthread_attr_t newattr; 109f08c3bdfSopenharmony_ci pthread_t sig_hand; 110f08c3bdfSopenharmony_ci size_t stacksize = 2093056; 111f08c3bdfSopenharmony_ci int th_num; 112f08c3bdfSopenharmony_ci int retvalend = 0; 113f08c3bdfSopenharmony_ci int retval = 0; 114f08c3bdfSopenharmony_ci int error = 0; 115f08c3bdfSopenharmony_ci /*int time=1; */ 116f08c3bdfSopenharmony_ci int i; 117f08c3bdfSopenharmony_ci 118f08c3bdfSopenharmony_ci /* Generate test ID from invocation name */ 119f08c3bdfSopenharmony_ci if ((TCID = strrchr(argv[0], '/')) != NULL) 120f08c3bdfSopenharmony_ci TCID++; 121f08c3bdfSopenharmony_ci else 122f08c3bdfSopenharmony_ci TCID = argv[0]; 123f08c3bdfSopenharmony_ci ltproot = getenv("LTPROOT"); 124f08c3bdfSopenharmony_ci if (ltproot == NULL || strlen(ltproot) == 0) { 125f08c3bdfSopenharmony_ci tst_brkm(TBROK, NULL, 126f08c3bdfSopenharmony_ci "You must set $LTPROOT before executing this test"); 127f08c3bdfSopenharmony_ci } 128f08c3bdfSopenharmony_ci bin_path = malloc(strlen(ltproot) + 16); 129f08c3bdfSopenharmony_ci if (bin_path == NULL) { 130f08c3bdfSopenharmony_ci tst_brkm(TBROK | TERRNO, NULL, "malloc failed"); 131f08c3bdfSopenharmony_ci } 132f08c3bdfSopenharmony_ci sprintf(bin_path, "%s/testcases/bin", ltproot); 133f08c3bdfSopenharmony_ci 134f08c3bdfSopenharmony_ci tst_tmpdir(); 135f08c3bdfSopenharmony_ci 136f08c3bdfSopenharmony_ci setbuf(stdout, NULL); 137f08c3bdfSopenharmony_ci setbuf(stderr, NULL); 138f08c3bdfSopenharmony_ci datadir[0] = '.'; 139f08c3bdfSopenharmony_ci datadir[1] = '\0'; 140f08c3bdfSopenharmony_ci 141f08c3bdfSopenharmony_ci if (argc != 1) { 142f08c3bdfSopenharmony_ci while ((opt = getopt(argc, argv, "vn:l:D:?")) != EOF) { 143f08c3bdfSopenharmony_ci switch (opt) { 144f08c3bdfSopenharmony_ci case 'D': 145f08c3bdfSopenharmony_ci strncpy(datadir, optarg, PATH_MAX); 146f08c3bdfSopenharmony_ci break; 147f08c3bdfSopenharmony_ci case 'l': 148f08c3bdfSopenharmony_ci num_loops = atoi(optarg); 149f08c3bdfSopenharmony_ci break; 150f08c3bdfSopenharmony_ci case 'n': 151f08c3bdfSopenharmony_ci num_threads = atoi(optarg); 152f08c3bdfSopenharmony_ci break; 153f08c3bdfSopenharmony_ci case 'v': 154f08c3bdfSopenharmony_ci ++debug; /* verbose mode */ 155f08c3bdfSopenharmony_ci break; 156f08c3bdfSopenharmony_ci default: 157f08c3bdfSopenharmony_ci fprintf(stderr, 158f08c3bdfSopenharmony_ci "usage: %s [-n number_of_threads] [-v]\n", 159f08c3bdfSopenharmony_ci argv[0]); 160f08c3bdfSopenharmony_ci fprintf(stderr, "[-l number_of_loops] "); 161f08c3bdfSopenharmony_ci fprintf(stderr, "[-D DATAs absolute path]\n"); 162f08c3bdfSopenharmony_ci exit(1); 163f08c3bdfSopenharmony_ci } 164f08c3bdfSopenharmony_ci } 165f08c3bdfSopenharmony_ci } 166f08c3bdfSopenharmony_ci switch (pid = fork()) { 167f08c3bdfSopenharmony_ci case -1: 168f08c3bdfSopenharmony_ci tst_brkm(TBROK | TERRNO, cleanup, "fork failed"); 169f08c3bdfSopenharmony_ci case 0: 170f08c3bdfSopenharmony_ci generate(datadir, bin_path); 171f08c3bdfSopenharmony_ci exit(0); 172f08c3bdfSopenharmony_ci default: 173f08c3bdfSopenharmony_ci waitpid(pid, NULL, 0); 174f08c3bdfSopenharmony_ci } 175f08c3bdfSopenharmony_ci SAFE_FREE(bin_path); 176f08c3bdfSopenharmony_ci 177f08c3bdfSopenharmony_ci if (debug) { 178f08c3bdfSopenharmony_ci tst_resm(TINFO, 179f08c3bdfSopenharmony_ci "%s: will run for %d loops; using %s as a data directory", 180f08c3bdfSopenharmony_ci argv[0], num_loops, datadir); 181f08c3bdfSopenharmony_ci } 182f08c3bdfSopenharmony_ci if (num_threads <= 0) { 183f08c3bdfSopenharmony_ci tst_resm(TWARN, 184f08c3bdfSopenharmony_ci "num_threads undefined or incorrect, using \"1\""); 185f08c3bdfSopenharmony_ci num_threads = 1; 186f08c3bdfSopenharmony_ci } 187f08c3bdfSopenharmony_ci 188f08c3bdfSopenharmony_ci if (nb_func * num_threads > PTHREAD_THREADS_MAX - 2) 189f08c3bdfSopenharmony_ci while (nb_func * num_threads > PTHREAD_THREADS_MAX - 2) 190f08c3bdfSopenharmony_ci num_threads--; 191f08c3bdfSopenharmony_ci if (debug) 192f08c3bdfSopenharmony_ci tst_resm(TINFO, 193f08c3bdfSopenharmony_ci "%s: will run %d functions, %d threads per function", 194f08c3bdfSopenharmony_ci argv[0], nb_func, num_threads); 195f08c3bdfSopenharmony_ci 196f08c3bdfSopenharmony_ci retval = pthread_mutex_init(&sig_mutex, NULL); 197f08c3bdfSopenharmony_ci if (retval != 0) 198f08c3bdfSopenharmony_ci sys_error("main : mutex_init(&sig_mutex) FAILED", __LINE__); 199f08c3bdfSopenharmony_ci 200f08c3bdfSopenharmony_ci retval = pthread_create(&sig_hand, NULL, handle_signals, NULL); 201f08c3bdfSopenharmony_ci if (retval != 0) 202f08c3bdfSopenharmony_ci sys_error("main : create(&sig_hand) FAILED", __LINE__); 203f08c3bdfSopenharmony_ci 204f08c3bdfSopenharmony_ci /* 205f08c3bdfSopenharmony_ci * Start all calculation threads... 206f08c3bdfSopenharmony_ci */ 207f08c3bdfSopenharmony_ci threads = malloc(nb_func * num_threads * sizeof(pthread_t)); 208f08c3bdfSopenharmony_ci if (threads == NULL) 209f08c3bdfSopenharmony_ci tst_brkm(TFAIL | TERRNO, cleanup, "malloc failed"); 210f08c3bdfSopenharmony_ci 211f08c3bdfSopenharmony_ci tabcom = malloc((sizeof(TH_DATA *) * nb_func * num_threads)); 212f08c3bdfSopenharmony_ci if (!tabcom) 213f08c3bdfSopenharmony_ci tst_brkm(TFAIL | TERRNO, cleanup, "malloc failed"); 214f08c3bdfSopenharmony_ci tabcour = tabcom; 215f08c3bdfSopenharmony_ci 216f08c3bdfSopenharmony_ci retval = pthread_attr_init(&newattr); 217f08c3bdfSopenharmony_ci if (retval != 0) 218f08c3bdfSopenharmony_ci sys_error("main : attr_init(&newattr) FAILED", __LINE__); 219f08c3bdfSopenharmony_ci 220f08c3bdfSopenharmony_ci if (pthread_attr_setstacksize(&newattr, stacksize)) 221f08c3bdfSopenharmony_ci sys_error("main: pthread_attr_setstacksize failed", __LINE__); 222f08c3bdfSopenharmony_ci 223f08c3bdfSopenharmony_ci retval = pthread_attr_setdetachstate(&newattr, PTHREAD_CREATE_JOINABLE); 224f08c3bdfSopenharmony_ci if (retval != 0) 225f08c3bdfSopenharmony_ci sys_error("main : attr_setdetachstate(&newattr) FAILED", 226f08c3bdfSopenharmony_ci __LINE__); 227f08c3bdfSopenharmony_ci 228f08c3bdfSopenharmony_ci /* run the nb_func functions on num_threads */ 229f08c3bdfSopenharmony_ci 230f08c3bdfSopenharmony_ci indice = 0; 231f08c3bdfSopenharmony_ci for (i = 0; i < nb_func; i++) { 232f08c3bdfSopenharmony_ci 233f08c3bdfSopenharmony_ci for (th_num = 0; th_num < num_threads; th_num++) { 234f08c3bdfSopenharmony_ci 235f08c3bdfSopenharmony_ci /* allocate struct of commucation with the thread */ 236f08c3bdfSopenharmony_ci pcom = calloc(1, sizeof(TH_DATA)); 237f08c3bdfSopenharmony_ci if (pcom == NULL) 238f08c3bdfSopenharmony_ci tst_brkm(TFAIL | TERRNO, cleanup, 239f08c3bdfSopenharmony_ci "calloc failed"); 240f08c3bdfSopenharmony_ci *tabcour = (TH_DATA *) pcom; 241f08c3bdfSopenharmony_ci tabcour++; 242f08c3bdfSopenharmony_ci /* 243f08c3bdfSopenharmony_ci * update structure of communication 244f08c3bdfSopenharmony_ci */ 245f08c3bdfSopenharmony_ci pcom->th_num = th_num; 246f08c3bdfSopenharmony_ci pcom->th_func = th_func[i]; 247f08c3bdfSopenharmony_ci 248f08c3bdfSopenharmony_ci pthread_mutex_lock(&sig_mutex); 249f08c3bdfSopenharmony_ci 250f08c3bdfSopenharmony_ci if (sig_cancel) { /* stop processing right now! */ 251f08c3bdfSopenharmony_ci pthread_mutex_unlock(&sig_mutex); 252f08c3bdfSopenharmony_ci goto finished; 253f08c3bdfSopenharmony_ci } 254f08c3bdfSopenharmony_ci retval = pthread_create(&threads[indice], &newattr, 255f08c3bdfSopenharmony_ci thread_code, (void *)pcom); 256f08c3bdfSopenharmony_ci if (retval != 0) 257f08c3bdfSopenharmony_ci sys_error("main : create FAILED", __LINE__); 258f08c3bdfSopenharmony_ci indice++; 259f08c3bdfSopenharmony_ci pthread_mutex_unlock(&sig_mutex); 260f08c3bdfSopenharmony_ci 261f08c3bdfSopenharmony_ci } /* num_threads */ 262f08c3bdfSopenharmony_ci } /* for i */ 263f08c3bdfSopenharmony_ci 264f08c3bdfSopenharmony_ci /*alarm(60*time); *//* start all threads for TEST_time */ 265f08c3bdfSopenharmony_ci 266f08c3bdfSopenharmony_ci /* 267f08c3bdfSopenharmony_ci * Wait for the threads finish their task 268f08c3bdfSopenharmony_ci * pthread_join () will block 269f08c3bdfSopenharmony_ci */ 270f08c3bdfSopenharmony_ci 271f08c3bdfSopenharmony_cifinished: 272f08c3bdfSopenharmony_ci if (debug) { 273f08c3bdfSopenharmony_ci tst_resm(TINFO, 274f08c3bdfSopenharmony_ci "initial thread: Waiting for %d threads to finish", 275f08c3bdfSopenharmony_ci indice); 276f08c3bdfSopenharmony_ci } 277f08c3bdfSopenharmony_ci tabcour = tabcom; 278f08c3bdfSopenharmony_ci 279f08c3bdfSopenharmony_ci for (th_num = 0; th_num < indice; th_num++) { 280f08c3bdfSopenharmony_ci retvalend = pthread_join(threads[th_num], &exit_value); 281f08c3bdfSopenharmony_ci if (retvalend != 0) 282f08c3bdfSopenharmony_ci sys_error("finish : join FAILED", __LINE__); 283f08c3bdfSopenharmony_ci 284f08c3bdfSopenharmony_ci /* test the result in TH_DATA : communication buffer */ 285f08c3bdfSopenharmony_ci pcom = *tabcour++; 286f08c3bdfSopenharmony_ci if (pcom->th_result != 0) { 287f08c3bdfSopenharmony_ci error++; 288f08c3bdfSopenharmony_ci tst_resm(TFAIL, 289f08c3bdfSopenharmony_ci "thread %d (%s) terminated unsuccessfully %d " 290f08c3bdfSopenharmony_ci "errors/%d loops\n%s", 291f08c3bdfSopenharmony_ci th_num, pcom->th_func.fident, pcom->th_nerror, 292f08c3bdfSopenharmony_ci pcom->th_nloop, pcom->detail_data); 293f08c3bdfSopenharmony_ci } else if (debug) { 294f08c3bdfSopenharmony_ci tst_resm(TINFO, 295f08c3bdfSopenharmony_ci "thread %d (%s) terminated successfully %d loops", 296f08c3bdfSopenharmony_ci th_num, pcom->th_func.fident, 297f08c3bdfSopenharmony_ci pcom->th_nloop - 1); 298f08c3bdfSopenharmony_ci } 299f08c3bdfSopenharmony_ci SAFE_FREE(pcom); 300f08c3bdfSopenharmony_ci 301f08c3bdfSopenharmony_ci } 302f08c3bdfSopenharmony_ci SAFE_FREE(tabcom); 303f08c3bdfSopenharmony_ci SAFE_FREE(threads); 304f08c3bdfSopenharmony_ci tst_rmdir(); 305f08c3bdfSopenharmony_ci if (error) 306f08c3bdfSopenharmony_ci exit(1); 307f08c3bdfSopenharmony_ci else 308f08c3bdfSopenharmony_ci exit(0); 309f08c3bdfSopenharmony_ci return 0; 310f08c3bdfSopenharmony_ci} 311f08c3bdfSopenharmony_ci 312f08c3bdfSopenharmony_ci/*----------------------------------------------------------------------+ 313f08c3bdfSopenharmony_ci| handle_signals () | 314f08c3bdfSopenharmony_ci| ======================================================================| 315f08c3bdfSopenharmony_ci| | 316f08c3bdfSopenharmony_ci| Function: .... | 317f08c3bdfSopenharmony_ci| If SIGALRM or SIGUSR1 or SIGINT : cancel threads | 318f08c3bdfSopenharmony_ci| | 319f08c3bdfSopenharmony_ci| Updates: .... | 320f08c3bdfSopenharmony_ci| | 321f08c3bdfSopenharmony_ci+-----------------------------------------------------------------------*/ 322f08c3bdfSopenharmony_cistatic void *handle_signals(void *arg) 323f08c3bdfSopenharmony_ci{ 324f08c3bdfSopenharmony_ci sigset_t signals_set; 325f08c3bdfSopenharmony_ci int thd; 326f08c3bdfSopenharmony_ci int sig; 327f08c3bdfSopenharmony_ci int retvalsig = 0; 328f08c3bdfSopenharmony_ci 329f08c3bdfSopenharmony_ci if (debug) 330f08c3bdfSopenharmony_ci tst_resm(TINFO, "signal handler %lu started", pthread_self()); 331f08c3bdfSopenharmony_ci /* 332f08c3bdfSopenharmony_ci * Set up the signals that we want to handle... 333f08c3bdfSopenharmony_ci */ 334f08c3bdfSopenharmony_ci sigemptyset(&signals_set); 335f08c3bdfSopenharmony_ci sigaddset(&signals_set, SIGINT); 336f08c3bdfSopenharmony_ci sigaddset(&signals_set, SIGQUIT); 337f08c3bdfSopenharmony_ci sigaddset(&signals_set, SIGTERM); 338f08c3bdfSopenharmony_ci sigaddset(&signals_set, SIGUSR1); 339f08c3bdfSopenharmony_ci sigaddset(&signals_set, SIGALRM); 340f08c3bdfSopenharmony_ci while (1) { 341f08c3bdfSopenharmony_ci if (debug) 342f08c3bdfSopenharmony_ci tst_resm(TINFO, "Signal handler starts waiting..."); 343f08c3bdfSopenharmony_ci 344f08c3bdfSopenharmony_ci sigwait(&signals_set, &sig); 345f08c3bdfSopenharmony_ci if (debug) 346f08c3bdfSopenharmony_ci tst_resm(TINFO, "Signal handler caught signal %d", sig); 347f08c3bdfSopenharmony_ci 348f08c3bdfSopenharmony_ci switch (sig) { 349f08c3bdfSopenharmony_ci case SIGALRM: 350f08c3bdfSopenharmony_ci case SIGUSR1: 351f08c3bdfSopenharmony_ci case SIGINT: 352f08c3bdfSopenharmony_ci if (sig_cancel) 353f08c3bdfSopenharmony_ci tst_resm(TINFO, 354f08c3bdfSopenharmony_ci "Signal handler: already finished; " 355f08c3bdfSopenharmony_ci "ignoring signal"); 356f08c3bdfSopenharmony_ci else { 357f08c3bdfSopenharmony_ci /* 358f08c3bdfSopenharmony_ci * Have to signal all non started threads... 359f08c3bdfSopenharmony_ci */ 360f08c3bdfSopenharmony_ci 361f08c3bdfSopenharmony_ci retvalsig = pthread_mutex_lock(&sig_mutex); 362f08c3bdfSopenharmony_ci if (retvalsig != 0) 363f08c3bdfSopenharmony_ci sys_error 364f08c3bdfSopenharmony_ci ("handle_signal : mutex_lock(&sig_mutex) FAILED", 365f08c3bdfSopenharmony_ci __LINE__); 366f08c3bdfSopenharmony_ci 367f08c3bdfSopenharmony_ci sig_cancel = 1; 368f08c3bdfSopenharmony_ci retvalsig = pthread_mutex_unlock(&sig_mutex); 369f08c3bdfSopenharmony_ci if (retvalsig != 0) 370f08c3bdfSopenharmony_ci sys_error 371f08c3bdfSopenharmony_ci ("handle_signal : mutex_unlock(&sig_mutex) FAILED", 372f08c3bdfSopenharmony_ci __LINE__); 373f08c3bdfSopenharmony_ci 374f08c3bdfSopenharmony_ci /* 375f08c3bdfSopenharmony_ci * ......... and all started 376f08c3bdfSopenharmony_ci */ 377f08c3bdfSopenharmony_ci for (thd = 0; thd < indice; thd++) { 378f08c3bdfSopenharmony_ci if (debug) 379f08c3bdfSopenharmony_ci tst_resm(TINFO, 380f08c3bdfSopenharmony_ci "signal handler: " 381f08c3bdfSopenharmony_ci "cancelling thread (%d of " 382f08c3bdfSopenharmony_ci "%d)", thd, indice); 383f08c3bdfSopenharmony_ci retvalsig = 384f08c3bdfSopenharmony_ci pthread_cancel(threads[thd]); 385f08c3bdfSopenharmony_ci if (retvalsig != 0) 386f08c3bdfSopenharmony_ci sys_error 387f08c3bdfSopenharmony_ci ("handle_signal : cancel FAILED", 388f08c3bdfSopenharmony_ci __LINE__); 389f08c3bdfSopenharmony_ci } 390f08c3bdfSopenharmony_ci } 391f08c3bdfSopenharmony_ci break; 392f08c3bdfSopenharmony_ci case SIGQUIT: 393f08c3bdfSopenharmony_ci tst_resm(TINFO, 394f08c3bdfSopenharmony_ci "Signal handler: Caught SIGQUIT; doing nothing"); 395f08c3bdfSopenharmony_ci break; 396f08c3bdfSopenharmony_ci case SIGTERM: 397f08c3bdfSopenharmony_ci tst_resm(TINFO, 398f08c3bdfSopenharmony_ci "Signal handler: Caught SIGTERM; doing nothing"); 399f08c3bdfSopenharmony_ci break; 400f08c3bdfSopenharmony_ci default: 401f08c3bdfSopenharmony_ci exit(1); 402f08c3bdfSopenharmony_ci } 403f08c3bdfSopenharmony_ci } 404f08c3bdfSopenharmony_ci return NULL; 405f08c3bdfSopenharmony_ci} 406f08c3bdfSopenharmony_ci 407f08c3bdfSopenharmony_ci/*----------------------------------------------------------------------+ 408f08c3bdfSopenharmony_ci | error () | 409f08c3bdfSopenharmony_ci | =====================================================================| 410f08c3bdfSopenharmony_ci | | 411f08c3bdfSopenharmony_ci | Function: Prints out message and exits... | 412f08c3bdfSopenharmony_ci | | 413f08c3bdfSopenharmony_ci +----------------------------------------------------------------------*/ 414f08c3bdfSopenharmony_cistatic void error(const char *msg, int line) 415f08c3bdfSopenharmony_ci{ 416f08c3bdfSopenharmony_ci tst_brkm(TFAIL, cleanup, "ERROR [line: %d] %s", line, msg); 417f08c3bdfSopenharmony_ci} 418f08c3bdfSopenharmony_ci 419f08c3bdfSopenharmony_ci/*----------------------------------------------------------------------+ 420f08c3bdfSopenharmony_ci | sys_error () | 421f08c3bdfSopenharmony_ci | =====================================================================| 422f08c3bdfSopenharmony_ci | | 423f08c3bdfSopenharmony_ci | Function: Creates system error message and calls error () | 424f08c3bdfSopenharmony_ci | | 425f08c3bdfSopenharmony_ci +----------------------------------------------------------------------*/ 426f08c3bdfSopenharmony_ci/* 427f08c3bdfSopenharmony_ci * XXX (garrcoop): the way that this is being called is just plain wrong. 428f08c3bdfSopenharmony_ci * pthread(5) returns 0 or errnos, not necessarily sets errno to a sensible 429f08c3bdfSopenharmony_ci * value. 430f08c3bdfSopenharmony_ci */ 431f08c3bdfSopenharmony_cistatic void sys_error(const char *msg, int line) 432f08c3bdfSopenharmony_ci{ 433f08c3bdfSopenharmony_ci char syserr_msg[256]; 434f08c3bdfSopenharmony_ci 435f08c3bdfSopenharmony_ci sprintf(syserr_msg, "%s: %s", msg, strerror(errno)); 436f08c3bdfSopenharmony_ci error(syserr_msg, line); 437f08c3bdfSopenharmony_ci} 438