-/*
- * Returns NULL if stack is empty.
- */
-struct wfs_node *
-__wfs_pop_blocking(struct wfs_stack *s)
-{
- struct wfs_node *head, *next;
- int attempt = 0;
-
-retry:
- head = LOAD_SHARED(s->head);
- if (head == WF_STACK_END)
- return NULL;
- /*
- * Adaptative busy-looping waiting for push to complete.
- */
- while ((next = LOAD_SHARED(head->next)) == NULL) {
- if (++attempt >= WFS_ADAPT_ATTEMPTS) {
- poll(NULL, 0, WFS_WAIT); /* Wait for 10ms */
- attempt = 0;
- } else
- cpu_relax();
- }
- if (uatomic_cmpxchg(&s->head, head, next) == head)
- return head;
- else
- goto retry; /* Concurrent modification. Retry. */
-}
-
-struct wfs_node *
-wfs_pop_blocking(struct wfs_stack *s)
-{
- struct wfs_node *retnode;
- int ret;
-
- ret = pthread_mutex_lock(&s->lock);
- assert(!ret);
- retnode = __wfs_pop_blocking(s);
- ret = pthread_mutex_unlock(&s->lock);
- assert(!ret);
- return retnode;
-}