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