/*
 * nasd_vx_basic.c
 *
 * Basic system support stuff
 *
 * Authors: Marc Unangst, Jim Zelenka
 */
/*
 * Copyright (c) of Carnegie Mellon University, 1996,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.
 */


#include <nasd/nasd_options.h>
#include <nasd/nasd_types.h>
#include <nasd/nasd_mem.h>
#include <nasd/nasd_threadstuff.h>
#include <sys/time.h>

nasd_status_t
nasd_sys_init()
{
  return(NASD_SUCCESS);
}

static nasd_timespec_t nasd_vx_last_time = {0,0};
static nasd_timespec_t nasd_vx_uniq_time = {0,0};

void
nasd_gettime(
  nasd_timespec_t  *tm)
{
  struct timespec ts;
  int ret;

  ret = clock_gettime(CLOCK_REALTIME, &ts);
  if (ret)
    NASD_PANIC();
  tm->ts_sec = ts.tv_sec;
  tm->ts_nsec = ts.tv_nsec;
  if ((tm->ts_sec == nasd_vx_last_time.ts_sec)
    && (tm->ts_nsec == nasd_vx_last_time.ts_nsec))
  {
    nasd_vx_uniq_time.ts_nsec++;
    if (nasd_vx_uniq_time.ts_nsec >= NASD_NSEC_PER_SEC) {
      nasd_vx_uniq_time.ts_nsec -= NASD_NSEC_PER_SEC;
      nasd_vx_uniq_time.ts_sec++;
    }
    *tm = nasd_vx_uniq_time;
  }
  else {
    nasd_vx_last_time = *tm;
    nasd_vx_uniq_time = nasd_vx_last_time;
  }
}

nasd_status_t
nasd_mutex_init(SEM_ID *m)
{
  *m = WIND_MUTEX_CREATE();
  if(*m)
    return NASD_SUCCESS;
  return NASD_FAIL;
}


nasd_status_t
nasd_mutex_destroy(SEM_ID *m)
{
  int rc;

  rc = WIND_MUTEX_DESTROY(*m);
  if(rc)
    return NASD_FAIL;
  return NASD_SUCCESS;
}


nasd_status_t
nasd_cond_init(SEM_ID *c)
{
  *c = WIND_COND_CREATE();
  if(*c)
    return NASD_SUCCESS;
  return NASD_FAIL;
}


nasd_status_t
nasd_cond_destroy(SEM_ID *c)
{
  int rc;

  rc = WIND_COND_DESTROY(*c);
  if(rc)
    return NASD_FAIL;
  return NASD_SUCCESS;
}

nasd_status_t
nasd_sys_threadattr_create(
  nasd_sys_threadattr_t  *attrp)
{
  attrp->name = NULL;
  attrp->priority = NASD_WIND_DEF_PRIORITY;
  attrp->options = NASD_WIND_DEF_OPTIONS;
  attrp->stackSize = NASD_WIND_DEF_STACKSIZE;

  return(NASD_SUCCESS);
}

nasd_status_t
nasd_sys_threadattr_destroy(
  nasd_sys_threadattr_t  *attrp)
{
  return(NASD_SUCCESS);
}

nasd_status_t
nasd_sys_threadattr_setstacksize(
  nasd_sys_threadattr_t  *attrp,
  int                     size)
{
  attrp->stackSize = size;
  return(NASD_SUCCESS);
}

nasd_status_t
nasd_sys_threadattr_getstacksize(
  nasd_sys_threadattr_t  *attrp,
  int                    *sizep)
{
  *sizep = attrp->stackSize;
  return(NASD_SUCCESS);
}

nasd_status_t
nasd_sys_thread_create_attr(
  nasd_sys_thread_t      *threadp,
  nasd_sys_threadattr_t  *attrp,
  nasd_threadfunc_t       func,
  nasd_threadarg_t        arg)
{
  *threadp = taskSpawn(attrp->name, attrp->priority, attrp->options,
    attrp->stackSize, func, arg,
    0, 0, 0, 0, 0, 0, 0, 0, 0);
  if (*threadp == NULL)
    return(NASD_FAIL);
  return(NASD_SUCCESS);
}

nasd_status_t
nasd_sys_thread_create(
  nasd_sys_thread_t  *threadp,
  nasd_threadfunc_t   func,
  nasd_threadarg_t    arg)
{
  *threadp = taskSpawn("anonymous", NASD_WIND_DEF_PRIORITY,
    NASD_WIND_DEF_OPTIONS, NASD_WIND_DEF_STACKSIZE,
    func, arg,
    0, 0, 0, 0, 0, 0, 0, 0, 0);
  if (*threadp == NULL)
    return(NASD_FAIL);
  return(NASD_SUCCESS);
}

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