/* GNU Objective C Runtime Thread Interface
   Copyright (C) 1996, 1997, 2009, 2010 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
/* The line below is needed for declarations of functions such as
   pthread_mutexattr_settype, without which gthr-posix.h may fail to
   compile within libobjc.  Unfortunately, this breaks compilation on
   Tru64 UNIX V4.0F, so disable it there.  */
#ifndef __osf__
#define _XOPEN_SOURCE 500
#endif
#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/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);  
}

