Xenomai 3.3.2
Loading...
Searching...
No Matches
clockobj.h
1/*
2 * Copyright (C) 2008 Philippe Gerum <rpm@xenomai.org>.
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
17 */
18
19#ifndef _COPPERPLATE_CLOCKOBJ_H
20#define _COPPERPLATE_CLOCKOBJ_H
21
22#include <pthread.h>
23#include <xeno_config.h>
24#include <boilerplate/time.h>
25#include <boilerplate/list.h>
26#include <boilerplate/lock.h>
27#include <boilerplate/limits.h>
28
29/*
30 * The Copperplate clock shall be monotonic unless the threading
31 * library has restrictions to support this over Mercury.
32 *
33 * In the normal case, this means that ongoing delays and timeouts
34 * won't be affected when the host system date is changed. In the
35 * restricted case by contrast, ongoing delays and timeouts may be
36 * impacted by changes to the host system date.
37 *
38 * The implementation maintains a per-clock epoch value, so that
39 * different emulators can have different (virtual) system dates.
40 */
41#ifdef CONFIG_XENO_COPPERPLATE_CLOCK_RESTRICTED
42#define CLOCK_COPPERPLATE CLOCK_REALTIME
43#else
44#define CLOCK_COPPERPLATE CLOCK_MONOTONIC
45#endif
46
47struct clockobj {
48 pthread_mutex_t lock;
49 struct timespec epoch;
50 struct timespec offset;
51#ifndef CONFIG_XENO_LORES_CLOCK_DISABLED
52 unsigned int resolution;
53 unsigned int frequency;
54#endif
55};
56
57#define zero_time ((struct timespec){ .tv_sec = 0, .tv_nsec = 0 })
58
59#ifdef __cplusplus
60extern "C" {
61#endif
62
63void clockobj_set_date(struct clockobj *clkobj, ticks_t ticks);
64
65void clockobj_get_date(struct clockobj *clkobj, ticks_t *pticks);
66
67ticks_t clockobj_get_time(struct clockobj *clkobj);
68
69void clockobj_get_distance(struct clockobj *clkobj,
70 const struct itimerspec *itm,
71 struct timespec *delta);
72
73void clockobj_caltime_to_timeout(struct clockobj *clkobj, const struct tm *tm,
74 unsigned long rticks, struct timespec *ts);
75
76void clockobj_caltime_to_ticks(struct clockobj *clkobj, const struct tm *tm,
77 unsigned long rticks, ticks_t *pticks);
78
79void clockobj_ticks_to_caltime(struct clockobj *clkobj,
80 ticks_t ticks,
81 struct tm *tm,
82 unsigned long *rticks);
83
84void clockobj_convert_clocks(struct clockobj *clkobj,
85 const struct timespec *in,
86 clockid_t clk_id,
87 struct timespec *out);
88
89int clockobj_set_resolution(struct clockobj *clkobj,
90 unsigned int resolution_ns);
91
92int clockobj_init(struct clockobj *clkobj,
93 unsigned int resolution_ns);
94
95int clockobj_destroy(struct clockobj *clkobj);
96
97#ifndef CONFIG_XENO_LORES_CLOCK_DISABLED
98
99void __clockobj_ticks_to_timeout(struct clockobj *clkobj, clockid_t clk_id,
100 ticks_t ticks, struct timespec *ts);
101
102void __clockobj_ticks_to_timespec(struct clockobj *clkobj,
103 ticks_t ticks, struct timespec *ts);
104#endif /* !CONFIG_XENO_LORES_CLOCK_DISABLED */
105
106#ifdef __cplusplus
107}
108#endif
109
110#ifdef CONFIG_XENO_COBALT
111
112#include <cobalt/ticks.h>
113#include <cobalt/sys/cobalt.h>
114
115/*
116 * The Cobalt core exclusively deals with aperiodic timings, so a
117 * Cobalt _tick_ is actually a nanosecond unit. In contrast, Copperplate
118 * deals with both nanosecond units and periodic _ticks_ which duration
119 * depend on the clock resolution. Copperplate ticks are periods of the
120 * reference clockobj which Cobalt does not know about.
121 */
122
123static inline ticks_t clockobj_get_ns(void)
124{
125 /* Guaranteed to be the source of CLOCK_COPPERPLATE. */
126 return cobalt_read_ns();
127}
128
129static inline
130void clockobj_ns_to_timespec(ticks_t ns, struct timespec *ts)
131{
132 unsigned long rem;
133
134 ts->tv_sec = (time_t)cobalt_divrem_billion(ns, &rem);
135 ts->tv_nsec = (long)rem;
136}
137
138#else /* CONFIG_XENO_MERCURY */
139
140ticks_t clockobj_get_ns(void);
141
142static inline
143void clockobj_ns_to_timespec(ticks_t ns, struct timespec *ts)
144{
145 ts->tv_sec = ns / 1000000000ULL;
146 ts->tv_nsec = ns - (ts->tv_sec * 1000000000ULL);
147}
148
149#endif /* CONFIG_XENO_MERCURY */
150
151#ifdef CONFIG_XENO_LORES_CLOCK_DISABLED
152
153static inline
154void __clockobj_ticks_to_timeout(struct clockobj *clkobj,
155 clockid_t clk_id,
156 ticks_t ticks, struct timespec *ts)
157{
158 struct timespec now, delta;
159
160 __RT(clock_gettime(clk_id, &now));
161 clockobj_ns_to_timespec(ticks, &delta);
162 timespec_add(ts, &now, &delta);
163}
164
165static inline
166void __clockobj_ticks_to_timespec(struct clockobj *clkobj,
167 ticks_t ticks, struct timespec *ts)
168{
169 clockobj_ns_to_timespec(ticks, ts);
170}
171
172static inline
173void clockobj_ticks_to_timespec(struct clockobj *clkobj,
174 ticks_t ticks, struct timespec *ts)
175{
176 __clockobj_ticks_to_timespec(clkobj, ticks, ts);
177}
178
179static inline
180unsigned int clockobj_get_resolution(struct clockobj *clkobj)
181{
182 return 1;
183}
184
185static inline
186unsigned int clockobj_get_frequency(struct clockobj *clkobj)
187{
188 return 1000000000;
189}
190
191static inline sticks_t clockobj_ns_to_ticks(struct clockobj *clkobj,
192 sticks_t ns)
193{
194 return ns;
195}
196
197static inline sticks_t clockobj_ticks_to_ns(struct clockobj *clkobj,
198 sticks_t ticks)
199{
200 return ticks;
201}
202
203#else /* !CONFIG_XENO_LORES_CLOCK_DISABLED */
204
205static inline
206void clockobj_ticks_to_timespec(struct clockobj *clkobj,
207 ticks_t ticks, struct timespec *ts)
208{
209 __clockobj_ticks_to_timespec(clkobj, ticks, ts);
210}
211
212static inline
213unsigned int clockobj_get_resolution(struct clockobj *clkobj)
214{
215 return clkobj->resolution;
216}
217
218static inline
219unsigned int clockobj_get_frequency(struct clockobj *clkobj)
220{
221 return clkobj->frequency;
222}
223
224sticks_t clockobj_ns_to_ticks(struct clockobj *clkobj,
225 sticks_t ns);
226
227static inline sticks_t clockobj_ticks_to_ns(struct clockobj *clkobj,
228 sticks_t ticks)
229{
230 return ticks * clkobj->resolution;
231}
232
233#endif /* !CONFIG_XENO_LORES_CLOCK_DISABLED */
234
235static inline
236void clockobj_ticks_to_timeout(struct clockobj *clkobj,
237 ticks_t ticks, struct timespec *ts)
238{
239 __clockobj_ticks_to_timeout(clkobj, CLOCK_COPPERPLATE, ticks, ts);
240}
241
242#endif /* _COPPERPLATE_CLOCKOBJ_H */