/*
 * RTLinux condvar implementation
 *
 * Written by Michael Barabanov
 * Rewritten by Victor Yodaiken after a long delay.
 * Copyright (C) Finite State Machine Labs Inc., 1999,2000
 * Released under the terms of the GPL Version 2
 *
 * StandAlone RTLinux integration 
 * written by Vicente Esteve LLoret <viesllo@inf.upv.es> 
 * 
 */

#include <rtl_conf.h>
#include <rtl_sched.h>
#include <rtl_cond.h>
#include <rtl_mutex.h>
#include <rtl_sync.h>

/* For condvar wait and signal operations the mutex should
 * be locked; otherwise the behaviour is undefined */


#if _RTL_POSIX_CONDVARS

int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex)
{
  int ret;
  rtl_irqstate_t flags;


  rtl_no_interrupts (flags);
  pthread_mutex_unlock (mutex);
  rtl_spin_lock(&cond->lock);
  ret = rtl_wait_sleep(&cond->wait, &cond->lock);
  pthread_mutex_lock (mutex);
//  pthread_testcancel();
  rtl_restore_interrupts (flags);
  return 0;
}

int pthread_cond_broadcast(pthread_cond_t *cond)
{

  rtl_irqstate_t flags;
  rtl_spin_lock_irqsave (&cond->lock, flags);
  rtl_wait_wakeup(&cond->wait);
  rtl_spin_unlock_irqrestore (&cond->lock, flags);
  return 0;
}

#if 0
int pthread_cond_timedwait(pthread_cond_t *cond,
		    pthread_mutex_t *mutex, const struct timespec *abstime)
{
  rtl_sigset_t reason;
  rtl_irqstate_t flags;
  pthread_t self = pthread_self();
  hrtime_t save_resume_time;
  hrtime_t timeout;

  if (abstime == (const struct timespec *) &self->timeval) 
  {
    timeout = self->timeval;
  } 
  else 
  {
    timeout = timespec_to_ns(abstime);
  }
  timeout = __rtl_fix_timeout_for_clock(CLOCK_REALTIME, timeout);

  rtl_no_interrupts (flags);
  pthread_mutex_unlock (mutex);

  save_resume_time = self->resume_time;
  __rtl_setup_timeout(self, timeout);

  rtl_spin_lock(&cond->lock);
  reason = rtl_wait_sleep(&cond->wait, &cond->lock);
  self->resume_time = save_resume_time;

  pthread_mutex_lock (mutex);
//  pthread_testcancel();

  rtl_restore_interrupts (flags);
  return RTL_TIMED_OUT(&reason) ? ETIMEDOUT : 0;
}
#endif

int pthread_cond_init(pthread_cond_t *cond,
		    const pthread_condattr_t *attr)
{
  rtl_wait_init(&cond->wait);
  spin_lock_init(&cond->lock);
  return 0;
}

int pthread_cond_destroy(pthread_cond_t *mutex)
{
  return 0;
}

#endif // _RTL_POSIX_CONDVARS
