LCOV - code coverage report
Current view: top level - arch/um/os-Linux - time.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 21 37 56.8 %
Date: 2023-03-27 20:00:47 Functions: 5 7 71.4 %

          Line data    Source code
       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 <unistd.h>
      11             : #include <errno.h>
      12             : #include <signal.h>
      13             : #include <time.h>
      14             : #include <sys/time.h>
      15             : #include <kern_util.h>
      16             : #include <os.h>
      17             : #include <string.h>
      18             : 
      19             : static timer_t event_high_res_timer = 0;
      20             : 
      21             : static inline long long timespec_to_ns(const struct timespec *ts)
      22             : {
      23        9597 :         return ((long long) ts->tv_sec * UM_NSEC_PER_SEC) + ts->tv_nsec;
      24             : }
      25             : 
      26           1 : long long os_persistent_clock_emulation(void)
      27             : {
      28             :         struct timespec realtime_tp;
      29             : 
      30           1 :         clock_gettime(CLOCK_REALTIME, &realtime_tp);
      31           1 :         return timespec_to_ns(&realtime_tp);
      32             : }
      33             : 
      34             : /**
      35             :  * os_timer_create() - create an new posix (interval) timer
      36             :  */
      37           1 : int os_timer_create(void)
      38             : {
      39           1 :         timer_t *t = &event_high_res_timer;
      40             : 
      41           1 :         if (timer_create(CLOCK_MONOTONIC, NULL, t) == -1)
      42             :                 return -1;
      43             : 
      44           1 :         return 0;
      45             : }
      46             : 
      47           1 : int os_timer_set_interval(unsigned long long nsecs)
      48             : {
      49             :         struct itimerspec its;
      50             : 
      51           1 :         its.it_value.tv_sec = nsecs / UM_NSEC_PER_SEC;
      52           1 :         its.it_value.tv_nsec = nsecs % UM_NSEC_PER_SEC;
      53             : 
      54           1 :         its.it_interval.tv_sec = nsecs / UM_NSEC_PER_SEC;
      55           1 :         its.it_interval.tv_nsec = nsecs % UM_NSEC_PER_SEC;
      56             : 
      57           1 :         if (timer_settime(event_high_res_timer, 0, &its, NULL) == -1)
      58           0 :                 return -errno;
      59             : 
      60             :         return 0;
      61             : }
      62             : 
      63           0 : int os_timer_one_shot(unsigned long long nsecs)
      64             : {
      65           0 :         struct itimerspec its = {
      66           0 :                 .it_value.tv_sec = nsecs / UM_NSEC_PER_SEC,
      67           0 :                 .it_value.tv_nsec = nsecs % UM_NSEC_PER_SEC,
      68             : 
      69             :                 .it_interval.tv_sec = 0,
      70             :                 .it_interval.tv_nsec = 0, // we cheat here
      71             :         };
      72             : 
      73           0 :         timer_settime(event_high_res_timer, 0, &its, NULL);
      74           0 :         return 0;
      75             : }
      76             : 
      77             : /**
      78             :  * os_timer_disable() - disable the posix (interval) timer
      79             :  */
      80           2 : void os_timer_disable(void)
      81             : {
      82             :         struct itimerspec its;
      83             : 
      84           2 :         memset(&its, 0, sizeof(struct itimerspec));
      85           2 :         timer_settime(event_high_res_timer, 0, &its, NULL);
      86           2 : }
      87             : 
      88        9596 : long long os_nsecs(void)
      89             : {
      90             :         struct timespec ts;
      91             : 
      92        9596 :         clock_gettime(CLOCK_MONOTONIC,&ts);
      93        9596 :         return timespec_to_ns(&ts);
      94             : }
      95             : 
      96             : /**
      97             :  * os_idle_sleep() - sleep until interrupted
      98             :  */
      99           0 : void os_idle_sleep(void)
     100             : {
     101             :         struct itimerspec its;
     102             :         sigset_t set, old;
     103             : 
     104             :         /* block SIGALRM while we analyze the timer state */
     105           0 :         sigemptyset(&set);
     106           0 :         sigaddset(&set, SIGALRM);
     107           0 :         sigprocmask(SIG_BLOCK, &set, &old);
     108             : 
     109             :         /* check the timer, and if it'll fire then wait for it */
     110           0 :         timer_gettime(event_high_res_timer, &its);
     111           0 :         if (its.it_value.tv_sec || its.it_value.tv_nsec)
     112           0 :                 sigsuspend(&old);
     113             :         /* either way, restore the signal mask */
     114           0 :         sigprocmask(SIG_UNBLOCK, &set, NULL);
     115           0 : }

Generated by: LCOV version 1.14