/* GNU Objective C Runtime Thread Interface
   Copyright (C) 1996-2025 Free Software Foundation, Inc.
   Contributed by Galen C. Hunt (gchunt@cs.rochester.edu)

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 "objc-private/common.h"
#include "objc-private/error.h"
#define _LIBOBJC
#include "config.h"
#include "tconfig.h"
#include "coretypes.h"
#include "tm.h"
#include "defaults.h"
#include "objc/thr.h"
#include "objc/message.h" /* For objc_msg_lookup().  */
#include "objc/runtime.h"
#include "objc-private/module-abi-8.h"
#include "objc-private/runtime.h"
#include <gthr.h>

#include <stdlib.h>

/* Global exit status. */
int __objc_thread_exit_status = 0;

/* Flag which lets us know if we ever became multi threaded.  */
int __objc_is_multi_threaded = 0;

/* The hook function called when the runtime becomes multi
   threaded.  */
objc_thread_callback _objc_became_multi_threaded = NULL;

/* Use this to set the hook function that will be called when the
   runtime initially becomes multi threaded.  The hook function is
   only called once, meaning only when the 2nd thread is spawned, not
   for each and every thread.

   It returns the previous hook function or NULL if there is none.

   A program outside of the runtime could set this to some function so
   it can be informed; for example, the GNUstep Base Library sets it
   so it can implement the NSBecomingMultiThreaded notification.  */
objc_thread_callback objc_set_thread_callback (objc_thread_callback func)
{
  objc_thread_callback temp = _objc_became_multi_threaded;
  _objc_became_multi_threaded = func;
  return temp;
}

/* Private functions.
   
   These functions are utilized by the runtime, but they are not
   considered part of the public interface.  */

/* Initialize the threads subsystem.  */
int
__objc_init_thread_system(void)
{
  return __gthread_objc_init_thread_system ();
}

/* First function called in a thread, starts everything else.

   This function is passed to the backend by objc_thread_detach as the
   starting function for a new thread.  */
struct __objc_thread_start_state
{
  SEL selector;
  id object;
  id argument;
};

static void __attribute__((noreturn))
__objc_thread_detach_function (struct __objc_thread_start_state *istate) 
{
  /* Valid state? */
  if (istate)
    {
      id (*imp) (id, SEL, id);
      SEL selector = istate->selector;
      id object   = istate->object;
      id argument = istate->argument;
      
      /* Don't need anymore so free it.  */
      objc_free (istate);

      /* Clear out the thread local storage.  */
      objc_thread_set_data (NULL);
      
      /* Check to see if we just became multi threaded. */
      if (! __objc_is_multi_threaded)
	{
	  __objc_is_multi_threaded = 1;
	  
	  /* Call the hook function.  */
	  if (_objc_became_multi_threaded != NULL)
	    (*_objc_became_multi_threaded) ();
	}
      
      /* Call the method.  */
      if ((imp = (id (*) (id, SEL, id))objc_msg_lookup (object, selector)))
	(*imp) (object, selector, argument);
      else
	{
	  /* FIXME: Should we abort here ? */
	  _objc_abort ("objc_thread_detach called with bad selector.\n");
	}
    }
  else
    {
      /* FIXME: Should we abort here ? */
      _objc_abort ("objc_thread_detach called with NULL state.\n");
    }
  
  /* Exit the thread.  */
  objc_thread_exit ();
  
  /* Make sure compiler detects no return.  */
  __builtin_trap ();
}

/* Public functions.

   These functions constitute the public interface to the Objective-C
   thread and mutex functionality.  */

/* Detach a new thread of execution and return its id.  Returns NULL
   if fails.  Thread is started by sending message with selector to
   object.  Message takes a single argument.  */
objc_thread_t
objc_thread_detach (SEL selector, id object, id argument)
{
  struct __objc_thread_start_state *istate;
  objc_thread_t        thread_id = NULL;

  /* Allocate the state structure.  */
  if (!(istate = (struct __objc_thread_start_state *)objc_malloc
	(sizeof (*istate))))
    return NULL;
  
  /* Initialize the state structure.  */
  istate->selector = selector;
  istate->object = object;
  istate->argument = argument;

  /* Lock access.  */
  objc_mutex_lock (__objc_runtime_mutex);

  /* Call the backend to spawn the thread.  */
  if ((thread_id = __gthread_objc_thread_detach ((void *)__objc_thread_detach_function,
						 istate)) == NULL)
    {
      /* Failed!  */
      objc_mutex_unlock (__objc_runtime_mutex);
      objc_free (istate);
      return NULL;
    }

  /* Increment our thread counter.  */
  __objc_runtime_threads_alive++;
  objc_mutex_unlock (__objc_runtime_mutex);

  return thread_id;
}

/* Set the current thread's priority.  */
int
objc_thread_set_priority (int priority)
{
  return __gthread_objc_thread_set_priority (priority);
}

/* Return the current thread's priority.  */
int
objc_thread_get_priority (void)
{
  return __gthread_objc_thread_get_priority ();
}

/* Yield our process time to another thread.  Any BUSY waiting that is
   done by a thread should use this function to make sure that other
   threads can make progress even on a lazy uniprocessor system.  */
void
objc_thread_yield (void)
{
  __gthread_objc_thread_yield ();
}

/* Terminate the current thread.  Doesn't return.  Actually, if it
   failed returns -1.  */
int
objc_thread_exit (void)
{
  /* Decrement our counter of the number of threads alive.  */
  objc_mutex_lock (__objc_runtime_mutex);
  __objc_runtime_threads_alive--;
  objc_mutex_unlock (__objc_runtime_mutex);

  /* Call the backend to terminate the thread.  */
  return __gthread_objc_thread_exit ();
}

/* Returns an integer value which uniquely describes a thread.  Must
   not be NULL which is reserved as a marker for "no thread".  */
objc_thread_t
objc_thread_id (void)
{
  return __gthread_objc_thread_id ();
}

/* Sets the thread's local storage pointer.  Returns 0 if successful
   or -1 if failed.  */
int
objc_thread_set_data (void *value)
{
  return __gthread_objc_thread_set_data (value);
}

/* Returns the thread's local storage pointer.  Returns NULL on
   failure.  */
void *
objc_thread_get_data (void)
{
  return __gthread_objc_thread_get_data ();
}

/* Public mutex functions */

/* Allocate a mutex.  Return the mutex pointer if successful or NULL
   if the allocation failed for any reason.  */
objc_mutex_t
objc_mutex_allocate (void)
{
  objc_mutex_t mutex;

  /* Allocate the mutex structure.  */
  if (! (mutex = (objc_mutex_t)objc_malloc (sizeof (struct objc_mutex))))
    return NULL;

  /* Call backend to create the mutex.  */
  if (__gthread_objc_mutex_allocate (mutex))
    {
      /* Failed!  */
      objc_free (mutex);
      return NULL;
    }

  /* Initialize mutex.  */
  mutex->owner = NULL;
  mutex->depth = 0;
  return mutex;
}

/* Deallocate a mutex.  Note that this includes an implicit mutex_lock
   to insure that no one else is using the lock.  It is legal to
   deallocate a lock if we have a lock on it, but illegal to
   deallocate a lock held by anyone else.  Returns the number of locks
   on the thread.  (1 for deallocate).  */
int
objc_mutex_deallocate (objc_mutex_t mutex)
{
  int depth;

  /* Valid mutex?  */
  if (! mutex)
    return -1;

  /* Acquire lock on mutex.  */
  depth = objc_mutex_lock (mutex);

  /* Call backend to destroy mutex.  */
  if (__gthread_objc_mutex_deallocate (mutex))
    return -1;

  /* Free the mutex structure.  */
  objc_free (mutex);

  /* Return last depth.  */
  return depth;
}

/* Grab a lock on a mutex.  If this thread already has a lock on this
   mutex then we increment the lock count.  If another thread has a
   lock on the mutex we block and wait for the thread to release the
   lock.  Returns the lock count on the mutex held by this thread.  */
int
objc_mutex_lock (objc_mutex_t mutex)
{
  objc_thread_t thread_id;
  int status;

  /* Valid mutex?  */
  if (! mutex)
    return -1;

  /* If we already own the lock then increment depth.  */
  thread_id = __gthread_objc_thread_id ();
  if (mutex->owner == thread_id)
    return ++mutex->depth;

  /* Call the backend to lock the mutex.  */
  status = __gthread_objc_mutex_lock (mutex);

  /* Failed?  */
  if (status)
    return status;

  /* Successfully locked the thread.  */
  mutex->owner = thread_id;
  return mutex->depth = 1;
}

/* Try to grab a lock on a mutex.  If this thread already has a lock
   on this mutex then we increment the lock count and return it.  If
   another thread has a lock on the mutex returns -1.  */
int
objc_mutex_trylock (objc_mutex_t mutex)
{
  objc_thread_t thread_id;
  int status;

  /* Valid mutex?  */
  if (! mutex)
    return -1;

  /* If we already own the lock then increment depth.  */
  thread_id = __gthread_objc_thread_id ();
  if (mutex->owner == thread_id)
    return ++mutex->depth;
    
  /* Call the backend to try to lock the mutex.  */
  status = __gthread_objc_mutex_trylock (mutex);

  /* Failed?  */
  if (status)
    return status;

  /* Successfully locked the thread.  */
  mutex->owner = thread_id;
  return mutex->depth = 1;
}

/* Unlocks the mutex by one level.  Decrements the lock count on this
   mutex by one.  If the lock count reaches zero, release the lock on
   the mutex.  Returns the lock count on the mutex.  It is an error to
   attempt to unlock a mutex which this thread doesn't hold in which
   case return -1 and the mutex is unaffected.  */
int
objc_mutex_unlock (objc_mutex_t mutex)
{
  objc_thread_t thread_id;
  int status;

  /* Valid mutex?  */
  if (! mutex)
    return -1;

  /* If another thread owns the lock then abort.  */
  thread_id = __gthread_objc_thread_id ();
  if (mutex->owner != thread_id)
    return -1;

  /* Decrement depth and return.  */
  if (mutex->depth > 1)
    return --mutex->depth;

  /* Depth down to zero so we are no longer the owner.  */
  mutex->depth = 0;
  mutex->owner = NULL;

  /* Have the backend unlock the mutex.  */
  status = __gthread_objc_mutex_unlock (mutex);

  /* Failed?  */
  if (status)
    return status;

  return 0;
}

/* Public condition mutex functions */

/* Allocate a condition.  Return the condition pointer if successful
   or NULL if the allocation failed for any reason.  */
objc_condition_t 
objc_condition_allocate (void)
{
  objc_condition_t condition;
    
  /* Allocate the condition mutex structure.  */
  if (! (condition = 
	 (objc_condition_t) objc_malloc (sizeof (struct objc_condition))))
    return NULL;

  /* Call the backend to create the condition mutex.  */
  if (__gthread_objc_condition_allocate (condition))
    {
      /* Failed!  */
      objc_free (condition);
      return NULL;
    }

  /* Success!  */
  return condition;
}

/* Deallocate a condition. Note that this includes an implicit
   condition_broadcast to insure that waiting threads have the
   opportunity to wake.  It is legal to dealloc a condition only if no
   other thread is/will be using it. Here we do NOT check for other
   threads waiting but just wake them up.  */
int
objc_condition_deallocate (objc_condition_t condition)
{
  /* Broadcast the condition.  */
  if (objc_condition_broadcast (condition))
    return -1;

  /* Call the backend to destroy.  */
  if (__gthread_objc_condition_deallocate (condition))
    return -1;

  /* Free the condition mutex structure.  */
  objc_free (condition);

  return 0;
}

/* Wait on the condition unlocking the mutex until
   objc_condition_signal () or objc_condition_broadcast () are called
   for the same condition. The given mutex *must* have the depth set
   to 1 so that it can be unlocked here, so that someone else can lock
   it and signal/broadcast the condition.  The mutex is used to lock
   access to the shared data that make up the "condition"
   predicate.  */
int
objc_condition_wait (objc_condition_t condition, objc_mutex_t mutex)
{
  objc_thread_t thread_id;

  /* Valid arguments?  */
  if (! mutex || ! condition)
    return -1;

  /* Make sure we are owner of mutex.  */
  thread_id = __gthread_objc_thread_id ();
  if (mutex->owner != thread_id)
    return -1;

  /* Cannot be locked more than once.  */
  if (mutex->depth > 1)
    return -1;

  /* Virtually unlock the mutex.  */
  mutex->depth = 0;
  mutex->owner = (objc_thread_t)NULL;

  /* Call the backend to wait.  */
  __gthread_objc_condition_wait (condition, mutex);

  /* Make ourselves owner of the mutex.  */
  mutex->owner = thread_id;
  mutex->depth = 1;

  return 0;
}

/* Wake up all threads waiting on this condition. It is recommended
   that the called would lock the same mutex as the threads in
   objc_condition_wait before changing the "condition predicate" and
   make this call and unlock it right away after this call.  */
int
objc_condition_broadcast (objc_condition_t condition)
{
  /* Valid condition mutex?  */
  if (! condition)
    return -1;

  return __gthread_objc_condition_broadcast (condition);
}

/* Wake up one thread waiting on this condition. It is recommended
   that the called would lock the same mutex as the threads in
   objc_condition_wait before changing the "condition predicate" and
   make this call and unlock it right away after this call.  */
int
objc_condition_signal (objc_condition_t condition)
{
  /* Valid condition mutex?  */
  if (! condition)
    return -1;

  return __gthread_objc_condition_signal (condition);
}

/* Make the objc thread system aware that a thread which is managed
   (started, stopped) by external code could access objc facilities
   from now on.  This is used when you are interfacing with some
   external non-objc-based environment/system - you must call
   objc_thread_add () before an alien thread makes any calls to
   Objective-C.  Do not cause the _objc_became_multi_threaded hook to
   be executed. */
void 
objc_thread_add (void)
{
  objc_mutex_lock (__objc_runtime_mutex);
  __objc_is_multi_threaded = 1;
  __objc_runtime_threads_alive++;
  objc_mutex_unlock (__objc_runtime_mutex);  
}

/* Make the objc thread system aware that a thread managed (started,
   stopped) by some external code will no longer access objc and thus
   can be forgotten by the objc thread system.  Call
   objc_thread_remove () when your alien thread is done with making
   calls to Objective-C. */
void
objc_thread_remove (void)
{
  objc_mutex_lock (__objc_runtime_mutex);
  __objc_runtime_threads_alive--;
  objc_mutex_unlock (__objc_runtime_mutex);  
}

