Skip to content

Commit 3b4cc50

Browse files
committed
Stable queue
1 parent 2f2e908 commit 3b4cc50

2 files changed

Lines changed: 568 additions & 44 deletions

File tree

src/static_queue.c

Lines changed: 18 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -94,23 +94,6 @@ int32_t staticQueuePop(staticQueue_t* queue, staticQueueItem_t** pop_item)
9494
return STATIC_QUEUE_EMPTY;
9595
}
9696

97-
// Skip over any inactive items at tail (from previous erase operations)
98-
while (queue->tail != queue->head && !queue->tail->active) {
99-
queue->tail = queue->tail->next;
100-
}
101-
102-
// If tail caught up to head with exactly one active item, move head forward
103-
if (queue->tail == queue->head && queue->tail->active) {
104-
queue->head = queue->head->next;
105-
}
106-
107-
// Check again if empty after skipping
108-
if (staticQueueEmpty(queue)) {
109-
queue->head = queue->first_item;
110-
queue->tail = queue->first_item;
111-
return STATIC_QUEUE_EMPTY;
112-
}
113-
11497
*pop_item = queue->tail;
11598
queue->tail->active = false;
11699
queue->tail = queue->tail->next;
@@ -123,20 +106,7 @@ int32_t staticQueuePeak(staticQueue_t* queue, staticQueueItem_t** peak_item) {
123106
return STATIC_QUEUE_EMPTY;
124107
}
125108

126-
// Skip over any inactive items at tail (from previous erase operations)
127-
staticQueueItem_t* temp_tail = queue->tail;
128-
while (temp_tail != queue->head && !temp_tail->active) {
129-
temp_tail = temp_tail->next;
130-
}
131-
132-
// Check if we reached head without finding an active item
133-
if (temp_tail == queue->head && !temp_tail->active) {
134-
queue->head = queue->first_item;
135-
queue->tail = queue->first_item;
136-
return STATIC_QUEUE_EMPTY;
137-
}
138-
139-
*peak_item = temp_tail;
109+
*peak_item = queue->tail;
140110

141111
return STATIC_QUEUE_SUCCESS;
142112
}
@@ -173,10 +143,14 @@ int32_t staticQueueErase(staticQueue_t* queue, staticQueueItem_t* item)
173143
}
174144

175145
// If erasing the tail item (oldest item), just move tail to next
176-
// Pop/peak will skip over inactive items
177146
if (item == queue->tail) {
178147
queue->tail = queue->tail->next;
179148

149+
// Skip over any remaining inactive items at tail
150+
while (queue->tail != queue->head && !queue->tail->active) {
151+
queue->tail = queue->tail->next;
152+
}
153+
180154
// Check if tail caught up to head with exactly one active item
181155
if (queue->tail == queue->head && queue->tail->active) {
182156
// Move head forward to maintain tail != head invariant for single item
@@ -199,8 +173,7 @@ int32_t staticQueueErase(staticQueue_t* queue, staticQueueItem_t* item)
199173
return STATIC_QUEUE_SUCCESS;
200174
}
201175

202-
// For items in the middle: remove from current position and relink immediately after tail
203-
// This ensures tail never points to an inactive item.
176+
// For items in the middle: remove from current position and relink immediately before tail
204177

205178
// Step 1: Remove item from its current position in the list
206179
staticQueueItem_t* prev_item = item->last;
@@ -209,18 +182,19 @@ int32_t staticQueueErase(staticQueue_t* queue, staticQueueItem_t* item)
209182
prev_item->next = next_item;
210183
next_item->last = prev_item;
211184

212-
// Step 2: Reinsert the item immediately after tail (but before the next active item)
213-
// This keeps it in the circular structure but ensures tail always points to an active item.
214-
staticQueueItem_t* after_tail = queue->tail->next;
185+
// Step 2: Reinsert the item immediately before tail
186+
staticQueueItem_t* before_tail = queue->tail->last;
215187

216-
// Insert: tail <-> item <-> after_tail
217-
queue->tail->next = item;
218-
item->last = queue->tail;
219-
item->next = after_tail;
220-
after_tail->last = item;
188+
// Insert: before_tail <-> item <-> tail
189+
before_tail->next = item;
190+
item->last = before_tail;
191+
item->next = queue->tail;
192+
queue->tail->last = item;
221193

222-
// Don't move tail or head - the inactive item sits right after tail,
223-
// and will be naturally encountered when tail advances during pop.
194+
// Step 3: If queue was full, move head to point to the erased item (now inactive)
195+
if (queue->head == queue->tail && queue->head->active) {
196+
queue->head = item;
197+
}
224198

225199
return STATIC_QUEUE_SUCCESS;
226200
}

0 commit comments

Comments
 (0)