1 // SPDX-License-Identifier: GPL-2.0+
3 * Handles a contiguous list of pointers which be allocated and freed
5 * Copyright 2023 Google LLC
10 #include <display_options.h>
16 ALIST_INITIAL_SIZE = 4, /* default size of unsized list */
19 bool alist_init(struct alist *lst, uint obj_size, uint start_size)
21 /* Avoid realloc for the initial size to help malloc_simple */
22 memset(lst, '\0', sizeof(struct alist));
24 lst->data = calloc(obj_size, start_size);
26 lst->flags = ALISTF_FAIL;
29 lst->alloc = start_size;
31 lst->obj_size = obj_size;
36 void alist_uninit(struct alist *lst)
40 /* Clear fields to avoid any confusion */
41 memset(lst, '\0', sizeof(struct alist));
45 * alist_expand_to() - Expand a list to the given size
47 * @lst: List to modify
48 * @inc_by: Amount to expand to
49 * Return: true if OK, false if out of memory
51 static bool alist_expand_to(struct alist *lst, uint new_alloc)
55 if (lst->flags & ALISTF_FAIL)
58 /* avoid using realloc() since it increases code size */
59 new_data = malloc(lst->obj_size * new_alloc);
61 lst->flags |= ALISTF_FAIL;
65 memcpy(new_data, lst->data, lst->obj_size * lst->alloc);
68 memset(new_data + lst->obj_size * lst->alloc, '\0',
69 lst->obj_size * (new_alloc - lst->alloc));
70 lst->alloc = new_alloc;
76 bool alist_expand_by(struct alist *lst, uint inc_by)
78 return alist_expand_to(lst, lst->alloc + inc_by);
82 * alist_expand_min() - Expand to at least the provided size
84 * Expands to the lowest power of two which can incorporate the new size
86 * @lst: alist to expand
87 * @min_alloc: Minimum new allocated size; if 0 then ALIST_INITIAL_SIZE is used
88 * Return: true if OK, false if out of memory
90 static bool alist_expand_min(struct alist *lst, uint min_alloc)
94 for (new_alloc = lst->alloc ?: ALIST_INITIAL_SIZE;
95 new_alloc < min_alloc;)
98 return alist_expand_to(lst, new_alloc);
101 const void *alist_get_ptr(const struct alist *lst, uint index)
103 if (index >= lst->count)
106 return lst->data + index * lst->obj_size;
109 void *alist_ensure_ptr(struct alist *lst, uint index)
111 uint minsize = index + 1;
114 if (index >= lst->alloc && !alist_expand_min(lst, minsize))
117 ptr = lst->data + index * lst->obj_size;
118 if (minsize >= lst->count)
119 lst->count = minsize;
124 void *alist_add_placeholder(struct alist *lst)
126 return alist_ensure_ptr(lst, lst->count);
129 void *alist_add_ptr(struct alist *lst, void *obj)
133 ptr = alist_add_placeholder(lst);
136 memcpy(ptr, obj, lst->obj_size);
141 void *alist_uninit_move_ptr(struct alist *alist, size_t *countp)
146 *countp = alist->count;
154 /* Clear everything out so there is no record of the data */
155 alist_init(alist, alist->obj_size, 0);