/* Creating and controlling threads.
   Copyright (C) 2005-2026 Free Software Foundation, Inc.

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

   This file 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 this program.  If not, see <https://www.gnu.org/licenses/>.  */

/* Written by Bruno Haible <bruno@clisp.org>, 2005.
   Based on GCC's gthr-posix.h, gthr-posix95.h, gthr-win32.h.  */

#include <config.h>

/* Specification.  */
#include "glthread/thread.h"

#include <stdlib.h>

/* ========================================================================= */

#if USE_ISOC_THREADS

struct thrd_with_exitvalue
{
  thrd_t volatile tid;
  void * volatile exitvalue;
};

/* The Thread-Specific Storage (TSS) key that allows accessing each thread's
   'struct thrd_with_exitvalue *' pointer.  */
static tss_t thrd_with_exitvalue_key;

/* Initializes thrd_with_exitvalue_key.
   This function must only be called once.  */
static void
do_init_thrd_with_exitvalue_key (void)
{
  if (tss_create (&thrd_with_exitvalue_key, NULL) != thrd_success)
    abort ();
}

/* Initializes thrd_with_exitvalue_key.  */
static void
init_thrd_with_exitvalue_key (void)
{
  static once_flag once = ONCE_FLAG_INIT;
  call_once (&once, do_init_thrd_with_exitvalue_key);
}

typedef union
        {
          struct thrd_with_exitvalue t;
          struct
          {
            thrd_t tid; /* reserve memory for t.tid */
            void *(*mainfunc) (void *);
            void *arg;
          } a;
        }
        main_arg_t;

static int
thrd_main_func (void *pmarg)
{
  /* Unpack the object that combines mainfunc and arg.  */
  main_arg_t *main_arg = (main_arg_t *) pmarg;
  void *(*mainfunc) (void *) = main_arg->a.mainfunc;
  void *arg = main_arg->a.arg;

  if (tss_set (thrd_with_exitvalue_key, &main_arg->t) != thrd_success)
    abort ();

  /* Execute mainfunc, with arg as argument.  */
  {
    void *exitvalue = mainfunc (arg);
    /* Store the exitvalue, for use by glthread_join().  */
    main_arg->t.exitvalue = exitvalue;
    return 0;
  }
}

int
glthread_create (gl_thread_t *threadp, void *(*mainfunc) (void *), void *arg)
{
  init_thrd_with_exitvalue_key ();
  {
    /* Combine mainfunc and arg in a single object.
       A stack-allocated object does not work, because it would be out of
       existence when thrd_create returns before thrd_main_func is
       entered.  So, allocate it in the heap.  */
    main_arg_t *main_arg = (main_arg_t *) malloc (sizeof (main_arg_t));
    if (main_arg == NULL)
      return ENOMEM;
    main_arg->a.mainfunc = mainfunc;
    main_arg->a.arg = arg;
    switch (thrd_create ((thrd_t *) &main_arg->t.tid, thrd_main_func, main_arg))
      {
      case thrd_success:
        break;
      case thrd_nomem:
        free (main_arg);
        return ENOMEM;
      default:
        free (main_arg);
        return EAGAIN;
      }
    *threadp = &main_arg->t;
    return 0;
  }
}

gl_thread_t
gl_thread_self (void)
{
  init_thrd_with_exitvalue_key ();
  {
    gl_thread_t thread =
      (struct thrd_with_exitvalue *) tss_get (thrd_with_exitvalue_key);
    if (thread == NULL)
      {
        /* This happens only in threads that have not been created through
           glthread_create(), such as the main thread.  */
        for (;;)
          {
            thread =
              (struct thrd_with_exitvalue *)
              malloc (sizeof (struct thrd_with_exitvalue));
            if (thread != NULL)
              break;
            /* Memory allocation failed.  There is not much we can do.  Have to
               busy-loop, waiting for the availability of memory.  */
            {
              struct timespec ts =
                {
                  .tv_sec = 1,
                  .tv_nsec = 0
                };
              thrd_sleep (&ts, NULL);
            }
          }
        thread->tid = thrd_current ();
        thread->exitvalue = NULL; /* just to be deterministic */
        if (tss_set (thrd_with_exitvalue_key, thread) != thrd_success)
          abort ();
      }
    return thread;
  }
}

int
glthread_join (gl_thread_t thread, void **return_value_ptr)
{
  /* On Solaris 11.4, thrd_join crashes when the second argument we pass is
     NULL.  */
  int dummy;

  if (thread == gl_thread_self ())
    return EINVAL;
  if (thrd_join (thread->tid, &dummy) != thrd_success)
    return EINVAL;
  if (return_value_ptr != NULL)
    *return_value_ptr = thread->exitvalue;
  free (thread);
  return 0;
}

_Noreturn void
gl_thread_exit (void *return_value)
{
  gl_thread_t thread = gl_thread_self ();
  thread->exitvalue = return_value;
  thrd_exit (0);
}

#endif

/* ========================================================================= */

#if USE_POSIX_THREADS || USE_ISOC_AND_POSIX_THREADS

#include <pthread.h>

#if defined PTW32_VERSION || defined __MVS__

const gl_thread_t gl_null_thread /* = { .p = NULL } */;

#endif

#endif

/* ========================================================================= */

#if USE_WINDOWS_THREADS

#endif

/* ========================================================================= */

gl_thread_t
gl_thread_create (void *(*func) (void *arg), void *arg)
{
  gl_thread_t thread;
  int ret = glthread_create (&thread, func, arg);
  if (ret != 0)
    abort ();
  return thread;
}
