xref: /aosp_15_r20/external/minigbm/drv_array_helpers.c (revision d95af8df99a05bcb8679a54dc3ab8e5cd312b38e)
1*d95af8dfSAndroid Build Coastguard Worker /*
2*d95af8dfSAndroid Build Coastguard Worker  * Copyright 2017 The Chromium OS Authors. All rights reserved.
3*d95af8dfSAndroid Build Coastguard Worker  * Use of this source code is governed by a BSD-style license that can be
4*d95af8dfSAndroid Build Coastguard Worker  * found in the LICENSE file.
5*d95af8dfSAndroid Build Coastguard Worker  */
6*d95af8dfSAndroid Build Coastguard Worker #include "drv_array_helpers.h"
7*d95af8dfSAndroid Build Coastguard Worker 
8*d95af8dfSAndroid Build Coastguard Worker #include <assert.h>
9*d95af8dfSAndroid Build Coastguard Worker #include <stdint.h>
10*d95af8dfSAndroid Build Coastguard Worker #include <stdlib.h>
11*d95af8dfSAndroid Build Coastguard Worker #include <string.h>
12*d95af8dfSAndroid Build Coastguard Worker 
13*d95af8dfSAndroid Build Coastguard Worker #include "util.h"
14*d95af8dfSAndroid Build Coastguard Worker 
15*d95af8dfSAndroid Build Coastguard Worker struct drv_array {
16*d95af8dfSAndroid Build Coastguard Worker 	void **items;
17*d95af8dfSAndroid Build Coastguard Worker 	uint32_t size;
18*d95af8dfSAndroid Build Coastguard Worker 	uint32_t item_size;
19*d95af8dfSAndroid Build Coastguard Worker 	uint32_t allocations;
20*d95af8dfSAndroid Build Coastguard Worker };
21*d95af8dfSAndroid Build Coastguard Worker 
drv_array_init(uint32_t item_size)22*d95af8dfSAndroid Build Coastguard Worker struct drv_array *drv_array_init(uint32_t item_size)
23*d95af8dfSAndroid Build Coastguard Worker {
24*d95af8dfSAndroid Build Coastguard Worker 	struct drv_array *array;
25*d95af8dfSAndroid Build Coastguard Worker 
26*d95af8dfSAndroid Build Coastguard Worker 	array = calloc(1, sizeof(*array));
27*d95af8dfSAndroid Build Coastguard Worker 	if (!array)
28*d95af8dfSAndroid Build Coastguard Worker 		return NULL;
29*d95af8dfSAndroid Build Coastguard Worker 
30*d95af8dfSAndroid Build Coastguard Worker 	/* Start with a power of 2 number of allocations. */
31*d95af8dfSAndroid Build Coastguard Worker 	array->allocations = 2;
32*d95af8dfSAndroid Build Coastguard Worker 	array->items = calloc(array->allocations, sizeof(*array->items));
33*d95af8dfSAndroid Build Coastguard Worker 	if (!array->items) {
34*d95af8dfSAndroid Build Coastguard Worker 		free(array);
35*d95af8dfSAndroid Build Coastguard Worker 		return NULL;
36*d95af8dfSAndroid Build Coastguard Worker 	}
37*d95af8dfSAndroid Build Coastguard Worker 
38*d95af8dfSAndroid Build Coastguard Worker 	array->item_size = item_size;
39*d95af8dfSAndroid Build Coastguard Worker 	return array;
40*d95af8dfSAndroid Build Coastguard Worker }
41*d95af8dfSAndroid Build Coastguard Worker 
drv_array_append(struct drv_array * array,void * data)42*d95af8dfSAndroid Build Coastguard Worker void *drv_array_append(struct drv_array *array, void *data)
43*d95af8dfSAndroid Build Coastguard Worker {
44*d95af8dfSAndroid Build Coastguard Worker 	void *item;
45*d95af8dfSAndroid Build Coastguard Worker 
46*d95af8dfSAndroid Build Coastguard Worker 	if (array->size >= array->allocations) {
47*d95af8dfSAndroid Build Coastguard Worker 		void **new_items = NULL;
48*d95af8dfSAndroid Build Coastguard Worker 		array->allocations *= 2;
49*d95af8dfSAndroid Build Coastguard Worker 		new_items = realloc(array->items, array->allocations * sizeof(*array->items));
50*d95af8dfSAndroid Build Coastguard Worker 		assert(new_items);
51*d95af8dfSAndroid Build Coastguard Worker 		array->items = new_items;
52*d95af8dfSAndroid Build Coastguard Worker 	}
53*d95af8dfSAndroid Build Coastguard Worker 
54*d95af8dfSAndroid Build Coastguard Worker 	item = calloc(1, array->item_size);
55*d95af8dfSAndroid Build Coastguard Worker 	memcpy(item, data, array->item_size);
56*d95af8dfSAndroid Build Coastguard Worker 	array->items[array->size] = item;
57*d95af8dfSAndroid Build Coastguard Worker 	array->size++;
58*d95af8dfSAndroid Build Coastguard Worker 	return item;
59*d95af8dfSAndroid Build Coastguard Worker }
60*d95af8dfSAndroid Build Coastguard Worker 
drv_array_remove(struct drv_array * array,uint32_t idx)61*d95af8dfSAndroid Build Coastguard Worker void drv_array_remove(struct drv_array *array, uint32_t idx)
62*d95af8dfSAndroid Build Coastguard Worker {
63*d95af8dfSAndroid Build Coastguard Worker 	uint32_t i;
64*d95af8dfSAndroid Build Coastguard Worker 
65*d95af8dfSAndroid Build Coastguard Worker 	assert(array);
66*d95af8dfSAndroid Build Coastguard Worker 	assert(idx < array->size);
67*d95af8dfSAndroid Build Coastguard Worker 
68*d95af8dfSAndroid Build Coastguard Worker 	free(array->items[idx]);
69*d95af8dfSAndroid Build Coastguard Worker 	array->items[idx] = NULL;
70*d95af8dfSAndroid Build Coastguard Worker 
71*d95af8dfSAndroid Build Coastguard Worker 	for (i = idx + 1; i < array->size; i++)
72*d95af8dfSAndroid Build Coastguard Worker 		array->items[i - 1] = array->items[i];
73*d95af8dfSAndroid Build Coastguard Worker 
74*d95af8dfSAndroid Build Coastguard Worker 	array->size--;
75*d95af8dfSAndroid Build Coastguard Worker 	if ((DIV_ROUND_UP(array->allocations, 2) > array->size) && array->allocations > 2) {
76*d95af8dfSAndroid Build Coastguard Worker 		void **new_items = NULL;
77*d95af8dfSAndroid Build Coastguard Worker 		array->allocations = DIV_ROUND_UP(array->allocations, 2);
78*d95af8dfSAndroid Build Coastguard Worker 		new_items = realloc(array->items, array->allocations * sizeof(*array->items));
79*d95af8dfSAndroid Build Coastguard Worker 		assert(new_items);
80*d95af8dfSAndroid Build Coastguard Worker 		array->items = new_items;
81*d95af8dfSAndroid Build Coastguard Worker 	}
82*d95af8dfSAndroid Build Coastguard Worker }
83*d95af8dfSAndroid Build Coastguard Worker 
drv_array_at_idx(struct drv_array * array,uint32_t idx)84*d95af8dfSAndroid Build Coastguard Worker void *drv_array_at_idx(struct drv_array *array, uint32_t idx)
85*d95af8dfSAndroid Build Coastguard Worker {
86*d95af8dfSAndroid Build Coastguard Worker 	assert(idx < array->size);
87*d95af8dfSAndroid Build Coastguard Worker 	return array->items[idx];
88*d95af8dfSAndroid Build Coastguard Worker }
89*d95af8dfSAndroid Build Coastguard Worker 
drv_array_size(struct drv_array * array)90*d95af8dfSAndroid Build Coastguard Worker uint32_t drv_array_size(struct drv_array *array)
91*d95af8dfSAndroid Build Coastguard Worker {
92*d95af8dfSAndroid Build Coastguard Worker 	return array->size;
93*d95af8dfSAndroid Build Coastguard Worker }
94*d95af8dfSAndroid Build Coastguard Worker 
drv_array_destroy(struct drv_array * array)95*d95af8dfSAndroid Build Coastguard Worker void drv_array_destroy(struct drv_array *array)
96*d95af8dfSAndroid Build Coastguard Worker {
97*d95af8dfSAndroid Build Coastguard Worker 	uint32_t i;
98*d95af8dfSAndroid Build Coastguard Worker 
99*d95af8dfSAndroid Build Coastguard Worker 	for (i = 0; i < array->size; i++)
100*d95af8dfSAndroid Build Coastguard Worker 		free(array->items[i]);
101*d95af8dfSAndroid Build Coastguard Worker 
102*d95af8dfSAndroid Build Coastguard Worker 	free(array->items);
103*d95af8dfSAndroid Build Coastguard Worker 	free(array);
104*d95af8dfSAndroid Build Coastguard Worker }
105