/* ========================================================================== */
/*! \file
 * \brief Timing related functions
 *
 * Copyright (c) 2012-2020 by the developers. See the LICENSE file for details.
 *
 * If nothing else is specified, function return zero to indicate success
 * and a negative value to indicate an error.
 */


/* ========================================================================== */
/* Include headers */

#include "posix.h"  /* Include this first because of feature test macros */

#include <string.h>

#include "main.h"
#include "timing.h"


/* ========================================================================== */
/*! \defgroup TIMING TIME: Timing related convenience functions
 *
 * The functions are wrappers around POSIX \c nanosleep() .
 */
/*! @{ */


/* ========================================================================== */
/* Constants */

/*! \brief Message prefix for TIMING module */
#define MAIN_ERR_PREFIX  "TIME: "


/* ========================================================================== */
/*! \brief Milisecond delay
 *
 * \param[in] msecs  Number of miliseconds for delay
 *
 * \return
 * - 0 on success
 * - Negative value on error
 */

int  time_msleep(unsigned int  msecs)
{
   int  res;
   struct_posix_timespec  rqtp;
   struct_posix_timespec  rmtp;

   /* Prepare requested value as the remaining interval */
   rmtp.tv_sec = 0;
   if(1000U < msecs)  { rmtp.tv_sec = (posix_time_t) (msecs / 1000U); }
   rmtp.tv_nsec = (long int) (msecs % 1000U) * 1000000L;

   /* Execute delay */
   do
   {
      memcpy((void*) &rqtp, (void*) &rmtp, sizeof(struct_posix_timespec));
      res = posix_nanosleep(&rqtp, &rmtp);
   }
   while(-1 == res && POSIX_EINTR == posix_errno);
   if(-1 == res)
   {
      if(POSIX_ENOSYS == posix_errno)
      {
         PRINT_ERROR("nanosleep() not supported by operating system");
      }
      else  { PRINT_ERROR("msleep() failed"); }
   }

   return(res);
}


/*! @} */

/* EOF */
