2016-10-14 03:55:03 +01:00
|
|
|
/*
|
|
|
|
* Copyright © 2015 Intel Corporation
|
|
|
|
*
|
|
|
|
* Permission is hereby granted, free of charge, to any person obtaining a
|
|
|
|
* copy of this software and associated documentation files (the "Software"),
|
|
|
|
* to deal in the Software without restriction, including without limitation
|
|
|
|
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
|
|
|
* and/or sell copies of the Software, and to permit persons to whom the
|
|
|
|
* Software is furnished to do so, subject to the following conditions:
|
|
|
|
*
|
|
|
|
* The above copyright notice and this permission notice (including the next
|
|
|
|
* paragraph) shall be included in all copies or substantial portions of the
|
|
|
|
* Software.
|
|
|
|
*
|
|
|
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
|
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
|
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
|
|
|
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
|
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
|
|
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
|
|
|
* IN THE SOFTWARE.
|
|
|
|
*/
|
|
|
|
|
2022-03-18 05:14:55 +00:00
|
|
|
/*
|
2016-10-14 03:55:03 +01:00
|
|
|
* u_vector is a vector based queue for storing arbitrary
|
|
|
|
* sized arrays of objects without using a linked list.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#ifndef U_VECTOR_H
|
|
|
|
#define U_VECTOR_H
|
|
|
|
|
|
|
|
#include <stdint.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include "util/macros.h"
|
2021-10-05 19:58:58 +01:00
|
|
|
#include "util/u_math.h"
|
2016-10-14 03:55:03 +01:00
|
|
|
|
2020-01-16 23:05:06 +00:00
|
|
|
#ifdef __cplusplus
|
|
|
|
extern "C" {
|
|
|
|
#endif
|
|
|
|
|
2016-10-14 03:55:03 +01:00
|
|
|
/* TODO - move to u_math.h - name it better etc */
|
|
|
|
static inline uint32_t
|
|
|
|
u_align_u32(uint32_t v, uint32_t a)
|
|
|
|
{
|
2017-04-03 15:45:07 +01:00
|
|
|
assert(a != 0 && a == (a & -((int32_t) a)));
|
2016-10-14 03:55:03 +01:00
|
|
|
return (v + a - 1) & ~(a - 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
struct u_vector {
|
|
|
|
uint32_t head;
|
|
|
|
uint32_t tail;
|
|
|
|
uint32_t element_size;
|
|
|
|
uint32_t size;
|
|
|
|
void *data;
|
|
|
|
};
|
|
|
|
|
2021-10-05 19:58:58 +01:00
|
|
|
int u_vector_init_pow2(struct u_vector *queue,
|
|
|
|
uint32_t initial_element_count,
|
|
|
|
uint32_t element_size);
|
|
|
|
|
2016-10-14 03:55:03 +01:00
|
|
|
void *u_vector_add(struct u_vector *queue);
|
|
|
|
void *u_vector_remove(struct u_vector *queue);
|
|
|
|
|
2021-10-05 19:58:58 +01:00
|
|
|
static inline int
|
|
|
|
u_vector_init(struct u_vector *queue,
|
|
|
|
uint32_t initial_element_count,
|
|
|
|
uint32_t element_size)
|
|
|
|
{
|
|
|
|
initial_element_count = util_next_power_of_two(initial_element_count);
|
|
|
|
element_size = util_next_power_of_two(element_size);
|
|
|
|
return u_vector_init_pow2(queue, initial_element_count, element_size);
|
|
|
|
}
|
|
|
|
|
2016-10-14 03:55:03 +01:00
|
|
|
static inline int
|
|
|
|
u_vector_length(struct u_vector *queue)
|
|
|
|
{
|
|
|
|
return (queue->head - queue->tail) / queue->element_size;
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline void *
|
|
|
|
u_vector_head(struct u_vector *vector)
|
|
|
|
{
|
|
|
|
assert(vector->tail < vector->head);
|
|
|
|
return (void *)((char *)vector->data +
|
|
|
|
((vector->head - vector->element_size) &
|
|
|
|
(vector->size - 1)));
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline void *
|
|
|
|
u_vector_tail(struct u_vector *vector)
|
|
|
|
{
|
|
|
|
return (void *)((char *)vector->data + (vector->tail & (vector->size - 1)));
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline void
|
|
|
|
u_vector_finish(struct u_vector *queue)
|
|
|
|
{
|
|
|
|
free(queue->data);
|
|
|
|
}
|
|
|
|
|
2021-11-28 19:33:36 +00:00
|
|
|
#ifdef __cplusplus
|
|
|
|
#define u_vector_element_cast(elem) (decltype(elem))
|
|
|
|
#else
|
|
|
|
#define u_vector_element_cast(elem) (void *)
|
|
|
|
#endif
|
|
|
|
|
2016-10-14 03:55:03 +01:00
|
|
|
#define u_vector_foreach(elem, queue) \
|
2016-11-09 06:58:12 +00:00
|
|
|
STATIC_ASSERT(__builtin_types_compatible_p(__typeof__(queue), struct u_vector *)); \
|
2016-10-14 03:55:03 +01:00
|
|
|
for (uint32_t __u_vector_offset = (queue)->tail; \
|
2021-11-28 19:33:36 +00:00
|
|
|
elem = u_vector_element_cast(elem)((char *)(queue)->data + \
|
|
|
|
(__u_vector_offset & ((queue)->size - 1))), \
|
|
|
|
__u_vector_offset != (queue)->head; \
|
2016-10-14 03:55:03 +01:00
|
|
|
__u_vector_offset += (queue)->element_size)
|
|
|
|
|
2020-01-16 23:05:06 +00:00
|
|
|
#ifdef __cplusplus
|
|
|
|
}
|
|
|
|
#endif
|
2016-10-14 03:55:03 +01:00
|
|
|
|
|
|
|
#endif
|
|
|
|
|