123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189 |
- #include <stddef.h>
- #include <errno.h>
- #include <signal.h>
- #include <time.h>
- #include <sys/time.h>
- #include <kern_util.h>
- #include <os.h>
- #include <string.h>
- #include <timer-internal.h>
- static timer_t event_high_res_timer = 0;
- static inline long long timeval_to_ns(const struct timeval *tv)
- {
- return ((long long) tv->tv_sec * UM_NSEC_PER_SEC) +
- tv->tv_usec * UM_NSEC_PER_USEC;
- }
- static inline long long timespec_to_ns(const struct timespec *ts)
- {
- return ((long long) ts->tv_sec * UM_NSEC_PER_SEC) +
- ts->tv_nsec;
- }
- long long os_persistent_clock_emulation (void) {
- struct timespec realtime_tp;
- clock_gettime(CLOCK_REALTIME, &realtime_tp);
- return timespec_to_ns(&realtime_tp);
- }
- int os_timer_create(void* timer) {
- timer_t* t = timer;
- if(t == NULL) {
- t = &event_high_res_timer;
- }
- if (timer_create(
- CLOCK_MONOTONIC,
- NULL,
- t) == -1) {
- return -1;
- }
- return 0;
- }
- int os_timer_set_interval(void* timer, void* i)
- {
- struct itimerspec its;
- unsigned long long nsec;
- timer_t* t = timer;
- struct itimerspec* its_in = i;
- if(t == NULL) {
- t = &event_high_res_timer;
- }
- nsec = UM_NSEC_PER_SEC / UM_HZ;
- if(its_in != NULL) {
- its.it_value.tv_sec = its_in->it_value.tv_sec;
- its.it_value.tv_nsec = its_in->it_value.tv_nsec;
- } else {
- its.it_value.tv_sec = 0;
- its.it_value.tv_nsec = nsec;
- }
- its.it_interval.tv_sec = 0;
- its.it_interval.tv_nsec = nsec;
- if(timer_settime(*t, 0, &its, NULL) == -1) {
- return -errno;
- }
- return 0;
- }
- long os_timer_remain(void* timer)
- {
- struct itimerspec its;
- timer_t* t = timer;
- if(t == NULL) {
- t = &event_high_res_timer;
- }
- if(timer_gettime(t, &its) == -1) {
- return -errno;
- }
- return its.it_value.tv_nsec;
- }
- int os_timer_one_shot(int ticks)
- {
- struct itimerspec its;
- unsigned long long nsec;
- unsigned long sec;
- nsec = (ticks + 1);
- sec = nsec / UM_NSEC_PER_SEC;
- nsec = nsec % UM_NSEC_PER_SEC;
- its.it_value.tv_sec = nsec / UM_NSEC_PER_SEC;
- its.it_value.tv_nsec = nsec;
- its.it_interval.tv_sec = 0;
- its.it_interval.tv_nsec = 0;
- timer_settime(event_high_res_timer, 0, &its, NULL);
- return 0;
- }
- long long os_timer_disable(void)
- {
- struct itimerspec its;
- memset(&its, 0, sizeof(struct itimerspec));
- timer_settime(event_high_res_timer, 0, &its, &its);
- return its.it_value.tv_sec * UM_NSEC_PER_SEC + its.it_value.tv_nsec;
- }
- long long os_vnsecs(void)
- {
- struct timespec ts;
- clock_gettime(CLOCK_PROCESS_CPUTIME_ID,&ts);
- return timespec_to_ns(&ts);
- }
- long long os_nsecs(void)
- {
- struct timespec ts;
- clock_gettime(CLOCK_MONOTONIC,&ts);
- return timespec_to_ns(&ts);
- }
- void os_idle_sleep(unsigned long long nsecs)
- {
- struct timespec ts;
- if (nsecs <= 0) {
- return;
- }
- ts = ((struct timespec) {
- .tv_sec = nsecs / UM_NSEC_PER_SEC,
- .tv_nsec = nsecs % UM_NSEC_PER_SEC
- });
-
- if (clock_nanosleep(CLOCK_MONOTONIC, 0, &ts, NULL)) {
- deliver_alarm();
- }
- }
|