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
35extern "C" {
36#endif
37
38#ifdef _KERNEL
39
40/*
41 * Used by the new timeout functions
42 */
43typedef struct __timeout *timeout_t;
44
45/*
46 * Forward declarations.
47 */
48struct cyc_timer;
49struct 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 */
56typedef 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 */
67typedef 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 */
93typedef 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 */
139void timer_init(void);
140void cyclic_timer(void);
141void timer_softintr(int);
142timeout_t i_timeout(void (*)(void *), void *, hrtime_t, int);
143void i_untimeout(timeout_t);
144
145#endif	/* _KERNEL */
146
147#ifdef	__cplusplus
148}
149#endif
150
151#endif	/* _SYS_DDI_TIMER_H */
152