/******************************************************/
/* Copyright (C) 2008 Arch Rock Corporation 2008      */
/* License Agreement: refer to LICENSE.txt            */
/*                                                    */
/******************************************************/

#ifndef _TIME_H
#define _TIME_H    1

#include <event.h>

/*! A time value that is accurate to the nearest
   microsecond but also has a range of years.  
*/
typedef struct timeval
  {
    /*! Seconds.  */
    uint32_t tv_sec;       
    /*! Microseconds.  */     
    uint32_t tv_usec;      
  }timeval_t;

/*! Interval timer value.
 */
typedef struct itimerval
  {
    /*! Value to put into `it_value' when the timer expires.  */
    struct timeval it_interval;
    /*! Time to the next timer expiration.  */
    struct timeval it_value;
  }itimerval_t;


/*! A system call to access time of day.
 *  
 *  \pre Do not call this inside the interrupt handler context.
 *  \post If successful, \em tv contains the system's time
 *        of day.
 *
 *  @param[out] tv system fills the time value structure with
 *                 system's time of the day.
 *             
 *  \return 0 if succeed or -1 if fail and errno is set appropriately.
 *  \par Errors:
 *    ENOTTIMESYNC suggests the returned time value is not synchronized.
 */
int16_t gettimeofday(struct timeval *tv);

/*! A system call to set system's time of day.
 *  
 *  \pre Do not call this inside the interrupt handler context.
 *  \post If successful, system's time of day will be set to
 *        that specified in \em tv.
 *
 *  @param[in] tv the time value structure that the system will
 *                take as time of day.
 *             
 *  \return 0 if succeed or -1 if fail and errno is set appropriately.
 *  \par Errors:
 *    EINVAL invalid argument
 */
int16_t settimeofday(const struct timeval *tv);


/*! Request a unique resource identifier that enables
 *  scheduling timers.
 *
 *  \return a non-zero resource identifiier if succeed or
 *          -1 if fail and errno is set appropriately.
 *  \par Errors:
 *     ENFILE all unique resource identifier has been used up
 */
int16_t timer();


/*! Get value of an interval timer.
 *
 *  @param[in] timerid a valid timer id return by timer()
 *  @param[out] value to get the value of the timer
 *  \return 0 if succeed or -1 if fail and errno is set appropriately.
 *  \par Errors:
 *    EINVAL if invalid parameters are passed
 */
int16_t gettitimer(int16_t timerid, itimerval_t *value);


/*! Set the value of an interval timer. Setting the value 
 *  to zero means stopping the current timer.
 *
 *  @param[in] timerid a valid timer id return by timer().
 *  @param[in] value new interval timer value
 *  @param[out] old_value if old timer interval is not zero,
 *               it will copied into \em old_value.  Pass
 *               NULL if don't care.
 *  @param[in] timer_handler the continuation callback handler
 *             that will be fired when \em value becomes zero.
 *             If NULL is passed here, the call will fail.
 *  @param[in] resource no requirement here.
 *  @param[in] context user context
 *  \return 0 if succeed or -1 if fail and errno is set appropriately.
 *  \par Errors:
 *    EBUSY if the resource with \em timerid is busy
 *  \par
 *    EINVAL if invalid parameters are passed
 *
 *  \section handler Callback Descriptions
 *  \subsection timer_handler timer_handler
 *     @param[in] event Type is SETITIMER in #EventsEnum.
 *     @param[in] cbargs return \em resource in setitimer().
 *     @param[in] context return \em context in setitimer().
 *  \return None.
 */
int16_t setitimer(int16_t timerid,
		  const itimerval_t *value,
		  itimerval_t *old_value,
		  void (*timer_handler)(event_t event,
					void *cbargs,
					void *context), 
		  void * resource,
		  void * context);

#endif // _TIME_H
