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
306b55e0ab51eee7dbea679fda2b37ecf61f0025e5Tommi Rantala#include "compiler.h"
316b55e0ab51eee7dbea679fda2b37ecf61f0025e5Tommi Rantala
32716484f0009c474bb72cbf096f933b4118bf17a5mostang.com!davidm#include <libunwind.h>
33b0406d0a2a97b290a835ab94c13036119a0db23bhp.com!davidm#include <limits.h>
34716484f0009c474bb72cbf096f933b4118bf17a5mostang.com!davidm#include <pthread.h>
35716484f0009c474bb72cbf096f933b4118bf17a5mostang.com!davidm#include <signal.h>
36716484f0009c474bb72cbf096f933b4118bf17a5mostang.com!davidm#include <stdio.h>
37716484f0009c474bb72cbf096f933b4118bf17a5mostang.com!davidm#include <stdlib.h>
38716484f0009c474bb72cbf096f933b4118bf17a5mostang.com!davidm#include <unistd.h>
39716484f0009c474bb72cbf096f933b4118bf17a5mostang.com!davidm
40716484f0009c474bb72cbf096f933b4118bf17a5mostang.com!davidm#define NTHREADS	128
41716484f0009c474bb72cbf096f933b4118bf17a5mostang.com!davidm
42716484f0009c474bb72cbf096f933b4118bf17a5mostang.com!davidm#define panic(args...)						\
43716484f0009c474bb72cbf096f933b4118bf17a5mostang.com!davidm	do { fprintf (stderr, args); ++nerrors; } while (0)
44716484f0009c474bb72cbf096f933b4118bf17a5mostang.com!davidm
45716484f0009c474bb72cbf096f933b4118bf17a5mostang.com!davidmint verbose;
46716484f0009c474bb72cbf096f933b4118bf17a5mostang.com!davidmint nerrors;
47716484f0009c474bb72cbf096f933b4118bf17a5mostang.com!davidmint got_usr1, got_usr2;
48716484f0009c474bb72cbf096f933b4118bf17a5mostang.com!davidmchar *sigusr1_sp;
49716484f0009c474bb72cbf096f933b4118bf17a5mostang.com!davidm
50716484f0009c474bb72cbf096f933b4118bf17a5mostang.com!davidmvoid
516b55e0ab51eee7dbea679fda2b37ecf61f0025e5Tommi Rantalahandler (int sig UNUSED)
52716484f0009c474bb72cbf096f933b4118bf17a5mostang.com!davidm{
53716484f0009c474bb72cbf096f933b4118bf17a5mostang.com!davidm  unw_word_t ip;
54716484f0009c474bb72cbf096f933b4118bf17a5mostang.com!davidm  unw_context_t uc;
55716484f0009c474bb72cbf096f933b4118bf17a5mostang.com!davidm  unw_cursor_t c;
56716484f0009c474bb72cbf096f933b4118bf17a5mostang.com!davidm  int ret;
57716484f0009c474bb72cbf096f933b4118bf17a5mostang.com!davidm
58471e4e5fa698a9eeaef184d9acea32ad9aac2fe9mostang.com!davidm  unw_getcontext (&uc);
59471e4e5fa698a9eeaef184d9acea32ad9aac2fe9mostang.com!davidm  unw_init_local (&c, &uc);
60716484f0009c474bb72cbf096f933b4118bf17a5mostang.com!davidm  do
61716484f0009c474bb72cbf096f933b4118bf17a5mostang.com!davidm    {
62471e4e5fa698a9eeaef184d9acea32ad9aac2fe9mostang.com!davidm      unw_get_reg (&c, UNW_REG_IP, &ip);
63716484f0009c474bb72cbf096f933b4118bf17a5mostang.com!davidm      if (verbose)
6494f198b28835ff21668abb53bf146cabf209fbb7hp.com!davidm	printf ("%lx: IP=%lx\n", (long) pthread_self (), (unsigned long) ip);
65716484f0009c474bb72cbf096f933b4118bf17a5mostang.com!davidm    }
66471e4e5fa698a9eeaef184d9acea32ad9aac2fe9mostang.com!davidm  while ((ret = unw_step (&c)) > 0);
67716484f0009c474bb72cbf096f933b4118bf17a5mostang.com!davidm
68716484f0009c474bb72cbf096f933b4118bf17a5mostang.com!davidm  if (ret < 0)
69716484f0009c474bb72cbf096f933b4118bf17a5mostang.com!davidm    panic ("unw_step() returned %d\n", ret);
70716484f0009c474bb72cbf096f933b4118bf17a5mostang.com!davidm}
71716484f0009c474bb72cbf096f933b4118bf17a5mostang.com!davidm
72716484f0009c474bb72cbf096f933b4118bf17a5mostang.com!davidmvoid *
736b55e0ab51eee7dbea679fda2b37ecf61f0025e5Tommi Rantalaworker (void *arg UNUSED)
74716484f0009c474bb72cbf096f933b4118bf17a5mostang.com!davidm{
75716484f0009c474bb72cbf096f933b4118bf17a5mostang.com!davidm  signal (SIGUSR1, handler);
76716484f0009c474bb72cbf096f933b4118bf17a5mostang.com!davidm
77716484f0009c474bb72cbf096f933b4118bf17a5mostang.com!davidm  if (verbose)
78716484f0009c474bb72cbf096f933b4118bf17a5mostang.com!davidm    printf ("sending SIGUSR1\n");
79716484f0009c474bb72cbf096f933b4118bf17a5mostang.com!davidm  pthread_kill (pthread_self (), SIGUSR1);
80716484f0009c474bb72cbf096f933b4118bf17a5mostang.com!davidm  return NULL;
81716484f0009c474bb72cbf096f933b4118bf17a5mostang.com!davidm}
82716484f0009c474bb72cbf096f933b4118bf17a5mostang.com!davidm
83716484f0009c474bb72cbf096f933b4118bf17a5mostang.com!davidmstatic void
84716484f0009c474bb72cbf096f933b4118bf17a5mostang.com!davidmdoit (void)
85716484f0009c474bb72cbf096f933b4118bf17a5mostang.com!davidm{
86716484f0009c474bb72cbf096f933b4118bf17a5mostang.com!davidm  pthread_t th[NTHREADS];
87b0406d0a2a97b290a835ab94c13036119a0db23bhp.com!davidm  pthread_attr_t attr;
88716484f0009c474bb72cbf096f933b4118bf17a5mostang.com!davidm  int i;
89716484f0009c474bb72cbf096f933b4118bf17a5mostang.com!davidm
90b0406d0a2a97b290a835ab94c13036119a0db23bhp.com!davidm  pthread_attr_init (&attr);
91b0406d0a2a97b290a835ab94c13036119a0db23bhp.com!davidm  pthread_attr_setstacksize (&attr, PTHREAD_STACK_MIN + 64*1024);
92b0406d0a2a97b290a835ab94c13036119a0db23bhp.com!davidm
93716484f0009c474bb72cbf096f933b4118bf17a5mostang.com!davidm  for (i = 0; i < NTHREADS; ++i)
94b0406d0a2a97b290a835ab94c13036119a0db23bhp.com!davidm    if (pthread_create (th + i, &attr, worker, NULL))
95c0e81195b7e1fc1db66b4c324ba0d356ef7a0032hp.com!davidm      {
96c0e81195b7e1fc1db66b4c324ba0d356ef7a0032hp.com!davidm	fprintf (stderr, "FAILURE: Failed to create %u threads "
97c0e81195b7e1fc1db66b4c324ba0d356ef7a0032hp.com!davidm		 "(after %u threads)\n",
98c0e81195b7e1fc1db66b4c324ba0d356ef7a0032hp.com!davidm		 NTHREADS, i);
99c0e81195b7e1fc1db66b4c324ba0d356ef7a0032hp.com!davidm	exit (-1);
100c0e81195b7e1fc1db66b4c324ba0d356ef7a0032hp.com!davidm      }
101716484f0009c474bb72cbf096f933b4118bf17a5mostang.com!davidm
102716484f0009c474bb72cbf096f933b4118bf17a5mostang.com!davidm  for (i = 0; i < NTHREADS; ++i)
103716484f0009c474bb72cbf096f933b4118bf17a5mostang.com!davidm    pthread_join (th[i], NULL);
104716484f0009c474bb72cbf096f933b4118bf17a5mostang.com!davidm}
105716484f0009c474bb72cbf096f933b4118bf17a5mostang.com!davidm
106716484f0009c474bb72cbf096f933b4118bf17a5mostang.com!davidmint
1076b55e0ab51eee7dbea679fda2b37ecf61f0025e5Tommi Rantalamain (int argc, char **argv UNUSED)
108716484f0009c474bb72cbf096f933b4118bf17a5mostang.com!davidm{
109716484f0009c474bb72cbf096f933b4118bf17a5mostang.com!davidm  if (argc > 1)
110716484f0009c474bb72cbf096f933b4118bf17a5mostang.com!davidm    verbose = 1;
111716484f0009c474bb72cbf096f933b4118bf17a5mostang.com!davidm
112716484f0009c474bb72cbf096f933b4118bf17a5mostang.com!davidm  if (verbose)
113716484f0009c474bb72cbf096f933b4118bf17a5mostang.com!davidm    printf ("Caching: none\n");
114716484f0009c474bb72cbf096f933b4118bf17a5mostang.com!davidm  unw_set_caching_policy (unw_local_addr_space, UNW_CACHE_NONE);
115716484f0009c474bb72cbf096f933b4118bf17a5mostang.com!davidm  doit ();
116716484f0009c474bb72cbf096f933b4118bf17a5mostang.com!davidm
117716484f0009c474bb72cbf096f933b4118bf17a5mostang.com!davidm  if (verbose)
118716484f0009c474bb72cbf096f933b4118bf17a5mostang.com!davidm    printf ("Caching: global\n");
119716484f0009c474bb72cbf096f933b4118bf17a5mostang.com!davidm  unw_set_caching_policy (unw_local_addr_space, UNW_CACHE_GLOBAL);
120890a630d76ca4af8cb9758e3c74d00897dbcb544Paul Pluzhnikov  doit ();
121716484f0009c474bb72cbf096f933b4118bf17a5mostang.com!davidm
122716484f0009c474bb72cbf096f933b4118bf17a5mostang.com!davidm  if (verbose)
123716484f0009c474bb72cbf096f933b4118bf17a5mostang.com!davidm    printf ("Caching: per-thread\n");
124716484f0009c474bb72cbf096f933b4118bf17a5mostang.com!davidm  unw_set_caching_policy (unw_local_addr_space, UNW_CACHE_PER_THREAD);
125890a630d76ca4af8cb9758e3c74d00897dbcb544Paul Pluzhnikov  doit ();
126716484f0009c474bb72cbf096f933b4118bf17a5mostang.com!davidm
127716484f0009c474bb72cbf096f933b4118bf17a5mostang.com!davidm  if (nerrors)
128c0e81195b7e1fc1db66b4c324ba0d356ef7a0032hp.com!davidm    {
129c0e81195b7e1fc1db66b4c324ba0d356ef7a0032hp.com!davidm      fprintf (stderr, "FAILURE: detected %d errors\n", nerrors);
130c0e81195b7e1fc1db66b4c324ba0d356ef7a0032hp.com!davidm      exit (-1);
131c0e81195b7e1fc1db66b4c324ba0d356ef7a0032hp.com!davidm    }
132716484f0009c474bb72cbf096f933b4118bf17a5mostang.com!davidm
133716484f0009c474bb72cbf096f933b4118bf17a5mostang.com!davidm  if (verbose)
134716484f0009c474bb72cbf096f933b4118bf17a5mostang.com!davidm    printf ("SUCCESS\n");
135716484f0009c474bb72cbf096f933b4118bf17a5mostang.com!davidm  return 0;
136716484f0009c474bb72cbf096f933b4118bf17a5mostang.com!davidm}
137