]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/sys/timetc.h
This commit was generated by cvs2svn to compensate for changes in r93694,
[FreeBSD/FreeBSD.git] / sys / sys / timetc.h
1 /*
2  * ----------------------------------------------------------------------------
3  * "THE BEER-WARE LICENSE" (Revision 42):
4  * <phk@FreeBSD.ORG> wrote this file.  As long as you retain this notice you
5  * can do whatever you want with this stuff. If we meet some day, and you think
6  * this stuff is worth it, you can buy me a beer in return.   Poul-Henning Kamp
7  * ----------------------------------------------------------------------------
8  *
9  * $FreeBSD$
10  */
11
12 #ifndef _SYS_TIMETC_H_
13 #define _SYS_TIMETC_H_
14
15 /*
16  * Structure used to interface to the machine dependent hardware support
17  * for timekeeping.
18  *
19  * A timecounter is a (hard or soft) binary counter which has two properties:
20  *    * it runs at a fixed, known frequency.
21  *    * it must not roll over in less than (1 + delta)/HZ seconds.  "delta"
22  *      is expected to be less than 20 msec, but no hard data has been 
23  *      collected on this.  16 bit at 5 MHz (31 msec) is known to work.
24  *
25  * get_timecount() reads the counter.
26  *
27  * counter_mask removes unimplemented bits from the count value.
28  *
29  * frequency is the counter frequency in hz.
30  *
31  * name is a short mnemonic name for this counter.
32  *
33  * cost is a measure of how long time it takes to read the counter.
34  *
35  * adjustment [PPM << 16] which means that the smallest unit of correction
36  *     you can apply amounts to 481.5 usec/year.
37  *
38  * scale_micro [2^32 * usec/tick].
39  * scale_nano_i [ns/tick].
40  * scale_nano_f [(ns/2^32)/tick].
41  *
42  * offset_count is the contents of the counter which corresponds to the
43  *     rest of the offset_* values.
44  *
45  * offset_sec [s].
46  * offset_micro [usec].
47  * offset_nano [ns/2^32] is misnamed, the real unit is .23283064365...
48  *     attoseconds (10E-18) and before you ask: yes, they are in fact 
49  *     called attoseconds, it comes from "atten" for 18 in Danish/Swedish.
50  *
51  * Each timecounter must supply an array of three timecounters, this is needed
52  * to guarantee atomicity in the code.  Index zero is used to transport 
53  * modifications, for instance done with sysctl, into the timecounter being 
54  * used in a safe way.  Such changes may be adopted with a delay of up to 1/HZ,
55  * index one & two are used alternately for the actual timekeeping.
56  *
57  * 'tc_avail' points to the next available (external) timecounter in a
58  *      circular queue.  This is only valid for index 0.
59  *
60  * `tc_other' points to the next "work" timecounter in a circular queue,
61  *      i.e., for index i > 0 it points to index 1 + (i - 1) % NTIMECOUNTER.
62  *      We also use it to point from index 0 to index 1.
63  *
64  * `tc_tweak' points to index 0.
65  */
66
67 struct timecounter;
68 typedef unsigned timecounter_get_t(struct timecounter *);
69 typedef void timecounter_pps_t(struct timecounter *);
70
71 struct timecounter {
72         /* These fields must be initialized by the driver. */
73         timecounter_get_t       *tc_get_timecount;
74         timecounter_pps_t       *tc_poll_pps;
75         unsigned                tc_counter_mask;
76         u_int32_t               tc_frequency;
77         char                    *tc_name;
78         void                    *tc_priv;
79         /* These fields will be managed by the generic code. */
80         int64_t                 tc_adjustment;
81         u_int64_t               tc_scale;
82         unsigned                tc_offset_count;
83         struct bintime          tc_offset;
84         struct timeval          tc_microtime;
85         struct timespec         tc_nanotime;
86         struct timecounter      *tc_avail;
87         struct timecounter      *tc_tweak;
88         /* Fields not to be copied in tc_windup start with tc_generation */
89         volatile unsigned       tc_generation;
90         struct timecounter      *tc_next;
91 };
92
93 #ifdef _KERNEL
94 extern struct timecounter *volatile timecounter;
95
96 void    tc_init(struct timecounter *tc);
97 void    tc_setclock(struct timespec *ts);
98 void    tc_windup(void);
99 void    tc_update(struct timecounter *tc);
100 #endif /* !_KERNEL */
101
102 #endif /* !_SYS_TIMETC_H_ */