00001
00023 #ifndef _XENO_NUCLEUS_TIMEBASE_H
00024 #define _XENO_NUCLEUS_TIMEBASE_H
00025
00029 #include <nucleus/queue.h>
00030
00031 #if defined(__KERNEL__) || defined(__XENO_SIM__)
00032
00033 #ifdef CONFIG_PROC_FS
00034 #include <linux/proc_fs.h>
00035 #endif
00036
00037 struct xntimer;
00038
00039 typedef struct xntbops {
00040
00041 int (*start_timer)(struct xntimer *timer,
00042 xnticks_t value,
00043 xnticks_t interval,
00044 xntmode_t mode);
00045 void (*stop_timer)(struct xntimer *timer);
00046 xnticks_t (*get_timer_date)(struct xntimer *timer);
00047 xnticks_t (*get_timer_timeout)(struct xntimer *timer);
00048 xnticks_t (*get_timer_interval)(struct xntimer *timer);
00049 xnticks_t (*get_timer_raw_expiry)(struct xntimer *timer);
00050 void (*move_timer)(struct xntimer *timer);
00051
00052 } xntbops_t;
00053
00054 #define XNTBRUN 0x00000001
00055 #define XNTBSET 0x00000002
00056 #define XNTBLCK 0x00000004
00057 #define XNTBISO 0x00000008
00058
00059 typedef struct xntbase {
00060
00061 struct xntbops *ops;
00063 xnticks_t jiffies;
00065 void (*hook)(void);
00067 xnticks_t wallclock_offset;
00069 u_long tickvalue;
00071 u_long ticks2sec;
00073 u_long status;
00075 const char *name;
00076
00077 xnholder_t link;
00078
00079 #define link2tbase(ln) container_of(ln, xntbase_t, link)
00080
00081 #ifdef CONFIG_XENO_OPT_STATS
00082 xnqueue_t timerq;
00083
00084 int timerq_rev;
00085 #endif
00086
00087 } xntbase_t;
00088
00089 #ifdef __cplusplus
00090 extern "C" {
00091 #endif
00092
00093 extern xntbase_t nktbase;
00094
00095 extern xnqueue_t nktimebaseq;
00096
00097 static inline u_long xntbase_get_ticks2sec(xntbase_t *base)
00098 {
00099 return base->ticks2sec;
00100 }
00101
00102 static inline u_long xntbase_get_tickval(xntbase_t *base)
00103 {
00104
00105 return base->tickvalue;
00106 }
00107
00108 static inline xnticks_t xntbase_get_wallclock_offset(xntbase_t *base)
00109 {
00110 return base->wallclock_offset;
00111 }
00112
00113 static inline void xntbase_set_hook(xntbase_t *base, void (*hook)(void))
00114 {
00115 base->hook = hook;
00116 }
00117
00118 static inline int xntbase_timeset_p(xntbase_t *base)
00119 {
00120 return !!testbits(base->status, XNTBSET);
00121 }
00122
00123 static inline int xntbase_enabled_p(xntbase_t *base)
00124 {
00125 return !!testbits(base->status, XNTBRUN);
00126 }
00127
00128 static inline int xntbase_isolated_p(xntbase_t *base)
00129 {
00130 return !!testbits(base->status, XNTBISO);
00131 }
00132
00133 static inline const char *xntbase_name(xntbase_t *base)
00134 {
00135 return base->name;
00136 }
00137
00138 #ifdef CONFIG_XENO_OPT_TIMING_PERIODIC
00139
00140 static inline xntime_t xntbase_ticks2ns(xntbase_t *base, xnticks_t ticks)
00141 {
00142
00143 return ticks * xntbase_get_tickval(base);
00144 }
00145
00146 static inline xnticks_t xntbase_ns2ticks(xntbase_t *base, xntime_t t)
00147 {
00148 return xnarch_ulldiv(t, xntbase_get_tickval(base), NULL);
00149 }
00150
00151 xnticks_t xntbase_ns2ticks_ceil(xntbase_t *base, xntime_t t);
00152
00153 static inline int xntbase_master_p(xntbase_t *base)
00154 {
00155 return base == &nktbase;
00156 }
00157
00183 static inline xnticks_t xntbase_convert(xntbase_t *srcbase, xnticks_t ticks, xntbase_t *dstbase)
00184 {
00185
00186
00187
00188
00189 if (dstbase->tickvalue == srcbase->tickvalue)
00190 return ticks;
00191
00192 if (likely(xntbase_master_p(dstbase)))
00193 return xntbase_ticks2ns(srcbase, ticks);
00194
00195 if (xntbase_master_p(srcbase))
00196 return xntbase_ns2ticks(dstbase, ticks);
00197
00198
00199
00200 return xntbase_ns2ticks(dstbase, xntbase_ticks2ns(srcbase, ticks));
00201 }
00202
00203 static inline int xntbase_periodic_p(xntbase_t *base)
00204 {
00205 return !xntbase_master_p(base);
00206 }
00207
00208 static inline xnticks_t xntbase_get_jiffies(xntbase_t *base)
00209 {
00210 return xntbase_periodic_p(base) ? base->jiffies : xnarch_get_cpu_time();
00211 }
00212
00213 static inline xnticks_t xntbase_get_rawclock(xntbase_t *base)
00214 {
00215 return xntbase_periodic_p(base) ? base->jiffies : xnarch_get_cpu_tsc();
00216 }
00217
00218 int xntbase_alloc(const char *name,
00219 u_long period,
00220 u_long flags,
00221 xntbase_t **basep);
00222
00223 void xntbase_free(xntbase_t *base);
00224
00225 int xntbase_update(xntbase_t *base,
00226 u_long period);
00227
00228 int xntbase_switch(const char *name,
00229 u_long period,
00230 xntbase_t **basep);
00231
00232 void xntbase_start(xntbase_t *base);
00233
00234 void xntbase_stop(xntbase_t *base);
00235
00236 void xntbase_tick(xntbase_t *base);
00237
00238 #else
00239
00240 void xntimer_tick_aperiodic(void);
00241
00242 static inline xntime_t xntbase_ticks2ns(xntbase_t *base, xnticks_t ticks)
00243 {
00244 return ticks;
00245 }
00246
00247 static inline xnticks_t xntbase_ns2ticks(xntbase_t *base, xntime_t t)
00248 {
00249 return t;
00250 }
00251
00252 static inline xnticks_t xntbase_ns2ticks_ceil(xntbase_t *base, xntime_t t)
00253 {
00254 return t;
00255 }
00256
00257 static inline int xntbase_master_p(xntbase_t *base)
00258 {
00259 return 1;
00260 }
00261
00262 static inline xnticks_t xntbase_convert(xntbase_t *srcbase, xnticks_t ticks, xntbase_t *dstbase)
00263 {
00264 return ticks;
00265 }
00266
00267 static inline int xntbase_periodic_p(xntbase_t *base)
00268 {
00269 return 0;
00270 }
00271
00272 static inline xnticks_t xntbase_get_jiffies(xntbase_t *base)
00273 {
00274 return xnarch_get_cpu_time();
00275 }
00276
00277 static inline xnticks_t xntbase_get_rawclock(xntbase_t *base)
00278 {
00279 return xnarch_get_cpu_tsc();
00280 }
00281
00282 static inline int xntbase_alloc(const char *name, u_long period, u_long flags, xntbase_t **basep)
00283 {
00284 *basep = &nktbase;
00285 return 0;
00286 }
00287
00288 static inline void xntbase_free(xntbase_t *base)
00289 {
00290 }
00291
00292 static inline int xntbase_update(xntbase_t *base, u_long period)
00293 {
00294 return 0;
00295 }
00296
00297 static inline int xntbase_switch(const char *name, u_long period, xntbase_t **basep)
00298 {
00299 return period == XN_APERIODIC_TICK ? 0 : -ENODEV;
00300 }
00301
00302 static inline void xntbase_start(xntbase_t *base)
00303 {
00304 }
00305
00306 static inline void xntbase_stop(xntbase_t *base)
00307 {
00308 }
00309
00310 static inline void xntbase_tick(xntbase_t *base)
00311 {
00312 xntimer_tick_aperiodic();
00313 }
00314
00315 #endif
00316
00344 static inline xnticks_t xntbase_get_time(xntbase_t *base)
00345 {
00346
00347
00348 return xntbase_get_jiffies(base) + base->wallclock_offset;
00349 }
00350
00351 void xntbase_adjust_time(xntbase_t *base, xnsticks_t delta);
00352
00353 #ifdef __cplusplus
00354 }
00355 #endif
00356
00357 #define xntbase_mount() \
00358 do { \
00359 inith(&nktbase.link); \
00360 appendq(&nktimebaseq, &nktbase.link); \
00361 xnpod_declare_tbase_proc(&nktbase); \
00362 } while (0)
00363
00364 #define xntbase_umount() \
00365 do { \
00366 xnpod_discard_tbase_proc(&nktbase); \
00367 removeq(&nktimebaseq, &nktbase.link); \
00368 } while (0)
00369
00370 #endif
00371
00374 #endif