/*
 * Copyright (c) 2001-2003 Shiman Associates Inc. All Rights Reserved.
 * 
 * Permission is hereby granted, free of charge, to any person
 * obtaining a copy of this software and associated documentation
 * files (the "Software"), to deal in the Software without
 * restriction, including without limitation the rights to use, copy,
 * modify, merge, publish, distribute, sublicense, and/or sell copies
 * of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 * 
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.
 * 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 *
 */

/***************************************************************************/
#include <sys/time.h>
#include <time.h>
#include <limits.h>
#include <sys/times.h>
#include <unistd.h>

#define NTP_UNIX_EPOCH_START 2208988800u
#define NTP_LSW_MULTIPLIER   2.32830643654E-10
#define NTP_LSW16_MULTIPLIER 1.52587890625E-5

#include "mas/mas_common.h"
#include "mas/mas_nanosleep_reality.h"
#include "mas_time_pd.h"

/***************************************************************************
 * Initialization and exit cleanup -- must be called before calling
 * other timing functions.
 * 
 */
int32
masc_init_timing_pd( void )
{
    return 0;
}


int32
masc_exit_timing_pd( void )
{
    return 0;
}

/***************************************************************************
 * masc_get_systime
 *
 * arguments:
 *    1. pointer to struct mas_ntpval
 *
 *  Fills out an NTP-style timestamp from the system clock's current time.
 *
 * returns: error
 *
 ***************************************************************************/
int32
masc_get_systime_pd(struct mas_ntpval* systime)
{
    struct timeval tv;

    if (systime == 0) return mas_error(MERR_NULLPTR);
    
    gettimeofday(&tv, NULL);

    systime->secs = tv.tv_sec;
    systime->frac = 4295 * tv.tv_usec; /* this is an approximation! */

    systime->secs += NTP_UNIX_EPOCH_START;
    
    return 0;
}

/***************************************************************************
 * masc_get_short_usec_ts
 *
 * arguments:
 *    1. pointer to 32-bit unsigned counter
 *
 *  Gets the current system time and stores it in a 32-bit wrapping
 *  counter.  This rolls over every 71.6 minutes.  You can't use it to
 *  time events longer than that. 
 *
 * returns: error
 *
 ***************************************************************************/
int32
masc_get_short_usec_ts_pd(u_int32* usec)
{
    struct timeval systemtime;

    gettimeofday(&systemtime, NULL);
    *usec = systemtime.tv_sec * 1000000 + systemtime.tv_usec;

    return 0;
}

/***************************************************************************
 * masc_nanosleep
 *
 * arguments:
 *    1. 32-bit unsigned nanoseconds
 *
 *  Puts the process or LWP to sleep for a specified number of
 *  nanoseconds.  This could have rather coarse resolution on some
 *  systems. Since it's a 32bit uint this function can't sleep for
 *  longer than 4.29 seconds (2^32 / 10^9).
 *
 * returns: error
 *
 ***************************************************************************/
int32
masc_nanosleep_pd(u_int32 nsec)
{
    usleep(nsec/1000);

    return 0;
}
