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 */