11#pragma once
22
3+ #include <stddef.h>
34#include <stdint.h>
45
56/* TIMER */
@@ -10,4 +11,98 @@ typedef struct {
1011
1112void semu_timer_init (semu_timer_t * timer , uint64_t freq );
1213uint64_t semu_timer_get (semu_timer_t * timer );
13- void semu_timer_rebase (semu_timer_t * timer , uint64_t time );
14+ void semu_timer_rebase (semu_timer_t * timer , uint64_t time );
15+
16+ /* Linux-like queue API */
17+
18+ #if defined(__GNUC__ )
19+ #define __QUEUE_HAVE_TYPEOF 1
20+ #endif
21+
22+ /* Merely a doubly-linked list */
23+ struct queue_head {
24+ struct queue_head * prev , * next ;
25+ };
26+
27+ #define QUEUE_HEAD (head ) struct queue_head head = {&(head), &(head)}
28+
29+ static inline void INIT_QUEUE_HEAD (struct queue_head * head )
30+ {
31+ head -> next = head ;
32+ head -> prev = head ;
33+ }
34+
35+ /* Push the node to the end of queue */
36+ static inline void queue_push (struct queue_head * node , struct queue_head * head )
37+ {
38+ struct queue_head * prev = head -> prev ;
39+
40+ prev -> next = node ;
41+ node -> next = head ;
42+ node -> prev = prev ;
43+ head -> prev = node ;
44+ }
45+
46+ static inline int queue_empty (const struct queue_head * head )
47+ {
48+ return (head -> next == head );
49+ }
50+
51+ static inline void queue_del (struct queue_head * node )
52+ {
53+ struct queue_head * next = node -> next ;
54+ struct queue_head * prev = node -> prev ;
55+
56+ next -> prev = prev ;
57+ prev -> next = next ;
58+
59+ node -> prev = (struct queue_head * ) (0x00100100 );
60+ node -> next = (struct queue_head * ) (0x00200200 );
61+ }
62+
63+ static inline void queue_del_init (struct queue_head * node )
64+ {
65+ queue_del (node );
66+ INIT_QUEUE_HEAD (node );
67+ }
68+
69+ #ifndef container_of
70+ #ifdef __QUEUE_HAVE_TYPEOF
71+ #define container_of (ptr , type , member ) \
72+ __extension__({ \
73+ const __typeof__(((type *) 0)->member) *__pmember = (ptr); \
74+ (type *) ((char *) __pmember - offsetof(type, member)); \
75+ })
76+ #else
77+ #define container_of (ptr , type , member ) \
78+ ((type *) ((char *) (ptr) -offsetof(type, member)))
79+ #endif
80+ #endif
81+
82+ #define queue_entry (node , type , member ) container_of(node, type, member)
83+
84+ #define queue_first_entry (head , type , member ) \
85+ queue_entry((head)->next, type, member)
86+
87+ #define queue_last_entry (head , type , member ) \
88+ queue_entry((head)->prev, type, member)
89+
90+ #define queue_for_each (node , head ) \
91+ for (node = (head)->next; node != (head); node = node->next)
92+
93+ #ifdef __QUEUE_HAVE_TYPEOF
94+ #define queue_for_each_entry (entry , head , member ) \
95+ for (entry = queue_entry((head)->next, __typeof__(*entry), member); \
96+ &entry->member != (head); \
97+ entry = queue_entry(entry->member.next, __typeof__(*entry), member))
98+ #endif
99+
100+ #define queue_for_each_safe (node , safe , head ) \
101+ for (node = (head)->next, safe = node->next; node != (head); \
102+ node = safe, safe = node->next)
103+
104+ #define queue_for_each_entry_safe (entry , safe , head , member ) \
105+ for (entry = queue_entry((head)->next, __typeof__(*entry), member), \
106+ safe = queue_entry(entry->member.next, __typeof__(*entry), member); \
107+ &entry->member != (head); entry = safe, \
108+ safe = queue_entry(safe->member.next, __typeof__(*entry), member))
0 commit comments