/* Test basic thread_local support.
   Copyright (C) 2015-2018 Free Software Foundation, Inc.
   This file is part of the GNU C Library.

   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, see
   <http://www.gnu.org/licenses/>.  */

#include <errno.h>
#include <pthread.h>
#include <stdio.h>
#include <string.h>

#include <functional>
#include <string>
#include <thread>

struct counter
{
  int constructed {};
  int destructed {};

  void reset ();
};

void
counter::reset ()
{
  constructed = 0;
  destructed = 0;
}

static std::string
to_string (const counter &c)
{
  char buf[128];
  snprintf (buf, sizeof (buf), "%d/%d",
            c.constructed, c.destructed);
  return buf;
}

template <counter *Counter>
struct counting
{
  counting () __attribute__ ((noinline, noclone));
  ~counting () __attribute__ ((noinline, noclone));
  void operation () __attribute__ ((noinline, noclone));
};

template<counter *Counter>
__attribute__ ((noinline, noclone))
counting<Counter>::counting ()
{
  ++Counter->constructed;
}

template<counter *Counter>
__attribute__ ((noinline, noclone))
counting<Counter>::~counting ()
{
  ++Counter->destructed;
}

template<counter *Counter>
void __attribute__ ((noinline, noclone))
counting<Counter>::operation ()
{
  // Optimization barrier.
  asm ("");
}

static counter counter_static;
static counter counter_anonymous_namespace;
static counter counter_extern;
static counter counter_function_local;
static bool errors (false);

static std::string
all_counters ()
{
  return to_string (counter_static)
    + ' ' + to_string (counter_anonymous_namespace)
    + ' ' + to_string (counter_extern)
    + ' ' + to_string (counter_function_local);
}

static void
check_counters (const char *name, const char *expected)
{
  std::string actual{all_counters ()};
  if (actual != expected)
    {
      printf ("error: %s: (%s) != (%s)\n",
              name, actual.c_str (), expected);
      errors = true;
    }
}

static void
reset_all ()
{
  counter_static.reset ();
  counter_anonymous_namespace.reset ();
  counter_extern.reset ();
  counter_function_local.reset ();
}

static thread_local counting<&counter_static> counting_static;
namespace {
  thread_local counting<&counter_anonymous_namespace>
    counting_anonymous_namespace;
}
extern thread_local counting<&counter_extern> counting_extern;
thread_local counting<&counter_extern> counting_extern;

static void *
thread_without_access (void *)
{
  return nullptr;
}

static void *
thread_with_access (void *)
{
  thread_local counting<&counter_function_local> counting_function_local;
  counting_function_local.operation ();
  check_counters ("early in thread_with_access", "0/0 0/0 0/0 1/0");
  counting_static.operation ();
  counting_anonymous_namespace.operation ();
  counting_extern.operation ();
  check_counters ("in thread_with_access", "1/0 1/0 1/0 1/0");
  return nullptr;
}

static int
do_test (void)
{
  std::function<void (void *(void *))> do_pthread =
    [](void *(func) (void *))
    {
      pthread_t thr;
      int ret = pthread_create (&thr, nullptr, func, nullptr);
      if (ret != 0)
        {
          errno = ret;
          printf ("error: pthread_create: %m\n");
          errors = true;
          return;
        }
      ret = pthread_join (thr, nullptr);
      if (ret != 0)
        {
          errno = ret;
          printf ("error: pthread_join: %m\n");
          errors = true;
          return;
        }
    };
  std::function<void (void *(void *))> do_std_thread =
    [](void *(func) (void *))
    {
      std::thread thr{[func] {func (nullptr);}};
      thr.join ();
    };

  std::array<std::pair<const char *, std::function<void (void *(void *))>>, 2>
    do_thread_X
      {{
        {"pthread_create", do_pthread},
        {"std::thread", do_std_thread},
      }};

  for (auto do_thread : do_thread_X)
    {
      printf ("info: testing %s\n", do_thread.first);
      check_counters ("initial", "0/0 0/0 0/0 0/0");
      do_thread.second (thread_without_access);
      check_counters ("after thread_without_access", "0/0 0/0 0/0 0/0");
      reset_all ();
      do_thread.second (thread_with_access);
      check_counters ("after thread_with_access", "1/1 1/1 1/1 1/1");
      reset_all ();
    }

  return errors;
}

#define TEST_FUNCTION do_test ()
#include "../test-skeleton.c"
