xref: /onnv-gate/usr/src/uts/common/sys/ddi_timer.h (revision 5107:bb9efa2ee1e8)
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 2007 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 #pragma ident	"%Z%%M%	%I%	%E% SMI"
31 
32 #include <sys/list.h>
33 
34 #ifdef	__cplusplus
35 extern "C" {
36 #endif
37 
38 #ifdef _KERNEL
39 
40 /*
41  * Used by the new timeout functions
42  */
43 typedef struct __timeout *timeout_t;
44 
45 /*
46  * Forward declarations.
47  */
48 struct cyc_timer;
49 struct tm_req;
50 
51 /*
52  * Timing wheel cog.
53  * Each cog has a timeout request queue which is guarded by the lock
54  * here.
55  */
56 typedef struct timer_tw {
57 	list_t req;			/* timeout request queue */
58 	kmutex_t lock;			/* lock for this queue */
59 } timer_tw_t;
60 
61 /*
62  * Timer based on the cyclic subsystem.
63  * For each resolution, this timer structure should be allocated.
64  * Note. currently only one timer is used for periodic timeout requests,
65  * which is based on the system clock resolution.
66  */
67 typedef struct cyc_timer {
68 	hrtime_t res;			/* this cyclic resolution */
69 	hrtime_t tick;			/* tick of this cyclic */
70 	hrtime_t tick_time;		/* current time on this timer */
71 /*
72  * The hash size might need to be tuned if the lock contention is
73  * observed. So far the current size (1024) is sufficient though.
74  */
75 #define	TM_HASH_SZ	(1024)		/* must be power of 2 */
76 #define	TM_HASH(x)	((x) & (TM_HASH_SZ -1))
77 	timer_tw_t idhash[TM_HASH_SZ];	/* ID hash */
78 	timer_tw_t exhash[TM_HASH_SZ];  /* expiration time hash */
79 } cyc_timer_t;
80 
81 /*
82  * This value determines how many requests within 10ms can be allocated to
83  * different slots. This is an exponential number powered by 2.
84  * This value should be tuned with the hash size.
85  * Note. This value is fixed now, but can be adjusted by checking the number
86  * of CPUs when the timer structure is allocated.
87  */
88 #define	TICK_FACTOR	(3)
89 
90 /*
91  * Timer request.
92  */
93 typedef struct tm_req {
94 	struct list_node id_req;	/* request on ID hash */
95 	struct list_node ex_req;	/* request on expire hash */
96 	struct list_node disp_req;	/* request on dispatch queue */
97 	hrtime_t interval;	/* interval this request needs */
98 	hrtime_t exp_time;	/* time when the request executes */
99 	void (*handler)(void *);	/* timeout handler */
100 	void *arg;		/* timeout argument */
101 	kthread_t *h_thread;	/* handler thread */
102 	kmutex_t lock;		/* lock for setting counter and flag */
103 	kcondvar_t cv;		/* condition variable against the lock */
104 	timeout_t id;		/* this request id */
105 	int level;		/* interrupt level */
106 	volatile uint_t flags;	/* flags passed to ddi_timeout() */
107 	/*
108 	 * State flags
109 	 * These are used internally.
110 	 */
111 #define	TM_INVOKING	0x00000001	/* cyclic is invoked now */
112 #define	TM_EXECUTING	0x00000002	/* timeout is executed now */
113 #define	TM_CANCEL	0x00000004	/* request is canceled */
114 #define	TM_TRANSFER	0x00000008	/* request is transfered */
115 #define	TM_COMPLETE	0x00000010	/* request is complete */
116 #define	TM_COMPWAIT	0x00000020	/* wait request completion */
117 #define	TM_UTMCOMP	0x00000040	/* untimeout is complete */
118 	uint_t cnt;		/* invoke counter */
119 } tm_req_t;
120 
121 /*
122  * Software interrupt intr_state:
123  *
124  *  31              16 15               0
125  * +------------------+------------------+
126  * |  interrupt start |  interrupt set   |
127  * +------------------+------------------+
128  *
129  * Note. This structure can accomodate interrupts up to the level 15,
130  * but supported interrupts are up to the level 10 in practice because
131  * of the ddi timer restriction.
132  */
133 #define	TM_INTR_SET(l)		(1 << (l))
134 #define	TM_INTR_START(l)	(1 << ((l) + 16))
135 
136 /*
137  * internal functions for the ddi timeout
138  */
139 void timer_init(void);
140 void cyclic_timer(void);
141 void timer_softintr(int);
142 timeout_t i_timeout(void (*)(void *), void *, hrtime_t, int);
143 void i_untimeout(timeout_t);
144 
145 #endif	/* _KERNEL */
146 
147 #ifdef	__cplusplus
148 }
149 #endif
150 
151 #endif	/* _SYS_DDI_TIMER_H */
152