/* Copyright (C) 2003 Free Software Foundation, Inc.
   This file is part of the GNU C Library.
   Contributed by Jakub Jelinek <jakub@redhat.com>, 2003.

   The GNU C Library is free software; you can redistribute it and/or
   modify it under the terms of the GNU Lesser General Public
   License as published by the Free Software Foundation; either
   version 2.1 of the License, or (at your option) any later version.

   The GNU C Library is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   Lesser General Public License for more details.

   You should have received a copy of the GNU Lesser General Public
   License along with the GNU C Library; if not, write to the Free
   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
   02111-1307 USA.  */

#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

extern void _pthread_cleanup_push (struct _pthread_cleanup_buffer *__buffer,
                                   void (*__routine) (void *),
                                   void *__arg);
extern void _pthread_cleanup_pop (struct _pthread_cleanup_buffer *__buffer,
                                  int __execute);

extern void clh (void *arg);
extern void fn0 (void);
extern void fn1 (void);
extern void fn5 (void);
extern void fn7 (void);
extern void fn9 (void);


static __attribute__((noinline)) void
fn3 (void)
{
  /* This is the old LinuxThreads pthread_cleanup_{push,pop}.  */
     struct _pthread_cleanup_buffer b;
  _pthread_cleanup_push (&b, clh, (void *) 4l);

  fn0 ();

  _pthread_cleanup_pop (&b, 1);
}


static __attribute__((noinline)) void
fn4 (void)
{
  pthread_cleanup_push (clh, (void *) 5l);

  fn3 ();

  pthread_cleanup_pop (1);
}


void
fn5 (void)
{
  /* This is the old LinuxThreads pthread_cleanup_{push,pop}.  */
     struct _pthread_cleanup_buffer b;
  _pthread_cleanup_push (&b, clh, (void *) 6l);

  fn4 ();

  _pthread_cleanup_pop (&b, 1);
}


static __attribute__((noinline)) void
fn6 (void)
{
  pthread_cleanup_push (clh, (void *) 7l);

  fn0 ();

  pthread_cleanup_pop (1);
}


void
fn7 (void)
{
  /* This is the old LinuxThreads pthread_cleanup_{push,pop}.  */
     struct _pthread_cleanup_buffer b;
  _pthread_cleanup_push (&b, clh, (void *) 8l);

  fn6 ();

  _pthread_cleanup_pop (&b, 1);
}


static __attribute__((noinline)) void
fn8 (void)
{
  pthread_cleanup_push (clh, (void *) 9l);

  fn1 ();

  pthread_cleanup_pop (1);
}


void
fn9 (void)
{
  /* This is the old LinuxThreads pthread_cleanup_{push,pop}.  */
     struct _pthread_cleanup_buffer b;
  _pthread_cleanup_push (&b, clh, (void *) 10l);

  fn8 ();

  _pthread_cleanup_pop (&b, 1);
}
