/* Thread pool

   Copyright (C) 2019-2024 Free Software Foundation, Inc.

   This file is part of GDB.

   This program 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 of the License, or
   (at your option) any later version.

   This program 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.

   You should have received a copy of the GNU General Public License
   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */

#include "gdbsupport/thread-pool.h"

#if CXX_STD_THREAD

#include "gdbsupport/alt-stack.h"
#include "gdbsupport/block-signals.h"
#include <algorithm>
#include <system_error>

/* On the off chance that we have the pthread library on a Windows
   host, but std::thread is not using it, avoid calling
   pthread_setname_np on Windows.  */
#ifndef _WIN32
#ifdef HAVE_PTHREAD_SETNAME_NP
#define USE_PTHREAD_SETNAME_NP
#endif
#endif

#ifdef USE_PTHREAD_SETNAME_NP

#include <pthread.h>

/* Handle platform discrepancies in pthread_setname_np: macOS uses a
   single-argument form, while Linux uses a two-argument form.  NetBSD
   takes a printf-style format and an argument.  This wrapper handles the
   difference.  */

ATTRIBUTE_UNUSED static void
do_set_thread_name (int (*set_name) (pthread_t, const char *, void *),
		    const char *name)
{
  set_name (pthread_self (), "%s", const_cast<char *> (name));
}

ATTRIBUTE_UNUSED static void
do_set_thread_name (int (*set_name) (pthread_t, const char *),
		    const char *name)
{
  set_name (pthread_self (), name);
}

/* The macOS man page says that pthread_setname_np returns "void", but
   the headers actually declare it returning "int".  */
ATTRIBUTE_UNUSED static void
do_set_thread_name (int (*set_name) (const char *), const char *name)
{
  set_name (name);
}

static void
set_thread_name (const char *name)
{
  do_set_thread_name (pthread_setname_np, name);
}

#elif defined (USE_WIN32API)

#include <windows.h>

typedef HRESULT WINAPI (SetThreadDescription_ftype) (HANDLE, PCWSTR);
static SetThreadDescription_ftype *dyn_SetThreadDescription;
static bool initialized;

static void
init_windows ()
{
  initialized = true;

  HMODULE hm = LoadLibrary (TEXT ("kernel32.dll"));
  if (hm)
    dyn_SetThreadDescription
      = (SetThreadDescription_ftype *) GetProcAddress (hm,
						       "SetThreadDescription");

  /* On some versions of Windows, this function is only available in
     KernelBase.dll, not kernel32.dll.  */
  if (dyn_SetThreadDescription == nullptr)
    {
      hm = LoadLibrary (TEXT ("KernelBase.dll"));
      if (hm)
	dyn_SetThreadDescription
	  = (SetThreadDescription_ftype *) GetProcAddress (hm,
							   "SetThreadDescription");
    }
}

static void
do_set_thread_name (const wchar_t *name)
{
  if (!initialized)
    init_windows ();

  if (dyn_SetThreadDescription != nullptr)
    dyn_SetThreadDescription (GetCurrentThread (), name);
}

#define set_thread_name(NAME) do_set_thread_name (L ## NAME)

#else /* USE_WIN32API */

static void
set_thread_name (const char *name)
{
}

#endif

#endif /* CXX_STD_THREAD */

namespace gdb
{

/* The thread pool detach()s its threads, so that the threads will not
   prevent the process from exiting.  However, it was discovered that
   if any detached threads were still waiting on a condition variable,
   then the condition variable's destructor would wait for the threads
   to exit -- defeating the purpose.

   Allocating the thread pool on the heap and simply "leaking" it
   avoids this problem.
*/
thread_pool *thread_pool::g_thread_pool = new thread_pool ();

thread_pool::~thread_pool ()
{
  /* Because this is a singleton, we don't need to clean up.  The
     threads are detached so that they won't prevent process exit.
     And, cleaning up here would be actively harmful in at least one
     case -- see the comment by the definition of g_thread_pool.  */
}

void
thread_pool::set_thread_count (size_t num_threads)
{
#if CXX_STD_THREAD
  std::lock_guard<std::mutex> guard (m_tasks_mutex);
  m_sized_at_least_once = true;

  /* If the new size is larger, start some new threads.  */
  if (m_thread_count < num_threads)
    {
      /* Ensure that signals used by gdb are blocked in the new
	 threads.  */
      block_signals blocker;
      for (size_t i = m_thread_count; i < num_threads; ++i)
	{
	  try
	    {
	      std::thread thread (&thread_pool::thread_function, this);
	      thread.detach ();
	    }
	  catch (const std::system_error &)
	    {
	      /* libstdc++ may not implement std::thread, and will
		 throw an exception on use.  It seems fine to ignore
		 this, and any other sort of startup failure here.  */
	      num_threads = i;
	      break;
	    }
	}
    }
  /* If the new size is smaller, terminate some existing threads.  */
  if (num_threads < m_thread_count)
    {
      for (size_t i = num_threads; i < m_thread_count; ++i)
	m_tasks.emplace ();
      m_tasks_cv.notify_all ();
    }

  m_thread_count = num_threads;
#else
  /* No threads available, simply ignore the request.  */
#endif /* CXX_STD_THREAD */
}

#if CXX_STD_THREAD

void
thread_pool::do_post_task (std::packaged_task<void ()> &&func)
{
  /* This assert is here to check that no tasks are posted to the pool between
     its initialization and sizing.  */
  gdb_assert (m_sized_at_least_once);
  std::packaged_task<void ()> t (std::move (func));

  if (m_thread_count != 0)
    {
      std::lock_guard<std::mutex> guard (m_tasks_mutex);
      m_tasks.emplace (std::move (t));
      m_tasks_cv.notify_one ();
    }
  else
    {
      /* Just execute it now.  */
      t ();
    }
}

void
thread_pool::thread_function ()
{
  /* This must be done here, because on macOS one can only set the
     name of the current thread.  */
  set_thread_name ("gdb worker");

  /* Ensure that SIGSEGV is delivered to an alternate signal
     stack.  */
  gdb::alternate_signal_stack signal_stack;

  while (true)
    {
      std::optional<task_t> t;

      {
	/* We want to hold the lock while examining the task list, but
	   not while invoking the task function.  */
	std::unique_lock<std::mutex> guard (m_tasks_mutex);
	while (m_tasks.empty ())
	  m_tasks_cv.wait (guard);
	t = std::move (m_tasks.front());
	m_tasks.pop ();
      }

      if (!t.has_value ())
	break;
      (*t) ();
    }
}

#endif /* CXX_STD_THREAD */

} /* namespace gdb */
