Files
Server_Monitor/code/lib/queue.h

94 lines
2.2 KiB
C
Raw Normal View History

2023-09-26 19:40:16 +02:00
#ifndef _PIUMA_LIB_QUEUE_H_
#define _PIUMA_LIB_QUEUE_H_
#include "types.h"
#include <assert.h>
struct queue_header
{
u64 start;
u64 size;
u64 capacity;
};
#define QUEUE_HEADER_PTR(queue) ((queue_header *)(((u8*)queue) - sizeof(queue_header)))
#define QUEUE_TYPE(type) type *
#define Queue_Alloc(alloc_func, type, capacity) ((type*) _queue_alloc(alloc_func, sizeof(type), capacity))
#define Queue_Free(free_func, queue) free_func(QUEUE_HEADER_PTR(queue))
#define Queue_Pop(queue) (queue[_queue_pop_index((u8*)queue)])
#define Queue_Push(queue, element) { queue[_queue_at_index((u8*)queue, QUEUE_HEADER_PTR(queue)->size)] = element; _queue_push_fix_indices((u8*)queue); }
#define Queue_At(queue, index) (queue[_queue_at_index((u8*)queue, index)])
#define Queue_Size(queue) _queue_size((u8*)queue)
#define Queue_Capacity(queue) _queue_capacity((u8*)queue)
typedef void * (*alloc_func_t)(u64);
typedef void (*free_func_t)(void *);
inline u8 * _queue_alloc(alloc_func_t alloc_func, u64 sizeof_type, u64 capacity)
{
u8 *data;
queue_header *header;
data = (u8 *)alloc_func(sizeof(queue_header) + sizeof_type * capacity);
header = (queue_header *)data;
header->capacity = capacity;
header->start = 0;
header->size = 0;
return data + sizeof(queue_header);
}
inline u64 _queue_pop_index(u8 *queue)
{
queue_header *header = QUEUE_HEADER_PTR(queue);
assert(header->size > 0);
u64 element_index = header->start;
header->start = (header->start + 1) % header->capacity;
header->size--;
return element_index;
}
inline void _queue_push_fix_indices(u8 *queue)
{
queue_header *header = QUEUE_HEADER_PTR(queue);
header->size++;
if(header->size > header->capacity)
{
// Queue is full. Remove oldest element
header->start = (header->start + 1) % header->capacity;
header->size = header->capacity;
}
}
inline u64 _queue_at_index(u8 *queue, u64 index)
{
queue_header *header = QUEUE_HEADER_PTR(queue);
return (header->start + index) % header->capacity;
}
inline u64 _queue_size(u8 *queue)
{
queue_header *header = QUEUE_HEADER_PTR(queue);
return header->size;
}
inline u64 _queue_capacity(u8 *queue)
{
queue_header *header = QUEUE_HEADER_PTR(queue);
return header->capacity;
}
#endif