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