/* * Fast, unordered lists * * Supports add, remove, and iterate * * Underneath, they're a radix tree and an IDA, with a percpu buffer for slot * allocation and freeing. * * This means that adding, removing, and iterating over items is lockless, * except when refilling/emptying the percpu slot buffers.
*/
staticint fast_list_alloc_idx(struct fast_list *l, gfp_t gfp)
{ int idx = ida_alloc_range(&l->slots_allocated, 1, INT_MAX, gfp); if (unlikely(idx < 0)) return 0;
if (unlikely(!genradix_ptr_alloc_inlined(&l->items, idx, gfp))) {
ida_free(&l->slots_allocated, idx); return 0;
}
return idx;
}
/** * fast_list_get_idx - get a slot in a fast_list * @l: list to get slot in * * This allocates a slot in the radix tree without storing to it, so that we can * take the potential memory allocation failure early and do the list add later * when we can't take an allocation failure. * * Returns: positive integer on success, -ENOMEM on failure
*/ int fast_list_get_idx(struct fast_list *l)
{ unsignedlong flags; int idx;
retry:
local_irq_save(flags); struct fast_list_pcpu *lp = this_cpu_ptr(l->buffer);
/** * fast_list_add - add an item to a fast_list * @l: list * @item: item to add * * Allocates a slot in the radix tree and stores to it and then returns the * slot index, which must be passed to fast_list_remove(). * * Returns: positive integer on success, -ENOMEM on failure
*/ int fast_list_add(struct fast_list *l, void *item)
{ int idx = fast_list_get_idx(l); if (idx < 0) return idx;
/** * fast_list_remove - remove an item from a fast_list * @l: list * @idx: item's slot index * * Zeroes out the slot in the radix tree and frees the slot for future * fast_list_add() operations.
*/ void fast_list_remove(struct fast_list *l, unsigned idx)
{
u32 entries[16], nr = 0; unsignedlong flags;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.