/ duct-tape / xnu / osfmk / kern / mpqueue.h
mpqueue.h
 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 */