/* Copyright (C) 2002-2025 Free Software Foundation, Inc.
   Contributed by Zack Weinberg <zack@codesourcery.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/>.  */

/* Threads compatibility routines for libgcc2 for VxWorks.
   These are out-of-line routines called from gthr-vxworks.h.

   This file provides the TLS related support routines, calling specific
   VxWorks kernel entry points for this purpose.  */

#include "tconfig.h"
#include "tsystem.h"
#include "gthr.h"

#if defined(__GTHREADS)

#include <vxWorks.h>
#ifndef __RTP__
#include <vxLib.h>
#endif
#include <taskLib.h>
#ifndef __RTP__
#include <taskHookLib.h>
#else
#include <errno.h>
#endif

#include <_vxworks-versions.h>

/* Thread-local storage.

   A gthread TLS key is simply an offset in an array, the address of which
   we store in a single pointer field associated with the current task.

   On VxWorks 7, we have direct support for __thread variables and use
   such a variable as the pointer "field".  On other versions, we resort
   to __gthread_get_tls_data and __gthread_set_tls_data functions provided
   by the kernel.

   There is also a global array which records which keys are valid and
   which have destructors.

   A task delete hook is installed to execute key destructors.  The routines
   __gthread_enter_tls_dtor_context and __gthread_leave_tls_dtor_context,
   which are also provided by the kernel, ensure that it is safe to call
   free() on memory allocated by the task being deleted.  This is a no-op on
   VxWorks 5, but a major undertaking on AE.

   The task delete hook is only installed when at least one thread
   has TLS data.  This is a necessary precaution, to allow this module
   to be unloaded - a module with a hook can not be removed.

   Since this interface is used to allocate only a small number of
   keys, the table size is small and static, which simplifies the
   code quite a bit.  Revisit this if and when it becomes necessary.  */

#define MAX_KEYS 4

/* This is the structure pointed to by the pointer returned
   by __gthread_get_tls_data.  */
struct tls_data
{
  int *owner;
  void *values[MAX_KEYS];
  unsigned int generation[MAX_KEYS];
};

/* To make sure we only delete TLS data associated with this object,
   include a pointer to a local variable in the TLS data object.  */
static int self_owner;

/* Flag to check whether the delete hook is installed.  Once installed
   it is only removed when unloading this module.  */
static volatile int delete_hook_installed;

/* TLS data access internal API.  A straight __thread variable starting with
   VxWorks 7, a pointer returned by kernel provided routines otherwise.  And
   on VxWorks 6, the kernel expects us to notify entry/exit of regions
   handling such variables by calls to kernel provided __gthread routines.  */

#if _VXWORKS_MAJOR_GE(7)

static __thread struct tls_data *__gthread_tls_data;

#define VX_GET_TLS_DATA() __gthread_tls_data
#define VX_SET_TLS_DATA(x) __gthread_tls_data = (x)

#else

extern void *__gthread_get_tls_data (void);
extern void __gthread_set_tls_data (void *data);

#define VX_GET_TLS_DATA() __gthread_get_tls_data()
#define VX_SET_TLS_DATA(x) __gthread_set_tls_data(x)

#endif

#if _VXWORKS_MAJOR_EQ(6)

extern void __gthread_enter_tls_dtor_context (void);
extern void __gthread_leave_tls_dtor_context (void);

#define VX_ENTER_TLS_DTOR() __gthread_enter_tls_dtor_context ()
#define VX_LEAVE_TLS_DTOR() __gthread_leave_tls_dtor_context ()

#else

#define VX_ENTER_TLS_DTOR()
#define VX_LEAVE_TLS_DTOR()

#endif

/* This is a global structure which records all of the active keys.

   A key is potentially valid (i.e. has been handed out by
   __gthread_key_create) iff its generation count in this structure is
   even.  In that case, the matching entry in the dtors array is a
   routine to be called when a thread terminates with a valid,
   non-NULL specific value for that key.

   A key is actually valid in a thread T iff the generation count
   stored in this structure is equal to the generation count stored in
   T's specific-value structure.  */

typedef void (*tls_dtor) (void *);

struct tls_keys
{
  tls_dtor dtor[MAX_KEYS];
  unsigned int generation[MAX_KEYS];
};

#define KEY_VALID_P(key) !(tls_keys.generation[key] & 1)

/* Note: if MAX_KEYS is increased, this initializer must be updated
   to match.  All the generation counts begin at 1, which means no
   key is valid.  */
static struct tls_keys tls_keys =
{
  { NULL, NULL, NULL, NULL },
  { 1, 1, 1, 1 }
};

/* This lock protects the tls_keys structure.  */
static __gthread_mutex_t tls_lock;

static __gthread_once_t tls_init_guard = __GTHREAD_ONCE_INIT;

/* Internal routines.  */

/* The task deletion hooks for TLS handling have different prototypes
   for kernel or rtp modes.  The RTP variant expects a TCB argument, which,
   fortunately, we don't need to use.  */

#ifdef __RTP__
#define TLS_DELETE_HOOK_ARG_DECL TASK_ID tcb ATTRIBUTE_UNUSED
#define TLS_DELETE_HOOK_ARG NULL
#else
#define TLS_DELETE_HOOK_ARG_DECL void
#define TLS_DELETE_HOOK_ARG
#endif

STATUS tls_delete_hook (TLS_DELETE_HOOK_ARG_DECL);


/* A task has just been deleted.  Call the destructor
   function for each TLS key that has both a destructor and
   a non-NULL specific value in this thread.

   This routine does not need to take tls_lock; the generation
   count protects us from calling a stale destructor.  It does
   need to read tls_keys.dtor[key] atomically.  */

STATUS
tls_delete_hook (TLS_DELETE_HOOK_ARG_DECL)
{
  struct tls_data *data;
  __gthread_key_t key;

  data = VX_GET_TLS_DATA();

  if (data && data->owner == &self_owner)
    {
      VX_ENTER_TLS_DTOR();
      for (key = 0; key < MAX_KEYS; key++)
	{
	  if (data->generation[key] == tls_keys.generation[key])
	    {
	      tls_dtor dtor = tls_keys.dtor[key];

	      if (dtor)
		dtor (data->values[key]);
	    }
	}
      free (data);

      VX_LEAVE_TLS_DTOR();
      VX_SET_TLS_DATA(NULL);
    }

  return OK;
}

/* Initialize global data used by the TLS system.  */
static void
tls_init (void)
{
  __GTHREAD_MUTEX_INIT_FUNCTION (&tls_lock);
}

static void tls_destructor (void) __attribute__ ((destructor));
static void
tls_destructor (void)
{
#ifdef __RTP__
  /* All threads but this one should have exited by now.  */
  tls_delete_hook (TLS_DELETE_HOOK_ARG);
#endif
  /* Unregister the hook.  */
  if (delete_hook_installed)
    taskDeleteHookDelete (tls_delete_hook);

  if (tls_init_guard.done && __gthread_mutex_lock (&tls_lock) != ERROR)
    semDelete (tls_lock);
}

/* External interface */

/* Store in KEYP a value which can be passed to __gthread_setspecific/
   __gthread_getspecific to store and retrieve a value which is
   specific to each calling thread.  If DTOR is not NULL, it will be
   called when a thread terminates with a non-NULL specific value for
   this key, with the value as its sole argument.  */

int
__gthread_key_create (__gthread_key_t *keyp, tls_dtor dtor)
{
  __gthread_key_t key;

  __gthread_once (&tls_init_guard, tls_init);

  if (__gthread_mutex_lock (&tls_lock) == ERROR)
    return errno;

  for (key = 0; key < MAX_KEYS; key++)
    if (!KEY_VALID_P (key))
      goto found_slot;

  /* no room */
  __gthread_mutex_unlock (&tls_lock);
  return EAGAIN;

 found_slot:
  tls_keys.generation[key]++;  /* making it even */
  tls_keys.dtor[key] = dtor;
  *keyp = key;
  __gthread_mutex_unlock (&tls_lock);
  return 0;
}

/* Invalidate KEY; it can no longer be used as an argument to
   setspecific/getspecific.  Note that this does NOT call destructor
   functions for any live values for this key.  */
int
__gthread_key_delete (__gthread_key_t key)
{
  if (key >= MAX_KEYS)
    return EINVAL;

  __gthread_once (&tls_init_guard, tls_init);

  if (__gthread_mutex_lock (&tls_lock) == ERROR)
    return errno;

  if (!KEY_VALID_P (key))
    {
      __gthread_mutex_unlock (&tls_lock);
      return EINVAL;
    }

  tls_keys.generation[key]++;  /* making it odd */
  tls_keys.dtor[key] = 0;

  __gthread_mutex_unlock (&tls_lock);
  return 0;
}

/* Retrieve the thread-specific value for KEY.  If it has never been
   set in this thread, or KEY is invalid, returns NULL.

   It does not matter if this function races with key_create or
   key_delete; the worst that can happen is you get a value other than
   the one that a serialized implementation would have provided.  */

void *
__gthread_getspecific (__gthread_key_t key)
{
  struct tls_data *data;

  if (key >= MAX_KEYS)
    return 0;

  data = VX_GET_TLS_DATA();

  if (!data)
    return 0;

  if (data->generation[key] != tls_keys.generation[key])
    return 0;

  return data->values[key];
}

/* Set the thread-specific value for KEY.  If KEY is invalid, or
   memory allocation fails, returns -1, otherwise 0.

   The generation count protects this function against races with
   key_create/key_delete; the worst thing that can happen is that a
   value is successfully stored into a dead generation (and then
   immediately becomes invalid).  However, we do have to make sure
   to read tls_keys.generation[key] atomically.  */

int
__gthread_setspecific (__gthread_key_t key, void *value)
{
  struct tls_data *data;
  unsigned int generation;

  if (key >= MAX_KEYS)
    return EINVAL;

  data = VX_GET_TLS_DATA();

  if (!data)
    {
      if (!delete_hook_installed)
	{
	  /* Install the delete hook.  */
	  if (__gthread_mutex_lock (&tls_lock) == ERROR)
	    return ENOMEM;
	  if (!delete_hook_installed)
	    {
	      taskDeleteHookAdd (tls_delete_hook);
	      delete_hook_installed = 1;
	    }
	  __gthread_mutex_unlock (&tls_lock);
	}

      data = malloc (sizeof (struct tls_data));
      if (!data)
	return ENOMEM;

      memset (data, 0, sizeof (struct tls_data));
      data->owner = &self_owner;

      VX_SET_TLS_DATA(data);
    }

  generation = tls_keys.generation[key];

  if (generation & 1)
    return EINVAL;

  data->generation[key] = generation;
  data->values[key] = value;

  return 0;
}
#endif /* __GTHREADS */
