-
Notifications
You must be signed in to change notification settings - Fork 15
/
Copy pathrinq.c
104 lines (91 loc) · 2.04 KB
/
rinq.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
// read "rinq" as "ring-queue"
struct rinq {
struct rinq *next;
struct rinq *prev;
void *ref;
};
#define RINQ_IS_UNINIT(x_) ((x_)->next == NULL && (x_)->prev == NULL)
#define RINQ_IS_DETACHED(x_) ((x_)->next == (x_))
#define RINQ_IS_ATTACHED(x_) ((x_)->next != (x_))
#define RINQ_NEW(x_,ref_) do { \
x_ = (struct rinq *)malloc(sizeof(struct rinq)); \
x_->next = x_->prev = x_; \
x_->ref = ref_; \
} while(0)
#define RINQ_DETACH(x_) do { \
(x_)->next->prev = (x_)->prev; \
(x_)->prev->next = (x_)->next; \
(x_)->next = (x_)->prev = (x_); \
} while(0)
// INLINE_UNLESS_DEBUG
// static void
// rinq_unshift(struct rinq **head, void *ref)
// {
// struct rinq *x;
// RINQ_NEW(x,ref);
//
// if ((*head) != NULL) {
// x->next = (*head)->next;
// x->prev = (*head);
// x->next->prev = x->prev->next = x;
// }
// (*head) = x;
// }
INLINE_UNLESS_DEBUG
static void
rinq_push (struct rinq **head, void *ref)
{
struct rinq *x;
RINQ_NEW(x,ref);
if ((*head) == NULL) {
(*head) = x;
}
else {
x->next = (*head);
x->prev = (*head)->prev;
x->next->prev = x->prev->next = x;
}
}
// remove element from tail of rinq
// not actually used
// INLINE_UNLESS_DEBUG
// static void *
// rinq_pop (struct rinq **head) {
// void *ref;
// struct rinq *x;
//
// if ((*head) == NULL) return NULL;
//
// if (RINQ_IS_DETACHED((*head))) {
// x = (*head);
// (*head) = NULL;
// }
// else {
// x = (*head)->prev;
// RINQ_DETACH(x);
// }
//
// ref = x->ref;
// free(x);
// return ref;
// }
// remove element from head of rinq
INLINE_UNLESS_DEBUG
static void *
rinq_shift (struct rinq **head) {
void *ref;
struct rinq *x;
if ((*head) == NULL) return NULL;
if (RINQ_IS_DETACHED((*head))) {
x = (*head);
(*head) = NULL;
}
else {
x = (*head);
(*head) = (*head)->next;
RINQ_DETACH(x);
}
ref = x->ref;
free(x);
return ref;
}