/* GLIB - Library of useful routines for C programming
 * Copyright (C) 1995-1997  Peter Mattis, Spencer Kimball and Josh MacDonald
 *
 * gthread.c: posix thread system implementation
 * Copyright 1998 Sebastian Wilhelmi; University of Karlsruhe
 *
 * This library 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 of the License, or (at your option) any later version.
 *
 * This library 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 library; if not, write to the
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.
 */

/*
 * Modified by the GLib Team and others 1997-2000.  See the AUTHORS
 * file for a list of people on the GLib Team.  See the ChangeLog
 * files for a list of changes.  These files are distributed with
 * GLib at ftp://ftp.gtk.org/pub/gtk/. 
 */

/* 
 * MT safe
 */

#include <config.h>

#include <pthread.h>
#include <errno.h>
#include <stdlib.h>
#ifdef HAVE_SYS_TIME_H
# include <sys/time.h>
#endif
#ifdef HAVE_UNISTD_H
# include <unistd.h>
#endif

#ifdef HAVE_SCHED_H
#include <sched.h>
#endif

#define posix_check_err(err, name) G_STMT_START{			\
  int error = (err); 							\
  if (error)	 		 		 			\
    g_error ("file %s: line %d (%s): error '%s' during '%s'",		\
           __FILE__, __LINE__, G_GNUC_PRETTY_FUNCTION,			\
           g_strerror (error), name);					\
  }G_STMT_END

#define posix_check_cmd(cmd) posix_check_err (posix_error (cmd), #cmd)

#ifdef G_ENABLE_DEBUG
static gboolean posix_check_cmd_prio_warned = FALSE;
# define posix_check_cmd_prio(cmd) G_STMT_START{			\
    int err = posix_error (cmd);					\
    if (err == EPERM)		 		 			\
      { 	 			 				\
        if (!posix_check_cmd_prio_warned) 		 		\
          { 	 				 			\
            posix_check_cmd_prio_warned = TRUE;		 		\
            g_warning ("Priorities can only be changed " 		\
                        "(resp. increased) by root."); 			\
          }			 					\
      }			 						\
    else  		 						\
      posix_check_err (err, #cmd);					\
     }G_STMT_END
#else /* G_ENABLE_DEBUG */
# define posix_check_cmd_prio(cmd) G_STMT_START{			\
    int err = posix_error (cmd);					\
    if (err != EPERM)		 		 			\
      posix_check_err (err, #cmd);					\
     }G_STMT_END
#endif /* G_ENABLE_DEBUG */

#if defined(G_THREADS_IMPL_POSIX)
# define posix_error(what) (what)
# define mutexattr_default NULL
# define condattr_default NULL
#elif defined(G_THREADS_IMPL_DCE)
# define posix_error(what) ((what) == -1 ? errno : 0)
# define pthread_key_create(a, b) pthread_keycreate (a, b)
# define pthread_attr_init(a) pthread_attr_create (a)
# define pthread_attr_destroy(a) pthread_attr_delete (a)
# define pthread_create(a, b, c, d) pthread_create (a, *b, c, d) 
# define mutexattr_default (pthread_mutexattr_default)
# define condattr_default (pthread_condattr_default)
#else /* neither G_THREADS_IMPL_POSIX nor G_THREADS_IMPL_DCE are defined */
# error This should not happen. Contact the GLib team.
#endif

#if defined (POSIX_MIN_PRIORITY) && defined (POSIX_MAX_PRIORITY)
# define HAVE_PRIORITIES 1
static gint priority_normal_value;
# ifdef __FreeBSD__
   /* FreeBSD threads use different priority values from the POSIX_
    * defines so we just set them here. The corresponding macros
    * PTHREAD_MIN_PRIORITY and PTHREAD_MAX_PRIORITY are implied to be
    * exported by the docs, but they aren't.
    */
#  define PRIORITY_LOW_VALUE      0
#  define PRIORITY_URGENT_VALUE   31
# else /* !__FreeBSD__ */
#  define PRIORITY_LOW_VALUE      POSIX_MIN_PRIORITY
#  define PRIORITY_URGENT_VALUE   POSIX_MAX_PRIORITY
# endif /* !__FreeBSD__ */
# define PRIORITY_NORMAL_VALUE    priority_normal_value
#endif /* POSIX_MIN_PRIORITY && POSIX_MAX_PRIORITY */

static gulong g_thread_min_stack_size = 0;

#define G_MUTEX_SIZE (sizeof (pthread_mutex_t))

#if defined(_SC_THREAD_STACK_MIN) || defined (HAVE_PRIORITIES)
#define HAVE_G_THREAD_IMPL_INIT
static void 
g_thread_impl_init(void)
{
#ifdef _SC_THREAD_STACK_MIN
  g_thread_min_stack_size = MAX (sysconf (_SC_THREAD_STACK_MIN), 0);
#endif /* _SC_THREAD_STACK_MIN */
#ifdef HAVE_PRIORITIES
# ifdef G_THREADS_IMPL_POSIX
  {
    struct sched_param sched;
    int policy;
    posix_check_cmd (pthread_getschedparam (pthread_self(), &policy, &sched));
    priority_normal_value = sched.sched_priority;
  }
# else /* G_THREADS_IMPL_DCE */
  posix_check_cmd (priority_normal_value = 
		   pthread_getprio (*(pthread_t*)thread, 
				    g_thread_priority_map [priority]));
# endif
#endif /* HAVE_PRIORITIES */

}
#endif /* _SC_THREAD_STACK_MIN || HAVE_PRIORITIES */

static GMutex *
g_mutex_new_posix_impl (void)
{
  GMutex *result = (GMutex *) g_new (pthread_mutex_t, 1);
  posix_check_cmd (pthread_mutex_init ((pthread_mutex_t *) result, 
				       mutexattr_default));
  return result;
}

static void
g_mutex_free_posix_impl (GMutex * mutex)
{
  posix_check_cmd (pthread_mutex_destroy ((pthread_mutex_t *) mutex));
  g_free (mutex);
}

/* NOTE: the functions g_mutex_lock and g_mutex_unlock may not use
   functions from gmem.c and gmessages.c; */

/* pthread_mutex_lock, pthread_mutex_unlock can be taken directly, as
   signature and semantic are right, but without error check then!!!!,
   we might want to change this therefore. */

static gboolean
g_mutex_trylock_posix_impl (GMutex * mutex)
{
  int result;

  result = pthread_mutex_trylock ((pthread_mutex_t *) mutex);

#ifdef G_THREADS_IMPL_POSIX
  if (result == EBUSY)
    return FALSE;
#else /* G_THREADS_IMPL_DCE */
  if (result == 0)
    return FALSE;
#endif

  posix_check_err (posix_error (result), "pthread_mutex_trylock");
  return TRUE;
}

static GCond *
g_cond_new_posix_impl (void)
{
  GCond *result = (GCond *) g_new (pthread_cond_t, 1);
  posix_check_cmd (pthread_cond_init ((pthread_cond_t *) result, 
				      condattr_default));
  return result;
}

/* pthread_cond_signal, pthread_cond_broadcast and pthread_cond_wait
   can be taken directly, as signature and semantic are right, but
   without error check then!!!!, we might want to change this
   therfore. */

#define G_NSEC_PER_SEC 1000000000

static gboolean
g_cond_timed_wait_posix_impl (GCond * cond,
			      GMutex * entered_mutex,
			      GTimeVal * abs_time)
{
  int result;
  struct timespec end_time;
  gboolean timed_out;

  g_return_val_if_fail (cond != NULL, FALSE);
  g_return_val_if_fail (entered_mutex != NULL, FALSE);

  if (!abs_time)
    {
      g_cond_wait (cond, entered_mutex);
      return TRUE;
    }

  end_time.tv_sec = abs_time->tv_sec;
  end_time.tv_nsec = abs_time->tv_usec * (G_NSEC_PER_SEC / G_USEC_PER_SEC);

  g_return_val_if_fail (end_time.tv_nsec < G_NSEC_PER_SEC, TRUE);

  result = pthread_cond_timedwait ((pthread_cond_t *) cond,
				   (pthread_mutex_t *) entered_mutex,
				   &end_time);

#ifdef G_THREADS_IMPL_POSIX
  timed_out = (result == ETIMEDOUT);
#else /* G_THREADS_IMPL_DCE */
  timed_out = (result == -1) && (errno == EAGAIN);
#endif

  if (!timed_out)
    posix_check_err (posix_error (result), "pthread_cond_timedwait");
  return !timed_out;
}

static void
g_cond_free_posix_impl (GCond * cond)
{
  posix_check_cmd (pthread_cond_destroy ((pthread_cond_t *) cond));
  g_free (cond);
}

static GPrivate *
g_private_new_posix_impl (GDestroyNotify destructor)
{
  GPrivate *result = (GPrivate *) g_new (pthread_key_t, 1);
  posix_check_cmd (pthread_key_create ((pthread_key_t *) result, destructor));
  return result;
}

/* NOTE: the functions g_private_get and g_private_set may not use
   functions from gmem.c and gmessages.c */

static void
g_private_set_posix_impl (GPrivate * private_key, gpointer value)
{
  if (!private_key)
    return;
  pthread_setspecific (*(pthread_key_t *) private_key, value);
}

static gpointer
g_private_get_posix_impl (GPrivate * private_key)
{
  if (!private_key)
    return NULL;
#ifdef G_THREADS_IMPL_POSIX
  return pthread_getspecific (*(pthread_key_t *) private_key);
#else /* G_THREADS_IMPL_DCE */
  {
    void* data;
    posix_check_cmd (pthread_getspecific (*(pthread_key_t *) private_key, 
					  &data));
    return data;
  }
#endif
}

static void
g_thread_create_posix_impl (GThreadFunc thread_func, 
			    gpointer arg, 
			    gulong stack_size,
			    gboolean joinable,
			    gboolean bound,
			    GThreadPriority priority,
			    gpointer thread,
			    GError **error)
{
  pthread_attr_t attr;
  gint ret;

  g_return_if_fail (thread_func);
  g_return_if_fail (priority >= G_THREAD_PRIORITY_LOW);
  g_return_if_fail (priority <= G_THREAD_PRIORITY_URGENT);

  posix_check_cmd (pthread_attr_init (&attr));
  
#ifdef HAVE_PTHREAD_ATTR_SETSTACKSIZE
  if (stack_size)
    {
      stack_size = MAX (g_thread_min_stack_size, stack_size);
      posix_check_cmd (pthread_attr_setstacksize (&attr, stack_size));
    }
#endif /* HAVE_PTHREAD_ATTR_SETSTACKSIZE */

#ifdef PTHREAD_SCOPE_SYSTEM
  if (bound)
    /* No error check here, because some systems can't do it and we
     * simply don't want threads to fail because of that. */
    pthread_attr_setscope (&attr, PTHREAD_SCOPE_SYSTEM);
#endif /* PTHREAD_SCOPE_SYSTEM */

#ifdef G_THREADS_IMPL_POSIX
  posix_check_cmd (pthread_attr_setdetachstate (&attr,
          joinable ? PTHREAD_CREATE_JOINABLE : PTHREAD_CREATE_DETACHED));
#endif /* G_THREADS_IMPL_POSIX */
  
#ifdef HAVE_PRIORITIES
# ifdef G_THREADS_IMPL_POSIX
  {
    struct sched_param sched;
    posix_check_cmd (pthread_attr_getschedparam (&attr, &sched));
    sched.sched_priority = g_thread_priority_map [priority];
    posix_check_cmd_prio (pthread_attr_setschedparam (&attr, &sched));
  }
# else /* G_THREADS_IMPL_DCE */
  posix_check_cmd_prio 
    (pthread_attr_setprio (&attr, g_thread_priority_map [priority]));
# endif /* G_THREADS_IMPL_DCE */
#endif /* HAVE_PRIORITIES */
  ret = posix_error (pthread_create (thread, &attr, 
				     (void* (*)(void*))thread_func, arg));

  posix_check_cmd (pthread_attr_destroy (&attr));

  if (ret == EAGAIN)
    {
      g_set_error (error, G_THREAD_ERROR, G_THREAD_ERROR_AGAIN, 
		   "Error creating thread: %s", g_strerror (ret));
      return;
    }

  posix_check_err (ret, "pthread_create");

#ifdef G_THREADS_IMPL_DCE
  if (!joinable)
    posix_check_cmd (pthread_detach (thread));
#endif /* G_THREADS_IMPL_DCE */
}

static void 
g_thread_yield_posix_impl (void)
{
  POSIX_YIELD_FUNC;
}

static void
g_thread_join_posix_impl (gpointer thread)
{     
  gpointer ignore;
  posix_check_cmd (pthread_join (*(pthread_t*)thread, &ignore));
}

static void 
g_thread_exit_posix_impl (void) 
{
  pthread_exit (NULL);
}

static void
g_thread_set_priority_posix_impl (gpointer thread, GThreadPriority priority)
{
  g_return_if_fail (priority >= G_THREAD_PRIORITY_LOW);
  g_return_if_fail (priority <= G_THREAD_PRIORITY_URGENT);
#ifdef HAVE_PRIORITIES
# ifdef G_THREADS_IMPL_POSIX
  {
    struct sched_param sched;
    int policy;
    posix_check_cmd (pthread_getschedparam (*(pthread_t*)thread, &policy, 
					    &sched));
    sched.sched_priority = g_thread_priority_map [priority];
    posix_check_cmd_prio (pthread_setschedparam (*(pthread_t*)thread, policy, 
						 &sched));
  }
# else /* G_THREADS_IMPL_DCE */
  posix_check_cmd_prio (pthread_setprio (*(pthread_t*)thread, 
					 g_thread_priority_map [priority]));
# endif
#endif /* HAVE_PRIORITIES */
}

static void
g_thread_self_posix_impl (gpointer thread)
{
  *(pthread_t*)thread = pthread_self();
}

static gboolean
g_thread_equal_posix_impl (gpointer thread1, gpointer thread2)
{
  return (pthread_equal (*(pthread_t*)thread1, *(pthread_t*)thread2) != 0);
}

static GThreadFunctions g_thread_functions_for_glib_use_default =
{
  g_mutex_new_posix_impl,
  (void (*)(GMutex *)) pthread_mutex_lock,
  g_mutex_trylock_posix_impl,
  (void (*)(GMutex *)) pthread_mutex_unlock,
  g_mutex_free_posix_impl,
  g_cond_new_posix_impl,
  (void (*)(GCond *)) pthread_cond_signal,
  (void (*)(GCond *)) pthread_cond_broadcast,
  (void (*)(GCond *, GMutex *)) pthread_cond_wait,
  g_cond_timed_wait_posix_impl,
  g_cond_free_posix_impl,
  g_private_new_posix_impl,
  g_private_get_posix_impl,
  g_private_set_posix_impl,
  g_thread_create_posix_impl,
  g_thread_yield_posix_impl,
  g_thread_join_posix_impl,
  g_thread_exit_posix_impl,
  g_thread_set_priority_posix_impl,
  g_thread_self_posix_impl,
  g_thread_equal_posix_impl
};
