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