Print this page
OS-2366 ddi_periodic_add(9F) is entirely rubbish
*** 21,35 ****
--- 21,40 ----
/*
* Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
+ /*
+ * Copyright (c) 2013, Joyent, Inc. All rights reserved.
+ */
#ifndef _SYS_DDI_TIMER_H
#define _SYS_DDI_TIMER_H
#include <sys/list.h>
+ #include <sys/taskq_impl.h>
+ #include <sys/cyclic.h>
#ifdef __cplusplus
extern "C" {
#endif
*** 38,142 ****
/*
* 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_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 */
--- 43,82 ----
/*
* Used by the new timeout functions
*/
typedef struct __timeout *timeout_t;
! typedef enum ddi_periodic_flags {
! DPF_DISPATCHED = 0x01,
! DPF_EXECUTING = 0x02,
! DPF_CANCELLED = 0x04
! } ddi_periodic_flags_t;
! typedef struct ddi_periodic_impl {
! struct list_node dpr_link; /* protected by periodics_lock */
! struct list_node dpr_softint_link; /* only used when DPF_DISPATCHED */
! id_t dpr_id;
! hrtime_t dpr_interval;
! kmutex_t dpr_lock;
! kcondvar_t dpr_cv;
! ddi_periodic_flags_t dpr_flags;
! uint_t dpr_level; /* 0 <= dpr_level <= 10 */
! taskq_ent_t dpr_taskq_ent; /* only used for level of 0 */
! uint64_t dpr_fire_count;
! cyclic_id_t dpr_cyclic_id;
! void (*dpr_handler)(void *);
! void *dpr_arg;
! } ddi_periodic_impl_t;
/*
! * Internal implementation functions for the DDI periodic interface.
*/
! void ddi_periodic_init(void);
! void ddi_periodic_softintr(int level);
timeout_t i_timeout(void (*)(void *), void *, hrtime_t, int);
void i_untimeout(timeout_t);
#endif /* _KERNEL */