6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21
22 /*
23 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
25 */
26
27 #ifndef _SYS_DDI_TIMER_H
28 #define _SYS_DDI_TIMER_H
29
30 #include <sys/list.h>
31
32 #ifdef __cplusplus
33 extern "C" {
34 #endif
35
36 #ifdef _KERNEL
37
38 /*
39 * Used by the new timeout functions
40 */
41 typedef struct __timeout *timeout_t;
42
43 /*
44 * Forward declarations.
45 */
46 struct cyc_timer;
47 struct tm_req;
48
49 /*
50 * Timing wheel cog.
51 * Each cog has a timeout request queue which is guarded by the lock
52 * here.
53 */
54 typedef struct timer_tw {
55 list_t req; /* timeout request queue */
56 kmutex_t lock; /* lock for this queue */
57 } timer_tw_t;
58
59 /*
60 * Timer based on the cyclic subsystem.
61 * For each resolution, this timer structure should be allocated.
62 * Note. currently only one timer is used for periodic timeout requests,
63 * which is based on the system clock resolution.
64 */
65 typedef struct cyc_timer {
66 hrtime_t res; /* this cyclic resolution */
67 hrtime_t tick; /* tick of this cyclic */
68 hrtime_t tick_time; /* current time on this timer */
69 /*
70 * The hash size might need to be tuned if the lock contention is
71 * observed. So far the current size (1024) is sufficient though.
72 */
73 #define TM_HASH_SZ (1024) /* must be power of 2 */
74 #define TM_HASH(x) ((x) & (TM_HASH_SZ -1))
75 timer_tw_t idhash[TM_HASH_SZ]; /* ID hash */
76 timer_tw_t exhash[TM_HASH_SZ]; /* expiration time hash */
77 } cyc_timer_t;
78
79 /*
80 * This value determines how many requests within 10ms can be allocated to
81 * different slots. This is an exponential number powered by 2.
82 * This value should be tuned with the hash size.
83 * Note. This value is fixed now, but can be adjusted by checking the number
84 * of CPUs when the timer structure is allocated.
85 */
86 #define TICK_FACTOR (3)
87
88 /*
89 * Timer request.
90 */
91 typedef struct tm_req {
92 struct list_node id_req; /* request on ID hash */
93 struct list_node ex_req; /* request on expire hash */
94 struct list_node disp_req; /* request on dispatch queue */
95 hrtime_t interval; /* interval this request needs */
96 hrtime_t exp_time; /* time when the request executes */
97 void (*handler)(void *); /* timeout handler */
98 void *arg; /* timeout argument */
99 kthread_t *h_thread; /* handler thread */
100 kmutex_t lock; /* lock for setting counter and flag */
101 kcondvar_t cv; /* condition variable against the lock */
102 timeout_t id; /* this request id */
103 int level; /* interrupt level */
104 volatile uint_t flags; /* flags passed to ddi_timeout() */
105 /*
106 * State flags
107 * These are used internally.
108 */
109 #define TM_INVOKING 0x00000001 /* cyclic is invoked now */
110 #define TM_EXECUTING 0x00000002 /* timeout is executed now */
111 #define TM_CANCEL 0x00000004 /* request is canceled */
112 #define TM_TRANSFER 0x00000008 /* request is transfered */
113 #define TM_UTMCOMP 0x00000040 /* untimeout is complete */
114 uint_t cnt; /* invoke counter */
115 } tm_req_t;
116
117 /*
118 * Software interrupt intr_state:
119 *
120 * 31 16 15 0
121 * +------------------+------------------+
122 * | interrupt start | interrupt set |
123 * +------------------+------------------+
124 *
125 * Note. This structure can accomodate interrupts up to the level 15,
126 * but supported interrupts are up to the level 10 in practice because
127 * of the ddi timer restriction.
128 */
129 #define TM_INTR_SET(l) (1 << (l))
130 #define TM_INTR_START(l) (1 << ((l) + 16))
131
132 /*
133 * internal functions for the ddi timeout
134 */
135 void timer_init(void);
136 void cyclic_timer(void);
137 void timer_softintr(int);
138 timeout_t i_timeout(void (*)(void *), void *, hrtime_t, int);
139 void i_untimeout(timeout_t);
140
141 #endif /* _KERNEL */
142
143 #ifdef __cplusplus
144 }
145 #endif
146
147 #endif /* _SYS_DDI_TIMER_H */
|
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21
22 /*
23 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
25 */
26 /*
27 * Copyright (c) 2013, Joyent, Inc. All rights reserved.
28 */
29
30 #ifndef _SYS_DDI_TIMER_H
31 #define _SYS_DDI_TIMER_H
32
33 #include <sys/list.h>
34 #include <sys/taskq_impl.h>
35 #include <sys/cyclic.h>
36
37 #ifdef __cplusplus
38 extern "C" {
39 #endif
40
41 #ifdef _KERNEL
42
43 /*
44 * Used by the new timeout functions
45 */
46 typedef struct __timeout *timeout_t;
47
48 typedef enum ddi_periodic_flags {
49 DPF_DISPATCHED = 0x01,
50 DPF_EXECUTING = 0x02,
51 DPF_CANCELLED = 0x04
52 } ddi_periodic_flags_t;
53
54 typedef struct ddi_periodic_impl {
55 struct list_node dpr_link; /* protected by periodics_lock */
56 struct list_node dpr_softint_link; /* only used when DPF_DISPATCHED */
57 id_t dpr_id;
58 hrtime_t dpr_interval;
59
60 kmutex_t dpr_lock;
61 kcondvar_t dpr_cv;
62 ddi_periodic_flags_t dpr_flags;
63 uint_t dpr_level; /* 0 <= dpr_level <= 10 */
64 taskq_ent_t dpr_taskq_ent; /* only used for level of 0 */
65 uint64_t dpr_fire_count;
66
67 cyclic_id_t dpr_cyclic_id;
68
69 void (*dpr_handler)(void *);
70 void *dpr_arg;
71 } ddi_periodic_impl_t;
72
73 /*
74 * Internal implementation functions for the DDI periodic interface.
75 */
76 void ddi_periodic_init(void);
77 void ddi_periodic_softintr(int level);
78 timeout_t i_timeout(void (*)(void *), void *, hrtime_t, int);
79 void i_untimeout(timeout_t);
80
81 #endif /* _KERNEL */
82
83 #ifdef __cplusplus
84 }
85 #endif
86
87 #endif /* _SYS_DDI_TIMER_H */
|