root/arch/um/os-Linux/time.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. timeval_to_ns
  2. timespec_to_ns
  3. os_persistent_clock_emulation
  4. os_timer_create
  5. os_timer_set_interval
  6. os_timer_one_shot
  7. os_timer_disable
  8. os_nsecs
  9. os_idle_sleep

   1 // SPDX-License-Identifier: GPL-2.0
   2 /*
   3  * Copyright (C) 2015 Anton Ivanov (aivanov@{brocade.com,kot-begemot.co.uk})
   4  * Copyright (C) 2015 Thomas Meyer (thomas@m3y3r.de)
   5  * Copyright (C) 2012-2014 Cisco Systems
   6  * Copyright (C) 2000 - 2007 Jeff Dike (jdike{addtoit,linux.intel}.com)
   7  */
   8 
   9 #include <stddef.h>
  10 #include <errno.h>
  11 #include <signal.h>
  12 #include <time.h>
  13 #include <sys/time.h>
  14 #include <kern_util.h>
  15 #include <os.h>
  16 #include <string.h>
  17 #include <timer-internal.h>
  18 
  19 static timer_t event_high_res_timer = 0;
  20 
  21 static inline long long timeval_to_ns(const struct timeval *tv)
  22 {
  23         return ((long long) tv->tv_sec * UM_NSEC_PER_SEC) +
  24                 tv->tv_usec * UM_NSEC_PER_USEC;
  25 }
  26 
  27 static inline long long timespec_to_ns(const struct timespec *ts)
  28 {
  29         return ((long long) ts->tv_sec * UM_NSEC_PER_SEC) + ts->tv_nsec;
  30 }
  31 
  32 long long os_persistent_clock_emulation(void)
  33 {
  34         struct timespec realtime_tp;
  35 
  36         clock_gettime(CLOCK_REALTIME, &realtime_tp);
  37         return timespec_to_ns(&realtime_tp);
  38 }
  39 
  40 /**
  41  * os_timer_create() - create an new posix (interval) timer
  42  */
  43 int os_timer_create(void)
  44 {
  45         timer_t *t = &event_high_res_timer;
  46 
  47         if (timer_create(CLOCK_MONOTONIC, NULL, t) == -1)
  48                 return -1;
  49 
  50         return 0;
  51 }
  52 
  53 int os_timer_set_interval(unsigned long long nsecs)
  54 {
  55         struct itimerspec its;
  56 
  57         its.it_value.tv_sec = nsecs / UM_NSEC_PER_SEC;
  58         its.it_value.tv_nsec = nsecs % UM_NSEC_PER_SEC;
  59 
  60         its.it_interval.tv_sec = nsecs / UM_NSEC_PER_SEC;
  61         its.it_interval.tv_nsec = nsecs % UM_NSEC_PER_SEC;
  62 
  63         if (timer_settime(event_high_res_timer, 0, &its, NULL) == -1)
  64                 return -errno;
  65 
  66         return 0;
  67 }
  68 
  69 int os_timer_one_shot(unsigned long long nsecs)
  70 {
  71         struct itimerspec its = {
  72                 .it_value.tv_sec = nsecs / UM_NSEC_PER_SEC,
  73                 .it_value.tv_nsec = nsecs % UM_NSEC_PER_SEC,
  74 
  75                 .it_interval.tv_sec = 0,
  76                 .it_interval.tv_nsec = 0, // we cheat here
  77         };
  78 
  79         timer_settime(event_high_res_timer, 0, &its, NULL);
  80         return 0;
  81 }
  82 
  83 /**
  84  * os_timer_disable() - disable the posix (interval) timer
  85  */
  86 void os_timer_disable(void)
  87 {
  88         struct itimerspec its;
  89 
  90         memset(&its, 0, sizeof(struct itimerspec));
  91         timer_settime(event_high_res_timer, 0, &its, NULL);
  92 }
  93 
  94 long long os_nsecs(void)
  95 {
  96         struct timespec ts;
  97 
  98         clock_gettime(CLOCK_MONOTONIC,&ts);
  99         return timespec_to_ns(&ts);
 100 }
 101 
 102 /**
 103  * os_idle_sleep() - sleep for a given time of nsecs
 104  * @nsecs: nanoseconds to sleep
 105  */
 106 void os_idle_sleep(unsigned long long nsecs)
 107 {
 108         struct timespec ts = {
 109                 .tv_sec  = nsecs / UM_NSEC_PER_SEC,
 110                 .tv_nsec = nsecs % UM_NSEC_PER_SEC
 111         };
 112 
 113         /*
 114          * Relay the signal if clock_nanosleep is interrupted.
 115          */
 116         if (clock_nanosleep(CLOCK_MONOTONIC, 0, &ts, NULL))
 117                 deliver_alarm();
 118 }

/* [<][>][^][v][top][bottom][index][help] */