/* GNU Objective C Runtime Thread Interface
   Copyright (C) 1996-2021 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 tread.  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);  
}

