Gtest-concurrent.c revision c0e81195b7e1fc1db66b4c324ba0d356ef7a0032
1716484f0009c474bb72cbf096f933b4118bf17a5mostang.com!davidm/* libunwind - a platform-independent unwind library 2c0e81195b7e1fc1db66b4c324ba0d356ef7a0032hp.com!davidm Copyright (C) 2003-2005 Hewlett-Packard Co 3716484f0009c474bb72cbf096f933b4118bf17a5mostang.com!davidm Contributed by David Mosberger-Tang <davidm@hpl.hp.com> 4716484f0009c474bb72cbf096f933b4118bf17a5mostang.com!davidm 5716484f0009c474bb72cbf096f933b4118bf17a5mostang.com!davidmPermission is hereby granted, free of charge, to any person obtaining 6716484f0009c474bb72cbf096f933b4118bf17a5mostang.com!davidma copy of this software and associated documentation files (the 7716484f0009c474bb72cbf096f933b4118bf17a5mostang.com!davidm"Software"), to deal in the Software without restriction, including 8716484f0009c474bb72cbf096f933b4118bf17a5mostang.com!davidmwithout limitation the rights to use, copy, modify, merge, publish, 9716484f0009c474bb72cbf096f933b4118bf17a5mostang.com!davidmdistribute, sublicense, and/or sell copies of the Software, and to 10716484f0009c474bb72cbf096f933b4118bf17a5mostang.com!davidmpermit persons to whom the Software is furnished to do so, subject to 11716484f0009c474bb72cbf096f933b4118bf17a5mostang.com!davidmthe following conditions: 12716484f0009c474bb72cbf096f933b4118bf17a5mostang.com!davidm 13716484f0009c474bb72cbf096f933b4118bf17a5mostang.com!davidmThe above copyright notice and this permission notice shall be 14716484f0009c474bb72cbf096f933b4118bf17a5mostang.com!davidmincluded in all copies or substantial portions of the Software. 15716484f0009c474bb72cbf096f933b4118bf17a5mostang.com!davidm 16716484f0009c474bb72cbf096f933b4118bf17a5mostang.com!davidmTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17716484f0009c474bb72cbf096f933b4118bf17a5mostang.com!davidmEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18716484f0009c474bb72cbf096f933b4118bf17a5mostang.com!davidmMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 19716484f0009c474bb72cbf096f933b4118bf17a5mostang.com!davidmNONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 20716484f0009c474bb72cbf096f933b4118bf17a5mostang.com!davidmLIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 21716484f0009c474bb72cbf096f933b4118bf17a5mostang.com!davidmOF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 22716484f0009c474bb72cbf096f933b4118bf17a5mostang.com!davidmWITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ 23716484f0009c474bb72cbf096f933b4118bf17a5mostang.com!davidm 24716484f0009c474bb72cbf096f933b4118bf17a5mostang.com!davidm/* Verify that multi-threaded concurrent unwinding works as expected. */ 25716484f0009c474bb72cbf096f933b4118bf17a5mostang.com!davidm 26716484f0009c474bb72cbf096f933b4118bf17a5mostang.com!davidm#ifdef HAVE_CONFIG_H 27716484f0009c474bb72cbf096f933b4118bf17a5mostang.com!davidm# include "config.h" 28716484f0009c474bb72cbf096f933b4118bf17a5mostang.com!davidm#endif 29716484f0009c474bb72cbf096f933b4118bf17a5mostang.com!davidm 30716484f0009c474bb72cbf096f933b4118bf17a5mostang.com!davidm#include <libunwind.h> 31716484f0009c474bb72cbf096f933b4118bf17a5mostang.com!davidm#include <pthread.h> 32716484f0009c474bb72cbf096f933b4118bf17a5mostang.com!davidm#include <signal.h> 33716484f0009c474bb72cbf096f933b4118bf17a5mostang.com!davidm#include <stdio.h> 34716484f0009c474bb72cbf096f933b4118bf17a5mostang.com!davidm#include <stdlib.h> 35716484f0009c474bb72cbf096f933b4118bf17a5mostang.com!davidm#include <unistd.h> 36716484f0009c474bb72cbf096f933b4118bf17a5mostang.com!davidm 37716484f0009c474bb72cbf096f933b4118bf17a5mostang.com!davidm#define NTHREADS 128 38716484f0009c474bb72cbf096f933b4118bf17a5mostang.com!davidm 39716484f0009c474bb72cbf096f933b4118bf17a5mostang.com!davidm#define panic(args...) \ 40716484f0009c474bb72cbf096f933b4118bf17a5mostang.com!davidm do { fprintf (stderr, args); ++nerrors; } while (0) 41716484f0009c474bb72cbf096f933b4118bf17a5mostang.com!davidm 42716484f0009c474bb72cbf096f933b4118bf17a5mostang.com!davidmint verbose; 43716484f0009c474bb72cbf096f933b4118bf17a5mostang.com!davidmint nerrors; 44716484f0009c474bb72cbf096f933b4118bf17a5mostang.com!davidmint got_usr1, got_usr2; 45716484f0009c474bb72cbf096f933b4118bf17a5mostang.com!davidmchar *sigusr1_sp; 46716484f0009c474bb72cbf096f933b4118bf17a5mostang.com!davidm 47716484f0009c474bb72cbf096f933b4118bf17a5mostang.com!davidmvoid 48716484f0009c474bb72cbf096f933b4118bf17a5mostang.com!davidmhandler (int sig) 49716484f0009c474bb72cbf096f933b4118bf17a5mostang.com!davidm{ 50716484f0009c474bb72cbf096f933b4118bf17a5mostang.com!davidm unw_word_t ip; 51716484f0009c474bb72cbf096f933b4118bf17a5mostang.com!davidm unw_context_t uc; 52716484f0009c474bb72cbf096f933b4118bf17a5mostang.com!davidm unw_cursor_t c; 53716484f0009c474bb72cbf096f933b4118bf17a5mostang.com!davidm int ret; 54716484f0009c474bb72cbf096f933b4118bf17a5mostang.com!davidm 55471e4e5fa698a9eeaef184d9acea32ad9aac2fe9mostang.com!davidm unw_getcontext (&uc); 56471e4e5fa698a9eeaef184d9acea32ad9aac2fe9mostang.com!davidm unw_init_local (&c, &uc); 57716484f0009c474bb72cbf096f933b4118bf17a5mostang.com!davidm do 58716484f0009c474bb72cbf096f933b4118bf17a5mostang.com!davidm { 59471e4e5fa698a9eeaef184d9acea32ad9aac2fe9mostang.com!davidm unw_get_reg (&c, UNW_REG_IP, &ip); 60716484f0009c474bb72cbf096f933b4118bf17a5mostang.com!davidm if (verbose) 6194f198b28835ff21668abb53bf146cabf209fbb7hp.com!davidm printf ("%lx: IP=%lx\n", (long) pthread_self (), (unsigned long) ip); 62716484f0009c474bb72cbf096f933b4118bf17a5mostang.com!davidm } 63471e4e5fa698a9eeaef184d9acea32ad9aac2fe9mostang.com!davidm while ((ret = unw_step (&c)) > 0); 64716484f0009c474bb72cbf096f933b4118bf17a5mostang.com!davidm 65716484f0009c474bb72cbf096f933b4118bf17a5mostang.com!davidm if (ret < 0) 66716484f0009c474bb72cbf096f933b4118bf17a5mostang.com!davidm panic ("unw_step() returned %d\n", ret); 67716484f0009c474bb72cbf096f933b4118bf17a5mostang.com!davidm} 68716484f0009c474bb72cbf096f933b4118bf17a5mostang.com!davidm 69716484f0009c474bb72cbf096f933b4118bf17a5mostang.com!davidmvoid * 70716484f0009c474bb72cbf096f933b4118bf17a5mostang.com!davidmworker (void *arg) 71716484f0009c474bb72cbf096f933b4118bf17a5mostang.com!davidm{ 72716484f0009c474bb72cbf096f933b4118bf17a5mostang.com!davidm signal (SIGUSR1, handler); 73716484f0009c474bb72cbf096f933b4118bf17a5mostang.com!davidm 74716484f0009c474bb72cbf096f933b4118bf17a5mostang.com!davidm if (verbose) 75716484f0009c474bb72cbf096f933b4118bf17a5mostang.com!davidm printf ("sending SIGUSR1\n"); 76716484f0009c474bb72cbf096f933b4118bf17a5mostang.com!davidm pthread_kill (pthread_self (), SIGUSR1); 77716484f0009c474bb72cbf096f933b4118bf17a5mostang.com!davidm return NULL; 78716484f0009c474bb72cbf096f933b4118bf17a5mostang.com!davidm} 79716484f0009c474bb72cbf096f933b4118bf17a5mostang.com!davidm 80716484f0009c474bb72cbf096f933b4118bf17a5mostang.com!davidmstatic void 81716484f0009c474bb72cbf096f933b4118bf17a5mostang.com!davidmdoit (void) 82716484f0009c474bb72cbf096f933b4118bf17a5mostang.com!davidm{ 83716484f0009c474bb72cbf096f933b4118bf17a5mostang.com!davidm pthread_t th[NTHREADS]; 84716484f0009c474bb72cbf096f933b4118bf17a5mostang.com!davidm int i; 85716484f0009c474bb72cbf096f933b4118bf17a5mostang.com!davidm 86716484f0009c474bb72cbf096f933b4118bf17a5mostang.com!davidm for (i = 0; i < NTHREADS; ++i) 87c0e81195b7e1fc1db66b4c324ba0d356ef7a0032hp.com!davidm if (pthread_create (th + i, NULL, worker, NULL)) 88c0e81195b7e1fc1db66b4c324ba0d356ef7a0032hp.com!davidm { 89c0e81195b7e1fc1db66b4c324ba0d356ef7a0032hp.com!davidm fprintf (stderr, "FAILURE: Failed to create %u threads " 90c0e81195b7e1fc1db66b4c324ba0d356ef7a0032hp.com!davidm "(after %u threads)\n", 91c0e81195b7e1fc1db66b4c324ba0d356ef7a0032hp.com!davidm NTHREADS, i); 92c0e81195b7e1fc1db66b4c324ba0d356ef7a0032hp.com!davidm exit (-1); 93c0e81195b7e1fc1db66b4c324ba0d356ef7a0032hp.com!davidm } 94716484f0009c474bb72cbf096f933b4118bf17a5mostang.com!davidm 95716484f0009c474bb72cbf096f933b4118bf17a5mostang.com!davidm for (i = 0; i < NTHREADS; ++i) 96716484f0009c474bb72cbf096f933b4118bf17a5mostang.com!davidm pthread_join (th[i], NULL); 97716484f0009c474bb72cbf096f933b4118bf17a5mostang.com!davidm} 98716484f0009c474bb72cbf096f933b4118bf17a5mostang.com!davidm 99716484f0009c474bb72cbf096f933b4118bf17a5mostang.com!davidmint 100716484f0009c474bb72cbf096f933b4118bf17a5mostang.com!davidmmain (int argc, char **argv) 101716484f0009c474bb72cbf096f933b4118bf17a5mostang.com!davidm{ 102716484f0009c474bb72cbf096f933b4118bf17a5mostang.com!davidm if (argc > 1) 103716484f0009c474bb72cbf096f933b4118bf17a5mostang.com!davidm verbose = 1; 104716484f0009c474bb72cbf096f933b4118bf17a5mostang.com!davidm 105716484f0009c474bb72cbf096f933b4118bf17a5mostang.com!davidm if (verbose) 106716484f0009c474bb72cbf096f933b4118bf17a5mostang.com!davidm printf ("Caching: none\n"); 107716484f0009c474bb72cbf096f933b4118bf17a5mostang.com!davidm unw_set_caching_policy (unw_local_addr_space, UNW_CACHE_NONE); 108716484f0009c474bb72cbf096f933b4118bf17a5mostang.com!davidm doit (); 109716484f0009c474bb72cbf096f933b4118bf17a5mostang.com!davidm 110716484f0009c474bb72cbf096f933b4118bf17a5mostang.com!davidm if (verbose) 111716484f0009c474bb72cbf096f933b4118bf17a5mostang.com!davidm printf ("Caching: global\n"); 112716484f0009c474bb72cbf096f933b4118bf17a5mostang.com!davidm unw_set_caching_policy (unw_local_addr_space, UNW_CACHE_GLOBAL); 113716484f0009c474bb72cbf096f933b4118bf17a5mostang.com!davidm 114716484f0009c474bb72cbf096f933b4118bf17a5mostang.com!davidm if (verbose) 115716484f0009c474bb72cbf096f933b4118bf17a5mostang.com!davidm printf ("Caching: per-thread\n"); 116716484f0009c474bb72cbf096f933b4118bf17a5mostang.com!davidm unw_set_caching_policy (unw_local_addr_space, UNW_CACHE_PER_THREAD); 117716484f0009c474bb72cbf096f933b4118bf17a5mostang.com!davidm 118716484f0009c474bb72cbf096f933b4118bf17a5mostang.com!davidm if (nerrors) 119c0e81195b7e1fc1db66b4c324ba0d356ef7a0032hp.com!davidm { 120c0e81195b7e1fc1db66b4c324ba0d356ef7a0032hp.com!davidm fprintf (stderr, "FAILURE: detected %d errors\n", nerrors); 121c0e81195b7e1fc1db66b4c324ba0d356ef7a0032hp.com!davidm exit (-1); 122c0e81195b7e1fc1db66b4c324ba0d356ef7a0032hp.com!davidm } 123716484f0009c474bb72cbf096f933b4118bf17a5mostang.com!davidm 124716484f0009c474bb72cbf096f933b4118bf17a5mostang.com!davidm if (verbose) 125716484f0009c474bb72cbf096f933b4118bf17a5mostang.com!davidm printf ("SUCCESS\n"); 126716484f0009c474bb72cbf096f933b4118bf17a5mostang.com!davidm return 0; 127716484f0009c474bb72cbf096f933b4118bf17a5mostang.com!davidm} 128