/* Thread library support for -fsplit-stack.  */
/* Copyright (C) 2009, 2010 Free Software Foundation, Inc.
   Contributed by Ian Lance Taylor <iant@google.com>.

This file is part of GCC.

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

GCC 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 General Public License
for more details.

Under Section 7 of GPL version 3, you are granted additional
permissions described in the GCC Runtime Library Exception, version
3.1, as published by the Free Software Foundation.

You should have received a copy of the GNU General Public License and
a copy of the GCC Runtime Library Exception along with this program;
see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
<http://www.gnu.org/licenses/>.  */

#include "tconfig.h"
#include "tsystem.h"
#include "coretypes.h"
#include "tm.h"

/* If inhibit_libc is defined, we can not compile this file.  The
   effect is that people will not be able to use -fsplit-stack.  That
   is much better than failing the build particularly since people
   will want to define inhibit_libc while building a compiler which
   can build glibc.  */

#ifndef inhibit_libc

#include <pthread.h>

#include "generic-morestack.h"

/* We declare the pthread functions we need as weak, so that
   libgcc_s.so does not need to be linked against -lpthread.  */

extern int pthread_once (pthread_once_t *, void (*) (void))
  __attribute__ ((weak));

extern int pthread_key_create (pthread_key_t *, void (*) (void *))
  __attribute__ ((weak));

extern int pthread_setspecific (pthread_key_t, const void *)
  __attribute__ ((weak));

/* The key for the list of stack segments to free when the thread
   exits.  This is created by pthread_key_create.  */

static pthread_key_t segment_list_key;

/* Used to only run create_key once.  */

static pthread_once_t create_key_once = PTHREAD_ONCE_INIT;

/* Release all the segments for a thread.  This is the destructor
   function used by pthread_key_create, and is called when a thread
   exits.  */

static void
free_segments (void* arg)
{
  __morestack_release_segments ((struct stack_segment **) arg, 1);
}

/* Set up the key for the list of segments.  This is called via
   pthread_once.  */

static void
create_key (void)
{
  int err;

  err = pthread_key_create (&segment_list_key, free_segments);
  if (err != 0)
    {
      static const char msg[] = "pthread_key_create failed: errno ";
      __morestack_fail (msg, sizeof msg - 1, err);
    }
}

/* Pass information from the pthread_create wrapper to
   stack_split_initialize_thread.  */

struct pthread_create_args
{
  void *(*start_routine) (void *);
  void *arg;
};

/* Initialize a thread.  This is called via pthread_create.  It calls
   a target dependent function to set up any required stack guard.  */

static void* stack_split_initialize_thread (void *)
  __attribute__ ((no_split_stack));

static void *
stack_split_initialize_thread (void *varg)
{
  struct pthread_create_args *args = (struct pthread_create_args *) varg;
  int err;
  void *(*start_routine) (void *);
  void *arg;

  __stack_split_initialize ();

  err = pthread_setspecific (segment_list_key, (void *) &__morestack_segments);
  if (err != 0)
    {
      static const char msg[] = "pthread_setspecific failed: errno ";
      __morestack_fail (msg, sizeof msg - 1, err);
    }

  start_routine = args->start_routine;
  arg = args->arg;
  free (args);
  return (*start_routine) (arg);
}

/* This function wraps calls to pthread_create to make sure that the
   stack guard is initialized for new threads.  FIXME: This hack will
   not be necessary if glibc supports -fsplit-stack directly.  */

int __wrap_pthread_create (pthread_t *, const pthread_attr_t *,
			   void *(*start_routine) (void *), void *)
  __attribute__ ((visibility ("hidden")));

extern int __real_pthread_create (pthread_t *, const pthread_attr_t *,
				  void *(*start_routine) (void *), void *)
  __attribute__ ((weak));

int
__wrap_pthread_create (pthread_t *tid, const pthread_attr_t *attr,
		       void *(*start_routine) (void *), void *arg)
{
  int err;
  struct pthread_create_args* args;

  err = pthread_once (&create_key_once, create_key);
  if (err != 0)
    {
      static const char msg[] = "pthread_once failed: errno ";
      __morestack_fail (msg, sizeof msg - 1, err);
    }

  args = malloc (sizeof (struct pthread_create_args));
  if (args == NULL)
    return EAGAIN;
  args->start_routine = start_routine;
  args->arg = arg;
  return __real_pthread_create (tid, attr, stack_split_initialize_thread, args);
}

#endif /* !defined (inhibit_libc) */
