/*
 * nasd_solaris_basic.c
 *
 * Basic system support stuff
 *
 * Author: Jim Zelenka
 */
/*
 * Copyright (c) of Carnegie Mellon University, 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 <nasd/nasd_general.h>
#include <nasd/nasd_sys.h>
#include <nasd/nasd_common.h>
#include <nasd/nasd_timer.h>

#include <sys/types.h>
#include <sys/processor.h>

static nasd_timespec_t nasd_solaris_last_time = {0,0};
static nasd_timespec_t nasd_solaris_uniq_time = {0,0};

void
nasd_gettime(
  nasd_timespec_t  *tm)
{
  struct timeval tv;

#ifdef KERNEL
  uniqtime(&tv);
#else /* KERNEL */
  gettimeofday(&tv, NULL);
#endif /* KERNEL */
  tm->ts_sec = tv.tv_sec;
  tm->ts_nsec = tv.tv_usec*1000;
  if ((tm->ts_sec == nasd_solaris_last_time.ts_sec)
    && (tm->ts_nsec == nasd_solaris_last_time.ts_nsec))
  {
    nasd_solaris_uniq_time.ts_nsec++;
    if (nasd_solaris_uniq_time.ts_nsec >= NASD_NSEC_PER_SEC) {
      nasd_solaris_uniq_time.ts_nsec -= NASD_NSEC_PER_SEC;
      nasd_solaris_uniq_time.ts_sec++;
    }
    *tm = nasd_solaris_uniq_time;
  }
  else {
    nasd_solaris_last_time = *tm;
    nasd_solaris_uniq_time = nasd_solaris_last_time;
  }
}

nasd_status_t
nasd_sys_init()
{
#ifdef i386
  nasd_get_clock_speed(&nasd_ctimer_ticks);
#endif /* i386 */
  return(NASD_SUCCESS);
}

void
nasd_sys_shutdown()
{
}

void
nasd_delay_ts(
  nasd_timespec_t  ts)
{
  struct timeval tv;
  int ret;

  tv.tv_sec = ts.ts_sec;
  tv.tv_usec = ts.ts_nsec / 1000;
  ret = select(1, NULL, NULL, NULL, &tv);
  if (ret < 0)
    NASD_PANIC();
}

#ifndef __i386__
nasd_status_t
nasd_get_clock_speed(
  nasd_uint64  *ticksp)
{
  processorid_t processor_id;
  processor_info_t info;
  int ret;

  processor_id = 0; /* close enough */
  ret = processor_info(processor_id, &info);
  if (ret)
    return(NASD_FAIL);
  *ticksp = (nasd_uint64)info.pi_clock;
  return(NASD_SUCCESS);
}
#endif /* !__i386__ */

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