1 /*
2  * QEMU System Emulator
3  *
4  * Copyright (c) 2003-2008 Fabrice Bellard
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a copy
7  * of this software and associated documentation files (the "Software"), to deal
8  * in the Software without restriction, including without limitation the rights
9  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10  * copies of the Software, and to permit persons to whom the Software is
11  * furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be included in
14  * all copies or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22  * THE SOFTWARE.
23  */
24 
25 /* Modified for Unicorn Engine by Nguyen Anh Quynh, 2015 */
26 
27 #include "sysemu/sysemu.h"
28 
29 #include "hw/hw.h"
30 
31 #include "qemu/timer.h"
32 
33 #ifdef CONFIG_PPOLL
34 #include <poll.h>
35 #endif
36 
37 #ifdef CONFIG_PRCTL_PR_SET_TIMERSLACK
38 #include <sys/prctl.h>
39 #endif
40 
41 #include "uc_priv.h"
42 
43 /***********************************************************/
44 /* timers */
45 
46 typedef struct QEMUClock {
47     /* We rely on BQL to protect the timerlists */
48     QLIST_HEAD(, QEMUTimerList) timerlists;
49 
50     int64_t last;
51 
52     QEMUClockType type;
53     bool enabled;
54 } QEMUClock;
55 
56 static QEMUClock qemu_clocks[QEMU_CLOCK_MAX];
57 
58 /**
59  * qemu_clock_ptr:
60  * @type: type of clock
61  *
62  * Translate a clock type into a pointer to QEMUClock object.
63  *
64  * Returns: a pointer to the QEMUClock object
65  */
qemu_clock_ptr(QEMUClockType type)66 static inline QEMUClock *qemu_clock_ptr(QEMUClockType type)
67 {
68     return &qemu_clocks[type];
69 }
70 
71 /* return the host CPU cycle counter and handle stop/restart */
cpu_get_ticks(void)72 int64_t cpu_get_ticks(void)
73 {
74     return cpu_get_real_ticks();
75 }
76 
77 /* return the host CPU monotonic timer and handle stop/restart */
cpu_get_clock(void)78 int64_t cpu_get_clock(void)
79 {
80     return get_clock();
81 }
82 
qemu_clock_get_ns(QEMUClockType type)83 int64_t qemu_clock_get_ns(QEMUClockType type)
84 {
85     int64_t now, last;
86     QEMUClock *clock = qemu_clock_ptr(type);
87 
88     switch (type) {
89         case QEMU_CLOCK_REALTIME:
90             return get_clock();
91         default:
92         case QEMU_CLOCK_VIRTUAL:
93             return cpu_get_clock();
94         case QEMU_CLOCK_HOST:
95             now = get_clock_realtime();
96             last = clock->last;
97             clock->last = now;
98             if (now < last) {
99                 // notifier_list_notify(&clock->reset_notifiers, &now); // FIXME
100             }
101             return now;
102     }
103 }
104