You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
85 lines
2.6 KiB
85 lines
2.6 KiB
#include "packet_pool.h" |
|
#include "packet_buffer.h" |
|
#include <stdlib.h> |
|
#include <string.h> |
|
#include <stdio.h> |
|
|
|
void packet_pool_init(struct packet_pool* pool) { |
|
pool->free_count = 0; |
|
pool->allocations = 0; |
|
pool->reuse_count = 0; |
|
pool->overflow_count = 0; |
|
memset(pool->free_list, 0, sizeof(pool->free_list)); |
|
|
|
// Предварительно аллоцируем пакеты |
|
for (int i = 0; i < PACKET_POOL_SIZE / 2; i++) { |
|
struct packet_buffer* pkt = calloc(1, PACKET_TOTAL_SIZE); |
|
if (pkt) { |
|
pool->free_list[pool->free_count++] = pkt; |
|
} |
|
} |
|
} |
|
|
|
struct packet_buffer* packet_pool_get(struct packet_pool* pool) { |
|
pool->allocations++; |
|
|
|
// Если есть свободные пакеты в пуле, использовать их |
|
if (pool->free_count > 0) { |
|
pool->reuse_count++; |
|
pool->free_count--; |
|
struct packet_buffer* pkt = pool->free_list[pool->free_count]; |
|
pool->free_list[pool->free_count] = NULL; |
|
|
|
// Инициализировать метаданные |
|
packet_init(pkt); |
|
pkt->next_free = NULL; |
|
|
|
return pkt; |
|
} |
|
|
|
// Иначе выделить через malloc |
|
pool->overflow_count++; |
|
struct packet_buffer* pkt = calloc(1, PACKET_TOTAL_SIZE); |
|
if (pkt) { |
|
packet_init(pkt); |
|
} |
|
|
|
return pkt; |
|
} |
|
|
|
void packet_pool_put(struct packet_pool* pool, struct packet_buffer* pkt) { |
|
if (!pkt) return; |
|
|
|
// Если пул не заполнен, сохранить пакет для повторного использования |
|
if (pool->free_count < PACKET_POOL_SIZE) { |
|
pool->free_list[pool->free_count] = pkt; |
|
pool->free_count++; |
|
return; |
|
} |
|
|
|
// Иначе освободить через free (переполнение) |
|
free(pkt); |
|
} |
|
|
|
void packet_pool_get_stats(const struct packet_pool* pool, |
|
size_t* allocations, |
|
size_t* reuse_count, |
|
size_t* overflow_count) { |
|
if (allocations) *allocations = pool->allocations; |
|
if (reuse_count) *reuse_count = pool->reuse_count; |
|
if (overflow_count) *overflow_count = pool->overflow_count; |
|
} |
|
|
|
void packet_pool_destroy(struct packet_pool* pool) { |
|
// Освободить все пакеты в пуле |
|
for (int i = 0; i < pool->free_count; i++) { |
|
if (pool->free_list[i]) { |
|
free(pool->free_list[i]); |
|
pool->free_list[i] = NULL; |
|
} |
|
} |
|
pool->free_count = 0; |
|
pool->allocations = 0; |
|
pool->reuse_count = 0; |
|
pool->overflow_count = 0; |
|
} |