/* MIPS SDE threads compatibility routines for libgcc2 and libobjc.  */
/* Compile this one with gcc.  */
/* Copyright (C) 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
   Contributed by Nigel Stephens <nigel@mips.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/>.  */

#ifndef GCC_GTHR_MIPSSDE_H
#define GCC_GTHR_MIPSSDE_H

/* MIPS SDE threading API specific definitions.
   Easy, since the interface is pretty much one-to-one.  */

#define __GTHREADS 1

#include <sdethread.h>
#include <unistd.h>

#ifdef __cplusplus
extern "C" {
#endif

typedef __sdethread_key_t __gthread_key_t;
typedef __sdethread_once_t __gthread_once_t;
typedef __sdethread_mutex_t __gthread_mutex_t;

typedef struct {
  long depth;
  __sdethread_t owner;
  __sdethread_mutex_t actual;
} __gthread_recursive_mutex_t;

#define __GTHREAD_MUTEX_INIT __SDETHREAD_MUTEX_INITIALIZER("gthr")
#define __GTHREAD_ONCE_INIT __SDETHREAD_ONCE_INIT
static inline int
__gthread_recursive_mutex_init_function(__gthread_recursive_mutex_t *__mutex);
#define __GTHREAD_RECURSIVE_MUTEX_INIT_FUNCTION __gthread_recursive_mutex_init_function

#if SUPPORTS_WEAK && GTHREAD_USE_WEAK
# define __gthrw(name) \
  static __typeof(name) __gthrw_ ## name __attribute__ ((__weakref__(#name)));
# define __gthrw_(name) __gthrw_ ## name
#else
# define __gthrw(name)
# define __gthrw_(name) name
#endif

__gthrw(__sdethread_once)
__gthrw(__sdethread_key_create)
__gthrw(__sdethread_key_delete)
__gthrw(__sdethread_getspecific)
__gthrw(__sdethread_setspecific)

__gthrw(__sdethread_self)

__gthrw(__sdethread_mutex_lock)
__gthrw(__sdethread_mutex_trylock)
__gthrw(__sdethread_mutex_unlock)

__gthrw(__sdethread_mutex_init)

__gthrw(__sdethread_threading)

#if SUPPORTS_WEAK && GTHREAD_USE_WEAK

static inline int
__gthread_active_p (void)
{
  return !!(void *)&__sdethread_threading;
}

#else /* not SUPPORTS_WEAK */

static inline int
__gthread_active_p (void)
{
  return 1;
}

#endif /* SUPPORTS_WEAK */

static inline int
__gthread_once (__gthread_once_t *__once, void (*__func) (void))
{
  if (__gthread_active_p ())
    return __gthrw_(__sdethread_once) (__once, __func);
  else
    return -1;
}

static inline int
__gthread_key_create (__gthread_key_t *__key, void (*__dtor) (void *))
{
  return __gthrw_(__sdethread_key_create) (__key, __dtor);
}

static inline int
__gthread_key_delete (__gthread_key_t __key)
{
  return __gthrw_(__sdethread_key_delete) (__key);
}

static inline void *
__gthread_getspecific (__gthread_key_t __key)
{
  return __gthrw_(__sdethread_getspecific) (__key);
}

static inline int
__gthread_setspecific (__gthread_key_t __key, const void *__ptr)
{
  return __gthrw_(__sdethread_setspecific) (__key, __ptr);
}

static inline int
__gthread_mutex_destroy (__gthread_mutex_t * UNUSED(__mutex))
{
  return 0;
}

static inline int
__gthread_mutex_lock (__gthread_mutex_t *__mutex)
{
  if (__gthread_active_p ())
    return __gthrw_(__sdethread_mutex_lock) (__mutex);
  else
    return 0;
}

static inline int
__gthread_mutex_trylock (__gthread_mutex_t *__mutex)
{
  if (__gthread_active_p ())
    return __gthrw_(__sdethread_mutex_trylock) (__mutex);
  else
    return 0;
}

static inline int
__gthread_mutex_unlock (__gthread_mutex_t *__mutex)
{
  if (__gthread_active_p ())
    return __gthrw_(__sdethread_mutex_unlock) (__mutex);
  else
    return 0;
}

static inline int
__gthread_recursive_mutex_init_function (__gthread_recursive_mutex_t *__mutex)
{
  __mutex->depth = 0;
  __mutex->owner = __gthrw_(__sdethread_self) ();
  return __gthrw_(__sdethread_mutex_init) (&__mutex->actual, NULL);
}

static inline int
__gthread_recursive_mutex_lock (__gthread_recursive_mutex_t *__mutex)
{
  if (__gthread_active_p ())
    {
      __sdethread_t __me = __gthrw_(__sdethread_self) ();

      if (__mutex->owner != __me)
	{
	  __gthrw_(__sdethread_mutex_lock) (&__mutex->actual);
	  __mutex->owner = __me;
	}

      __mutex->depth++;
    }
  return 0;
}

static inline int
__gthread_recursive_mutex_trylock (__gthread_recursive_mutex_t *__mutex)
{
  if (__gthread_active_p ())
    {
      __sdethread_t __me = __gthrw_(__sdethread_self) ();

      if (__mutex->owner != __me)
	{
	  if (__gthrw_(__sdethread_mutex_trylock) (&__mutex->actual))
	    return 1;
	  __mutex->owner = __me;
	}

      __mutex->depth++;
    }
  return 0;
}

static inline int
__gthread_recursive_mutex_unlock (__gthread_recursive_mutex_t *__mutex)
{
  if (__gthread_active_p ())
    {
      if (--__mutex->depth == 0)
	{
	   __mutex->owner = (__sdethread_t) 0;
	   __gthrw_(__sdethread_mutex_unlock) (&__mutex->actual);
	}
    }
  return 0;
}

#ifdef __cplusplus
}
#endif

#endif /* ! GCC_GTHR_MIPSSDE_H */
