include/nucleus/timebase.h

Go to the documentation of this file.
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 /* CONFIG_PROC_FS */
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     /* Time base is running. */
00055 #define XNTBSET  0x00000002     /* Time set in time base. */
00056 #define XNTBLCK  0x00000004     /* Time base is locked. */
00057 #define XNTBISO  0x00000008     /* Time base uses private wallclock offset */
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;       /* !< Name of time base. */
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;       /* !< Timer holder in timebase. */
00083 
00084         int timerq_rev;         /* !< Revision (for non-atomic list walks). */
00085 #endif /* CONFIG_XENO_OPT_STATS */
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         /* Returns the duration of a tick in nanoseconds */
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         /* Convert a count of ticks in nanoseconds */
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         /* Twisted, but tries hard not to rescale to nanoseconds *
00186            before converting, so that we could save a 64bit multiply
00187            in the common cases (i.e. converting to/from master). */
00188 
00189         if (dstbase->tickvalue == srcbase->tickvalue)
00190                 return ticks;
00191 
00192         if (likely(xntbase_master_p(dstbase)))
00193                 return xntbase_ticks2ns(srcbase, ticks); /* Periodic to master base. */
00194 
00195         if (xntbase_master_p(srcbase))
00196                 return xntbase_ns2ticks(dstbase, ticks); /* Master base to periodic. */
00197 
00198         /* Periodic to periodic. */
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 /* !CONFIG_XENO_OPT_TIMING_PERIODIC */
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 /* !CONFIG_XENO_OPT_TIMING_PERIODIC */
00316 
00344 static inline xnticks_t xntbase_get_time(xntbase_t *base)
00345 {
00346         /* Return an adjusted value of the monotonic time with the
00347            translated system wallclock offset. */
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 /* __KERNEL__ || __XENO_SIM__ */
00371 
00374 #endif /* !_XENO_NUCLEUS_TIMEBASE_H */

Generated on Mon Mar 24 18:02:40 2008 for Xenomai API by  doxygen 1.5.3