]> git.saurik.com Git - apple/xnu.git/blobdiff - osfmk/kern/call_entry.h
xnu-4570.1.46.tar.gz
[apple/xnu.git] / osfmk / kern / call_entry.h
index 57ab51d5e016558a681458c0041c231143b638fe..dede1bffba1406dc1845e19f28309fd86bf3d81f 100644 (file)
 #ifndef _KERN_CALL_ENTRY_H_
 #define _KERN_CALL_ENTRY_H_
 
-#ifdef MACH_KERNEL_PRIVATE
+#ifdef XNU_KERNEL_PRIVATE
 #include <kern/queue.h>
 
-typedef void                   *call_entry_param_t;
-typedef void                   (*call_entry_func_t)(
-                                                               call_entry_param_t              param0,
-                                                               call_entry_param_t              param1);
+#if !CONFIG_EMBEDDED
+#define TIMER_TRACE    1
+#endif
+
+typedef void           *call_entry_param_t;
+typedef void           (*call_entry_func_t)(
+                               call_entry_param_t      param0,
+                               call_entry_param_t      param1);
 
 typedef struct call_entry {
-    queue_chain_t              q_link;
-       queue_t                         queue;
+    queue_chain_t      q_link;
+    queue_head_t       *queue;
     call_entry_func_t  func;
     call_entry_param_t param0;
     call_entry_param_t param1;
-    uint64_t                   deadline;
+    uint64_t           deadline;
+#if TIMER_TRACE
+    uint64_t           entry_time;
+#endif
 } call_entry_data_t;
 
-typedef struct call_entry              *call_entry_t;
-
-extern queue_t         call_entry_enqueue_deadline(
-                                                       call_entry_t            entry,
-                                                       queue_t                         queue,
-                                                       uint64_t                        deadline);
+typedef struct call_entry      *call_entry_t;
 
-extern queue_t         call_entry_enqueue_tail(
-                                                       call_entry_t    entry,
-                                                       queue_t                 queue);
-
-extern queue_t         call_entry_dequeue(
-                                                       call_entry_t    entry);
+#ifdef MACH_KERNEL_PRIVATE
 
-#define        call_entry_setup(entry, pfun, p0)                               \
-MACRO_BEGIN                                                                                            \
+#define        call_entry_setup(entry, pfun, p0)                       \
+MACRO_BEGIN                                                    \
        (entry)->func           = (call_entry_func_t)(pfun);    \
-       (entry)->param0         = (call_entry_param_t)(p0);             \
-       (entry)->queue          = NULL;                                                 \
+       (entry)->param0         = (call_entry_param_t)(p0);     \
+       (entry)->queue          = NULL;                         \
+       (entry)->deadline       = 0;                            \
+       queue_chain_init((entry)->q_link);                      \
 MACRO_END
 
+#define qe(x)          ((queue_entry_t)(x))
+#define CE(x)          ((call_entry_t)(x))
+
+static __inline__ queue_head_t *
+call_entry_enqueue_tail(
+        call_entry_t            entry,
+        queue_t                 queue)
+{
+        queue_t                 old_queue = entry->queue;
+
+        if (old_queue != NULL)
+               re_queue_tail(queue, &entry->q_link);
+       else
+               enqueue_tail(queue, &entry->q_link);
+
+        entry->queue = queue;
+
+        return (old_queue);
+}
+
+static __inline__ queue_head_t *
+call_entry_dequeue(
+       call_entry_t            entry)
+{
+        queue_t                 old_queue = entry->queue;
+
+       if (old_queue != NULL) {
+               (void)remque(qe(entry));
+
+               entry->queue = NULL;
+       }
+       return (old_queue);
+}
+
+static __inline__ queue_head_t *
+call_entry_enqueue_deadline(
+       call_entry_t                    entry,
+       queue_head_t                    *queue,
+       uint64_t                        deadline)
+{
+       queue_t         old_queue = entry->queue;
+       call_entry_t    current;
+
+       if (old_queue != queue || entry->deadline < deadline) {
+               if (old_queue == NULL) {
+                       current = CE(queue_first(queue));
+               } else if (old_queue != queue) {
+                       (void)remque(qe(entry));
+                       current = CE(queue_first(queue));
+               } else {
+                       current = CE(queue_next(qe(entry)));
+                       (void)remque(qe(entry));
+               }
+
+               while (TRUE) {
+                       if (queue_end(queue, qe(current)) ||
+                           deadline < current->deadline) {
+                               current = CE(queue_prev(qe(current)));
+                               break;
+                       }
+
+                       current = CE(queue_next(qe(current)));
+               }
+               insque(qe(entry), qe(current));
+       }
+       else if (deadline < entry->deadline) {
+               current = CE(queue_prev(qe(entry)));
+
+               (void)remque(qe(entry));
+
+               while (TRUE) {
+                       if (queue_end(queue, qe(current)) ||
+                           current->deadline <= deadline) {
+                               break;
+                       }
+
+                       current = CE(queue_prev(qe(current)));
+               }
+               insque(qe(entry), qe(current));
+       }
+       entry->queue = queue;
+       entry->deadline = deadline;
+
+       return (old_queue);
+}
 #endif /* MACH_KERNEL_PRIVATE */
 
+#endif /* XNU_KERNEL_PRIVATE */
+
 #endif /* _KERN_CALL_ENTRY_H_ */