1 #ifndef _KERN_MPQUEUE_H 2 #define _KERN_MPQUEUE_H 3 #include <kern/locks.h> 4 5 __BEGIN_DECLS 6 7 #ifdef MACH_KERNEL_PRIVATE 8 9 #include <kern/priority_queue.h> 10 11 /*----------------------------------------------------------------*/ 12 /* 13 * Define macros for queues with locks. 14 */ 15 struct mpqueue_head { 16 struct queue_entry head; /* header for queue */ 17 struct priority_queue_deadline_min mpq_pqhead; 18 uint64_t earliest_soft_deadline; 19 uint64_t count; 20 lck_mtx_t lock_data; 21 #if defined(__i386__) || defined(__x86_64__) 22 lck_mtx_ext_t lock_data_ext; 23 #endif 24 }; 25 26 typedef struct mpqueue_head mpqueue_head_t; 27 28 #if defined(__i386__) || defined(__x86_64__) 29 30 #define mpqueue_init(q, lck_grp, lck_attr) \ 31 MACRO_BEGIN \ 32 queue_init(&(q)->head); \ 33 lck_mtx_init_ext(&(q)->lock_data, \ 34 &(q)->lock_data_ext, \ 35 lck_grp, \ 36 lck_attr); \ 37 (q)->earliest_soft_deadline = UINT64_MAX; \ 38 (q)->count = 0; \ 39 priority_queue_init(&(q)->mpq_pqhead); \ 40 MACRO_END 41 42 #else 43 44 #define mpqueue_init(q, lck_grp, lck_attr) \ 45 MACRO_BEGIN \ 46 queue_init(&(q)->head); \ 47 lck_mtx_init(&(q)->lock_data, \ 48 lck_grp, \ 49 lck_attr); \ 50 priority_queue_init(&(q)->mpq_pqhead); \ 51 MACRO_END 52 #endif 53 54 55 #define mpenqueue_tail(q, elt) \ 56 MACRO_BEGIN \ 57 lck_mtx_lock_spin_always(&(q)->lock_data); \ 58 enqueue_tail(&(q)->head, elt); \ 59 lck_mtx_unlock_always(&(q)->lock_data); \ 60 MACRO_END 61 62 #define mpdequeue_head(q, elt) \ 63 MACRO_BEGIN \ 64 lck_mtx_lock_spin_always(&(q)->lock_data); \ 65 if (queue_empty(&(q)->head)) \ 66 *(elt) = 0; \ 67 else \ 68 *(elt) = dequeue_head(&(q)->head); \ 69 lck_mtx_unlock_always(&(q)->lock_data); \ 70 MACRO_END 71 72 #endif /* MACH_KERNEL_PRIVATE */ 73 74 __END_DECLS 75 76 77 #endif /* _KERN_QUEUE_H */ 78