/*
 * nasd_vx_threads.h
 *
 * vxworks variant of threads portability layer
 *
 * Authors: Marc Unangst, Jim Zelenka
 */
/*
 * Copyright (c) of Carnegie Mellon University, 1997,1998,1999.
 *
 * Permission to reproduce, use, and prepare derivative works of
 * this software for internal use is granted provided the copyright
 * and "No Warranty" statements are included with all reproductions
 * and derivative works. This software may also be redistributed
 * without charge provided that the copyright and "No Warranty"
 * statements are included in all redistributions.
 *
 * NO WARRANTY. THIS SOFTWARE IS FURNISHED ON AN "AS IS" BASIS.
 * CARNEGIE MELLON UNIVERSITY MAKES NO WARRANTIES OF ANY KIND, EITHER
 * EXPRESSED OR IMPLIED AS TO THE MATTER INCLUDING, BUT NOT LIMITED
 * TO: WARRANTY OF FITNESS FOR PURPOSE OR MERCHANTABILITY, EXCLUSIVITY
 * OF RESULTS OR RESULTS OBTAINED FROM USE OF THIS SOFTWARE. CARNEGIE
 * MELLON UNIVERSITY DOES NOT MAKE ANY WARRANTY OF ANY KIND WITH RESPECT
 * TO FREEDOM FROM PATENT, TRADEMARK, OR COPYRIGHT INFRINGEMENT.
 */


#ifndef _NASD__NASD_VX_THREADS_H_
#define _NASD__NASD_VX_THREADS_H_

#include <nasd/nasd_options.h>
#include <vxWorks.h>
#include <taskLib.h>
#include <semLib.h>

/* rephrase mutexes & condition variables in terms of binary semaphores */
#define WIND_MUTEX_CREATE()		semBCreate(SEM_Q_PRIORITY, SEM_FULL)
#define WIND_MUTEX_DESTROY(_m_)		semDelete(_m_)
#define WIND_MUTEX_LOCK(_m_)		semTake(_m_, WAIT_FOREVER)
#define WIND_MUTEX_TRYLOCK(_m_)		semTake(_m_, NO_WAIT)
#define WIND_MUTEX_UNLOCK(_m_)		semGive(_m_)

#define WIND_COND_CREATE()		semBCreate(SEM_Q_PRIORITY, SEM_EMPTY);
#define WIND_COND_DESTROY(_c_)		semDelete(_c_)
#define WIND_COND_SIGNAL(_c_)		semGive(_c_)
/* XXX-mju doublecheck broadcast & wait for correctness */
#define WIND_COND_BROADCAST(_c)		semGive(_c_),semFlush(_c_)
#define WIND_COND_WAIT(_c_, _m_)	semGive(_m_),semTake(_c_, WAIT_FOREVER),semTake(_m_, WAIT_FOREVER)

#define NASD_SYS_DECLARE_MUTEX(_m_)                SEM_ID _m_;
#define NASD_SYS_DECLARE_STATIC_MUTEX(_m_)  static SEM_ID _m_;
#define NASD_SYS_DECLARE_EXTERN_MUTEX(_m_)  extern SEM_ID _m_;
#define NASD_SYS_DECLARE_COND(_c_)                 SEM_ID _c_;
#define NASD_SYS_DECLARE_STATIC_COND(_c_)   static SEM_ID _c_;
#define NASD_SYS_DECLARE_EXTERN_COND(_c_)   extern SEM_ID _c_;

int nasd_sys_mutex_init(SEM_ID *m);
int nasd_sys_mutex_destroy(SEM_ID *m);
int nasd_sys_cond_init(SEM_ID *c);
int nasd_sys_cond_destroy(SEM_ID *c);

#define NASD_SYS_LOCK_MUTEX(_m_)     WIND_MUTEX_LOCK(_m_)
#define NASD_SYS_TRY_LOCK_MUTEX(_m_) WIND_MUTEX_TRYLOCK(_m_)
#define NASD_SYS_UNLOCK_MUTEX(_m_)   WIND_MUTEX_UNLOCK(_m_)

#define NASD_SYS_WAIT_COND(_c_,_m_)  WIND_COND_WAIT(_c_, _m_)
#define NASD_SYS_SIGNAL_COND(_c_)    WIND_COND_SIGNAL(_c_)
#define NASD_SYS_BROADCAST_COND(_c_) WIND_COND_BROADCAST(_c_)

struct nasd_threadattr_s {
  char *name;
  int priority;
  int options;
  int stackSize;
};

typedef int nasd_thread_t;
typedef int nasd_threadarg_t; /* the argument to a thread function */
typedef struct nasd_threadattr_s nasd_threadattr_t; /* a thread creation attribute structure */

#define NASD_EXIT_THREAD(_status_)                  exit(_status_)

#define NASD_DELAY_THREAD(_secs_,_nsecs_) { \
  struct timespec _interval; \
  _interval.tv_sec = (_secs_); \
  _interval.tv_nsec = (_msecs_)*1000000; \
  nanosleep(&_interval, NULL); \
}

#define NASD_WIND_DEF_PRIORITY		100
#define NASD_WIND_DEF_OPTIONS		0
#define NASD_WIND_DEF_STACKSIZE		20000

/* XXX only works if already at toplevel */
#define NASD_THREAD_KILL_SELF() return

#endif /* !_NASD__NASD_VX_THREADS_H_ */

/* Local Variables:  */
/* indent-tabs-mode: nil */
/* tab-width: 2 */
/* End: */
