summaryrefslogtreecommitdiff
path: root/usr/src/uts/common/sys/ddi_timer.h
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src/uts/common/sys/ddi_timer.h')
-rw-r--r--usr/src/uts/common/sys/ddi_timer.h151
1 files changed, 151 insertions, 0 deletions
diff --git a/usr/src/uts/common/sys/ddi_timer.h b/usr/src/uts/common/sys/ddi_timer.h
new file mode 100644
index 0000000000..035a68f74f
--- /dev/null
+++ b/usr/src/uts/common/sys/ddi_timer.h
@@ -0,0 +1,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 */