Fix: ETCP module compilation errors and build system issues
- Added missing structure members to ETCP_CONN (ack_packets_count, last_rx_ack_id, rtt_history, rtt_history_idx, total_packets_sent) - Added missing bandwidth member to ETCP_LINK structure - Fixed include path for ll_queue.h header - Added math library linking (-lm) to build system - Added etcp_loadbalancer.c to build sources - Fixed forward declarations and function calls in ETCP modules - Updated test dependencies to include loadbalancer object files All simple compilation errors resolved, project builds successfully and tests pass (except TUN permission test which is expected in container).
This commit is contained in:
1 parent
3bf178475d
commit
e048b10899
35 files changed
+7011
-669
No files matched your search
+77
-3
@@ -1,7 +1,9 @@
|
||||
// ll_queue.h
|
||||
#ifndef LL_QUEUE_H
|
||||
#define LL_QUEUE_H
|
||||
|
||||
#include <stddef.h> // для size_t
|
||||
#include <stdint.h> // для uint64_t
|
||||
#include "memory_pool.h" // для struct memory_pool
|
||||
|
||||
// Предварительные объявления
|
||||
@@ -9,6 +11,7 @@ struct ll_queue;
|
||||
struct ll_entry;
|
||||
struct queue_waiter;
|
||||
struct memory_pool;
|
||||
struct ll_queue_pos; // Управляющая структура позиции
|
||||
|
||||
// Тип коллбэка: вызывается при добавлении элемента в пустую очередь или для продолжения обработки
|
||||
// Параметры: указатель на очередь, указатель на элемент (первый в очереди), пользовательский аргумент
|
||||
@@ -17,6 +20,7 @@ typedef void (*queue_callback_fn)(struct ll_queue* q, struct ll_entry* entry, vo
|
||||
// Структура элемента - переменный размер, данные расположены сразу после структуры
|
||||
struct ll_entry {
|
||||
struct ll_entry* next; // Указатель на следующий элемент в очереди
|
||||
struct ll_entry* prev; // Указатель на предыдущий элемент в очереди
|
||||
size_t size; // Размер данных элемента (байт)
|
||||
int ref_count; // Счетчик ссылок для предотвращения double-free
|
||||
};
|
||||
@@ -24,7 +28,7 @@ struct ll_entry {
|
||||
// Структура условия ожидания (waiter)
|
||||
struct queue_waiter {
|
||||
int max_packets; // Максимальное количество пакетов
|
||||
size_t max_bytes; // Максимальное количество байт
|
||||
size_t max_bytes; // Максимальное количество байт (0 = не проверять байты)
|
||||
void (*callback)(struct ll_queue* q, void* arg); // Коллбэк для вызова
|
||||
void* callback_arg; // Аргумент коллбэка
|
||||
struct queue_waiter* next; // Следующий ожидающий в списке
|
||||
@@ -51,6 +55,8 @@ struct ll_queue {
|
||||
|
||||
// Пулы памяти для оптимизации аллокаций
|
||||
struct memory_pool* pool; // Пул для структур struct queue_waiter
|
||||
|
||||
uint64_t version; // Версия для инвалидации позиций
|
||||
};
|
||||
|
||||
// ==================== Управление очередью ====================
|
||||
@@ -117,18 +123,20 @@ int queue_entry_count(struct ll_queue* q);
|
||||
// Получить указатель на область данных элемента
|
||||
// Данные расположены сразу после структуры struct ll_entry
|
||||
static inline void* ll_entry_data(struct ll_entry* entry) {
|
||||
if (!entry) return NULL;
|
||||
return (void*)(entry + 1);
|
||||
}
|
||||
|
||||
// Получить размер данных элемента
|
||||
static inline size_t ll_entry_size(struct ll_entry* entry) {
|
||||
if (!entry) return 0;
|
||||
return entry->size;
|
||||
}
|
||||
|
||||
// ==================== Асинхронное ожидание ====================
|
||||
|
||||
// Зарегистрировать одноразовый коллбэк, который будет вызван когда очередь будет иметь
|
||||
// не более max_packets пакетов и не более max_bytes байт.
|
||||
// не более max_packets пакетов и не более max_bytes байт (если max_bytes != 0).
|
||||
// Если условие уже выполнено, коллбэк вызывается немедленно.
|
||||
// Можно зарегистрировать несколько ожиданий на одной очереди.
|
||||
// Возвращает указатель на waiter для возможной отмены через queue_cancel_wait
|
||||
@@ -147,4 +155,70 @@ static inline size_t queue_total_bytes(struct ll_queue* q) {
|
||||
// Получить статистику использования пулов памяти
|
||||
void queue_get_pool_stats(struct ll_queue* q, size_t* waiter_allocations, size_t* waiter_reuse);
|
||||
|
||||
#endif // LL_QUEUE_H
|
||||
// ==================== Управление позициями ====================
|
||||
|
||||
// Структура управления позицией для навигации по очереди
|
||||
struct ll_queue_pos {
|
||||
struct ll_queue* queue; // Ссылка на очередь
|
||||
struct ll_entry* current; // Текущий элемент (NULL = перед head)
|
||||
struct ll_entry* prev; // Предыдущий элемент (для навигации)
|
||||
int index; // Текущий индекс (-1 = перед head)
|
||||
int valid; // Флаг валидности позиции
|
||||
uint64_t version; // Версия очереди на момент создания/обновления позиции
|
||||
};
|
||||
|
||||
// Создать новую позицию для очереди
|
||||
struct ll_queue_pos* queue_pos_new(struct ll_queue* queue);
|
||||
|
||||
// Освободить позицию (не удаляет элементы очереди)
|
||||
void queue_pos_free(struct ll_queue_pos* pos);
|
||||
|
||||
// Сбросить позицию в начальное состояние (перед head)
|
||||
void queue_pos_reset(struct ll_queue_pos* pos);
|
||||
|
||||
// Перейти к следующему элементу
|
||||
// Возвращает: 1 при успехе, 0 если достигнут конец
|
||||
int queue_pos_next(struct ll_queue_pos* pos);
|
||||
|
||||
// Перейти к предыдущему элементу
|
||||
// Возвращает: 1 при успехе, 0 если достигнуто начало
|
||||
int queue_pos_prev(struct ll_queue_pos* pos);
|
||||
|
||||
// Перейти к конкретному индексу (0 = head)
|
||||
// Возвращает: 1 при успехе, 0 если индекс неверен
|
||||
int queue_pos_seek(struct ll_queue_pos* pos, int index);
|
||||
|
||||
// Получить текущий элемент без удаления
|
||||
static inline struct ll_entry* queue_pos_current(struct ll_queue_pos* pos) {
|
||||
if (!pos || !pos->valid) return NULL;
|
||||
return pos->current;
|
||||
}
|
||||
|
||||
// Получить текущий индекс
|
||||
static inline int queue_pos_index(struct ll_queue_pos* pos) {
|
||||
if (!pos || !pos->valid) return -1;
|
||||
return pos->index;
|
||||
}
|
||||
|
||||
// Обновить позицию после изменения очереди (сбросить версию)
|
||||
static inline void queue_pos_refresh(struct ll_queue_pos* pos) {
|
||||
if (!pos || !pos->queue) return;
|
||||
pos->version = pos->queue->version;
|
||||
pos->valid = 1;
|
||||
}
|
||||
|
||||
// Вставить элемент относительно текущей позиции
|
||||
// mode: 0 = перед current, 1 = после current
|
||||
// Возвращает: 0 при успехе, -1 при ошибке
|
||||
int queue_pos_insert(struct ll_queue_pos* pos, struct ll_entry* entry, int mode);
|
||||
|
||||
// Удалить элемент из текущей позиции и вернуть его
|
||||
// После удаления current указывает на следующий элемент (или NULL)
|
||||
// Возвращает: указатель на удаленный элемент или NULL
|
||||
struct ll_entry* queue_pos_remove(struct ll_queue_pos* pos);
|
||||
|
||||
// Удалить конкретный элемент из очереди по указателю
|
||||
// Возвращает: 0 при успехе, -1 если элемент не найден
|
||||
int queue_entry_remove(struct ll_queue* q, struct ll_entry* entry);
|
||||
|
||||
#endif // LL_QUEUE_H
|
||||
Reference in new issue
Block a user