xref: /onnv-gate/usr/src/uts/common/sys/ddi_timer.h (revision 9314:4be129136bf2)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
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 */
148