void pa_asyncq_post(pa_asyncq*l, void *p) { struct localq *q; pa_assert(l); pa_assert(p); if (flush_postq(l, FALSE)) if (pa_asyncq_push(l, p, FALSE) >= 0) return; /* OK, we couldn't push anything in the queue. So let's queue it * locally and push it later */ if (pa_log_ratelimit()) pa_log_warn("q overrun, queuing locally"); if (!(q = pa_flist_pop(PA_STATIC_FLIST_GET(localq)))) q = pa_xnew(struct localq, 1); q->data = p; PA_LLIST_PREPEND(struct localq, l->localq, q); if (!l->last_localq) l->last_localq = q; return; }
/* No lock necessary */ static struct mempool_slot* mempool_allocate_slot(pa_mempool *p) { struct mempool_slot *slot; pa_assert(p); if (!(slot = pa_flist_pop(p->free_slots))) { int idx; /* The free list was empty, we have to allocate a new entry */ if ((unsigned) (idx = pa_atomic_inc(&p->n_init)) >= p->n_blocks) pa_atomic_dec(&p->n_init); else slot = (struct mempool_slot*) ((uint8_t*) p->memory.ptr + (p->block_size * (size_t) idx)); if (!slot) { if (pa_log_ratelimit(PA_LOG_DEBUG)) pa_log_debug("Pool full"); pa_atomic_inc(&p->stat.n_pool_full); return NULL; } } /* #ifdef HAVE_VALGRIND_MEMCHECK_H */ /* if (PA_UNLIKELY(pa_in_valgrind())) { */ /* VALGRIND_MALLOCLIKE_BLOCK(slot, p->block_size, 0, 0); */ /* } */ /* #endif */ return slot; }
int pa_flist_push(pa_flist *l, void *p) { pa_flist_elem *elem; pa_assert(l); pa_assert(p); elem = stack_pop(l, &l->empty); if (elem == NULL) { if (pa_log_ratelimit(PA_LOG_DEBUG)) pa_log_debug("%s flist is full (don't worry)", l->name); return -1; } pa_atomic_ptr_store(&elem->ptr, p); stack_push(l, &l->stored, elem); return 0; }