Print this page
OS-2366 ddi_periodic_add(9F) is entirely rubbish

@@ -21,15 +21,20 @@
 
 /*
  * 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,105 +43,40 @@
 /*
  * Used by the new timeout functions
  */
 typedef struct __timeout *timeout_t;
 
-/*
- * Forward declarations.
- */
-struct cyc_timer;
-struct tm_req;
+typedef enum ddi_periodic_flags {
+        DPF_DISPATCHED = 0x01,
+        DPF_EXECUTING = 0x02,
+        DPF_CANCELLED = 0x04
+} ddi_periodic_flags_t;
 
-/*
- * 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;
+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;
 
-/*
- * 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;
+        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;
 
-/*
- * 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)
+        cyclic_id_t dpr_cyclic_id;
 
-/*
- * 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;
+        void (*dpr_handler)(void *);
+        void *dpr_arg;
+} ddi_periodic_impl_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.
+ * Internal implementation functions for the DDI periodic interface.
  */
-#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);
+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 */