Browse Source

GUI: add active timeouts and busy memory blocks counters

- Add timeout_heap_get_size() to get active timer count
- Add global counters in memory_pool: g_total_free and g_total_allocated
- Simplify busy memory calculation to single formula:
  busy = memory_pool_get_total_allocated() - memory_pool_get_total_free_blocks()
- Add new IDC_EDIT_ACTIVE_TIMEOUTS and IDC_EDIT_BUSY_MEMORY to GUI
congestion
Evgeny 5 months ago
parent
commit
cee9a04348
  1. 16
      lib/memory_pool.c
  2. 2
      lib/memory_pool.h
  3. 13
      lib/timeout_heap.c
  4. 2
      lib/timeout_heap.h
  5. 11
      src/control_server.c
  6. 18
      tools/etcpmon/etcpmon_gui.c
  7. 8
      tools/etcpmon/etcpmon_gui.h
  8. 4
      tools/etcpmon/etcpmon_protocol.h

16
lib/memory_pool.c

@ -5,6 +5,17 @@
#include "memory_pool.h" #include "memory_pool.h"
#include "mem.h" #include "mem.h"
static size_t g_total_free = 0;
static size_t g_total_allocated = 0;
size_t memory_pool_get_total_free_blocks(void) {
return g_total_free;
}
size_t memory_pool_get_total_allocated(void) {
return g_total_allocated;
}
// Инициализировать пул памяти // Инициализировать пул памяти
struct memory_pool* memory_pool_init(size_t object_size) { struct memory_pool* memory_pool_init(size_t object_size) {
struct memory_pool* pool = u_calloc(1, sizeof(struct memory_pool)); struct memory_pool* pool = u_calloc(1, sizeof(struct memory_pool));
@ -29,6 +40,7 @@ void* memory_pool_alloc_impl(struct memory_pool* pool, const char* location) {
void* obj = pool->free_head; void* obj = pool->free_head;
pool->free_head = *(void**)obj; // Извлекаем next из начала блока pool->free_head = *(void**)obj; // Извлекаем next из начала блока
pool->free_count--; pool->free_count--;
g_total_free--;
pool->reuse_count++; pool->reuse_count++;
memset(obj, 0, pool->object_size); // Опционально: очищаем память для безопасности memset(obj, 0, pool->object_size); // Опционально: очищаем память для безопасности
DEBUG_INFO(DEBUG_CATEGORY_MEMORY, "pool_alloc reused: %s, remaining=%zu", location, pool->free_count); DEBUG_INFO(DEBUG_CATEGORY_MEMORY, "pool_alloc reused: %s, remaining=%zu", location, pool->free_count);
@ -36,6 +48,7 @@ void* memory_pool_alloc_impl(struct memory_pool* pool, const char* location) {
} }
pool->allocations++; pool->allocations++;
g_total_allocated++;
DEBUG_INFO(DEBUG_CATEGORY_MEMORY, "pool_alloc: %s, total_allocs=%zu", location, pool->allocations); DEBUG_INFO(DEBUG_CATEGORY_MEMORY, "pool_alloc: %s, total_allocs=%zu", location, pool->allocations);
return u_calloc_impl(1, pool->object_size, location); // Используем calloc для инициализации нулями return u_calloc_impl(1, pool->object_size, location); // Используем calloc для инициализации нулями
} }
@ -51,6 +64,7 @@ void memory_pool_free_impl(struct memory_pool* pool, void* obj, const char* loca
*(void**)obj = pool->free_head; // Сохраняем next в начало блока *(void**)obj = pool->free_head; // Сохраняем next в начало блока
pool->free_head = obj; pool->free_head = obj;
pool->free_count++; pool->free_count++;
g_total_free++;
DEBUG_INFO(DEBUG_CATEGORY_MEMORY, "pool_free returned: %s, free_count=%zu", location, pool->free_count); DEBUG_INFO(DEBUG_CATEGORY_MEMORY, "pool_free returned: %s, free_count=%zu", location, pool->free_count);
return; return;
} }
@ -84,6 +98,8 @@ void memory_pool_destroy(struct memory_pool* pool) {
void* obj = pool->free_head; void* obj = pool->free_head;
while (obj) { while (obj) {
void* next = *(void**)obj; void* next = *(void**)obj;
g_total_free--;
g_total_allocated--;
u_free(obj); u_free(obj);
cnt++; cnt++;
obj = next; obj = next;

2
lib/memory_pool.h

@ -28,6 +28,8 @@ void memory_pool_destroy(struct memory_pool* pool);
void* memory_pool_alloc_impl(struct memory_pool* pool, const char* location); void* memory_pool_alloc_impl(struct memory_pool* pool, const char* location);
void memory_pool_free_impl(struct memory_pool* pool, void* obj, const char* location); void memory_pool_free_impl(struct memory_pool* pool, void* obj, const char* location);
void memory_pool_get_stats(struct memory_pool* pool, size_t* allocations, size_t* reuse_count); void memory_pool_get_stats(struct memory_pool* pool, size_t* allocations, size_t* reuse_count);
size_t memory_pool_get_total_free_blocks(void);
size_t memory_pool_get_total_allocated(void);
#define memory_pool_alloc(pool) memory_pool_alloc_impl(pool, PLOCATION) #define memory_pool_alloc(pool) memory_pool_alloc_impl(pool, PLOCATION)
#define memory_pool_free(pool, obj) memory_pool_free_impl(pool, obj, PLOCATION) #define memory_pool_free(pool, obj) memory_pool_free_impl(pool, obj, PLOCATION)

13
lib/timeout_heap.c

@ -159,8 +159,13 @@ int timeout_heap_cancel(TimeoutHeap *h, TimeoutTime expiration, void *data) {
return -1; // Not found return -1; // Not found
} }
void timeout_heap_set_free_callback(TimeoutHeap *h, void* user_data, void (*callback)(void* user_data, void* data)) { void timeout_heap_set_free_callback(TimeoutHeap *h, void* user_data, void (*callback)(void* user_data, void* data)) {
if (!h) return; if (!h) return;
h->user_data = user_data; h->user_data = user_data;
h->free_callback = callback; h->free_callback = callback;
} }
size_t timeout_heap_get_size(TimeoutHeap *h) {
if (!h) return 0;
return h->size;
}

2
lib/timeout_heap.h

@ -89,4 +89,6 @@ int timeout_heap_cancel(TimeoutHeap *h, TimeoutTime expiration, void *data);
*/ */
size_t timeout_heap_get_freed_count(TimeoutHeap *h); size_t timeout_heap_get_freed_count(TimeoutHeap *h);
size_t timeout_heap_get_size(TimeoutHeap *h);
#endif // TIMEOUT_HEAP_H #endif // TIMEOUT_HEAP_H

11
src/control_server.c

@ -14,6 +14,8 @@
#include "pkt_normalizer.h" #include "pkt_normalizer.h"
#include "../tools/etcpmon/etcpmon_protocol.h" #include "../tools/etcpmon/etcpmon_protocol.h"
#include "../lib/u_async.h" #include "../lib/u_async.h"
#include "../lib/timeout_heap.h"
#include "../lib/memory_pool.h"
#include "../lib/debug_config.h" #include "../lib/debug_config.h"
#include "../lib/mem.h" #include "../lib/mem.h"
#include "../lib/ll_queue.h" #include "../lib/ll_queue.h"
@ -971,6 +973,15 @@ static void send_metrics(struct control_server* server, struct control_client* c
for (int i = 0; i < 8; i++) { for (int i = 0; i < 8; i++) {
rsp->etcp.debug[i] = conn->debug[i]; rsp->etcp.debug[i] = conn->debug[i];
} }
/* System resources */
if (instance->ua && instance->ua->timeout_heap) {
rsp->etcp.active_timeouts = (uint32_t)timeout_heap_get_size(instance->ua->timeout_heap);
} else {
rsp->etcp.active_timeouts = 0;
}
rsp->etcp.busy_memory_blocks = (uint32_t)(memory_pool_get_total_allocated() - memory_pool_get_total_free_blocks());
/* Fill TUN metrics */ /* Fill TUN metrics */
if (instance->tun) { if (instance->tun) {

18
tools/etcpmon/etcpmon_gui.c

@ -548,6 +548,20 @@ static void CreateControls(struct etcpmon_app* app) {
app->hEditTimerAckResp = CreateWindowExA(WS_EX_CLIENTEDGE, "EDIT", "", app->hEditTimerAckResp = CreateWindowExA(WS_EX_CLIENTEDGE, "EDIT", "",
WS_CHILD | WS_VISIBLE | ES_READONLY | ES_CENTER, WS_CHILD | WS_VISIBLE | ES_READONLY | ES_CENTER,
q_col2 + 110, qy - 2, 50, 18, hWnd, (HMENU)IDC_EDIT_TIMER_ACK_RESP, hInst, NULL); q_col2 + 110, qy - 2, 50, 18, hWnd, (HMENU)IDC_EDIT_TIMER_ACK_RESP, hInst, NULL);
/* System resources - below timer flags */
qy += 28;
CreateWindowExA(0, "STATIC", "Timeouts:",
WS_CHILD | WS_VISIBLE, q_col1, qy, 60, 16, hWnd, (HMENU)IDC_STATIC, hInst, NULL);
app->hEditActiveTimeouts = CreateWindowExA(WS_EX_CLIENTEDGE, "EDIT", "",
WS_CHILD | WS_VISIBLE | ES_READONLY | ES_CENTER,
q_col1 + 65, qy - 2, 50, 18, hWnd, (HMENU)IDC_EDIT_ACTIVE_TIMEOUTS, hInst, NULL);
CreateWindowExA(0, "STATIC", "Memory:",
WS_CHILD | WS_VISIBLE, q_col2, qy, 50, 16, hWnd, (HMENU)IDC_STATIC, hInst, NULL);
app->hEditBusyMemory = CreateWindowExA(WS_EX_CLIENTEDGE, "EDIT", "",
WS_CHILD | WS_VISIBLE | ES_READONLY | ES_CENTER,
q_col2 + 60, qy - 2, 60, 18, hWnd, (HMENU)IDC_EDIT_BUSY_MEMORY, hInst, NULL);
/* WaitAck queue state */ /* WaitAck queue state */
qy += 30; qy += 30;
@ -1088,6 +1102,10 @@ void etcpmon_gui_update_metrics(struct etcpmon_app* app,
for (int i = 0; i < 8; i++) { for (int i = 0; i < 8; i++) {
UpdateEditIfChanged(hMain, IDC_EDIT_DEBUG_0 + i, "%u", metrics->etcp.debug[i]); UpdateEditIfChanged(hMain, IDC_EDIT_DEBUG_0 + i, "%u", metrics->etcp.debug[i]);
} }
/* System resources */
UpdateEditIfChanged(hMain, IDC_EDIT_ACTIVE_TIMEOUTS, "%u", metrics->etcp.active_timeouts);
UpdateEditIfChanged(hMain, IDC_EDIT_BUSY_MEMORY, "%u", metrics->etcp.busy_memory_blocks);
/* Links list */ /* Links list */
if (app->hListLinks) { if (app->hListLinks) {

8
tools/etcpmon/etcpmon_gui.h

@ -146,6 +146,10 @@ extern "C" {
#define IDC_EDIT_DEBUG_6 692 #define IDC_EDIT_DEBUG_6 692
#define IDC_EDIT_DEBUG_7 693 #define IDC_EDIT_DEBUG_7 693
/* System resources IDs */
#define IDC_EDIT_ACTIVE_TIMEOUTS 700
#define IDC_EDIT_BUSY_MEMORY 701
/* Graph control ID */ /* Graph control ID */
#define IDC_GRAPH 500 #define IDC_GRAPH 500
@ -284,6 +288,10 @@ struct etcpmon_app {
HWND hEditCntLinkWait; HWND hEditCntLinkWait;
HWND hEditTxState; HWND hEditTxState;
HWND hEditDebug[8]; HWND hEditDebug[8];
/* System resources */
HWND hEditActiveTimeouts;
HWND hEditBusyMemory;
/* Graph controls */ /* Graph controls */
HWND hGraphWnd; HWND hGraphWnd;

4
tools/etcpmon/etcpmon_protocol.h

@ -192,6 +192,10 @@ struct etcpmon_etcp_metrics {
uint32_t cnt_link_wait; uint32_t cnt_link_wait;
uint32_t tx_state; uint32_t tx_state;
uint32_t debug[8]; uint32_t debug[8];
/* System resources */
uint32_t active_timeouts;
uint32_t busy_memory_blocks;
}; };
/* Link metrics */ /* Link metrics */

Loading…
Cancel
Save