xref: /xnu-8020.101.4/osfmk/kern/mpqueue.h (revision e7776783b89a353188416a9a346c6cdb4928faad)
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