Browse Source

android: debug categories from GUI, fix poll log format, event loop sleeps until traffic

- android_jni_bridge: utun_bridge_set_debug_level actually calls debug_set_level / debug_set_category_level_by_name (was stub)
- SettingsScreen: CATEGORIES updated to match current g_debug_categories from debug_config.c
- ConfigProvider: persist category levels in [debug] section of generated INI config
- u_async: poll() log uses computed timeout_ms instead of confusing %d.%dms format
- u_async: timeout_node char name[16] → const char* name (no truncation, smaller struct)
- memory_pool: pool alloc/free debug logs moved from DEBUG to TRACE
- instance_lite: poll timeout changed from 10ms (100tb) to infinite (-1) — sleeps until traffic
- instance_lite: removed useless heartbeat timer
topo_upd
evgeny 2 months ago
parent
commit
5d02a6d419
  1. 8
      lib/memory_pool.c
  2. 40
      lib/u_async.c
  3. 7
      tools/chatgui-android/app/src/main/java/com/utun/chat/data/ConfigProvider.kt
  4. 9
      tools/chatgui-android/app/src/main/java/com/utun/chat/ui/screens/SettingsScreen.kt
  5. 8
      tools/chatgui-android/jni_bridge/android_jni_bridge.c
  6. 13
      tools/chatgui-android/libutun_lite/instance_lite.c

8
lib/memory_pool.c

@ -84,12 +84,12 @@ void* memory_pool_alloc_impl(struct memory_pool* pool, const char* location) {
pool->reuse_count++;
memset(obj, 0, pool->object_size);
pool_init_tags(pool, obj, location);
DEBUG_DEBUG(DEBUG_CATEGORY_SYS, "pool_alloc reused: %s, remaining=%zu", location, pool->free_count);
DEBUG_TRACE(DEBUG_CATEGORY_SYS, "pool_alloc reused: %s, remaining=%zu", location, pool->free_count);
return obj;
}
pool->allocations++;
DEBUG_DEBUG(DEBUG_CATEGORY_SYS, "pool_alloc: %s, total_allocs=%zu", location, pool->allocations);
DEBUG_TRACE(DEBUG_CATEGORY_SYS, "pool_alloc: %s, total_allocs=%zu", location, pool->allocations);
void* obj = u_calloc_impl(1, POOL_ALLOC_SIZE, location);
if (obj) pool_init_tags(pool, obj, location);
return obj;
@ -108,11 +108,11 @@ void memory_pool_free_impl(struct memory_pool* pool, void* obj, const char* loca
pool->free_head = obj;
pool->free_count++;
g_total_free++;
DEBUG_DEBUG(DEBUG_CATEGORY_SYS, "pool_free returned: %s, free_count=%zu", location, pool->free_count);
DEBUG_TRACE(DEBUG_CATEGORY_SYS, "pool_free returned: %s, free_count=%zu", location, pool->free_count);
return;
}
DEBUG_DEBUG(DEBUG_CATEGORY_SYS, "pool_free direct: %s", location);
DEBUG_TRACE(DEBUG_CATEGORY_SYS, "pool_free direct: %s", location);
u_free_impl(obj, location);
}

40
lib/u_async.c

@ -33,7 +33,7 @@
// Timeout node with safe cancellation
struct timeout_node {
char name[16];
const char* name;
void* arg;
timeout_callback_t callback;
uint64_t expiration_ms; // absolute expiration time in milliseconds
@ -450,7 +450,7 @@ void process_immediate_queue(struct UASYNC* ua) {
if (!ua->immediate_queue_head) ua->immediate_queue_tail = NULL;
if (node && node->callback) {
DEBUG_DEBUG(DEBUG_CATEGORY_SYS, "timer→immediate %s", node->name[0] ? node->name : "");
DEBUG_DEBUG(DEBUG_CATEGORY_SYS, "timer→immediate %s", node->name);
node->callback(node->arg);
}
@ -485,7 +485,7 @@ static void process_timeouts(struct UASYNC* ua) {
struct timeout_node* node = (struct timeout_node*)entry.data;
if (node && node->callback) {
DEBUG_DEBUG(DEBUG_CATEGORY_SYS, "timer→%s expired", node->name[0] ? node->name : "");
DEBUG_DEBUG(DEBUG_CATEGORY_SYS, "timer→%s expired", node->name);
node->callback(node->arg);
}
@ -545,10 +545,9 @@ void* uasync_set_timeout(struct UASYNC* ua, int timeout_tb, void* arg, timeout_c
ua->timer_alloc_count++;
if (name) {
strncpy(node->name, name, sizeof(node->name) - 1);
node->name[sizeof(node->name) - 1] = '\0';
node->name = name;
} else {
node->name[0] = '\0';
node->name = "";
}
node->arg = arg;
node->callback = callback;
@ -591,7 +590,7 @@ void* uasync_call_soon(struct UASYNC* ua, void* user_arg, timeout_callback_t cal
}
ua->timer_alloc_count++;
node->name[0] = '\0';
node->name = "";
node->arg = user_arg;
node->callback = callback;
node->ua = ua;
@ -1002,24 +1001,18 @@ void uasync_poll(struct UASYNC* ua, int timeout_tb) {
(unsigned long long)(now_us_poll_entry - ua->last_poll_exit_us));
}
DEBUG_DEBUG(DEBUG_CATEGORY_SYS, "poll(%d sockets, %zu timers, timeout=%d.%dms)",
ua->sockets->count, ua->timeout_heap->size, timeout_tb >= 0 ? timeout_tb / 10000 : -1,
timeout_tb >= 0 ? (timeout_tb % 10000) / 10 : 0);
// Handle negative or zero timeout
if (timeout_tb < 0) timeout_tb = -1; // Infinite wait
else if (timeout_tb == 0) timeout_tb = 0; // No wait
// Get next timeout
if (timeout_tb < 0) timeout_tb = -1;
else if (timeout_tb == 0) timeout_tb = 0;
struct timeval next_timeout;
get_next_timeout(ua, &next_timeout);
// Convert requested timeout to timeval
struct timeval req_timeout = {0};
if (timeout_tb >= 0) {
req_timeout.tv_sec = timeout_tb / 10000;
req_timeout.tv_usec = (timeout_tb % 10000) * 100;
}
struct timeval poll_timeout;
if (timeout_tb < 0) {
poll_timeout = next_timeout;
@ -1033,28 +1026,27 @@ void uasync_poll(struct UASYNC* ua, int timeout_tb) {
}
if (poll_timeout.tv_sec == 0 && poll_timeout.tv_usec == 0 && timeout_tb > 0) poll_timeout = req_timeout;
int timeout_ms;
if (timeout_tb < 0 && (next_timeout.tv_sec > 0 || next_timeout.tv_usec > 0)) {
timeout_ms = (int)timeval_to_ms(&poll_timeout);
} else if (timeout_tb < 0) {
timeout_ms = -1; // Infinite
timeout_ms = -1;
} else {
timeout_ms = (int)timeval_to_ms(&poll_timeout);
}
// Count active sockets
int socket_count = ua->sockets->count;
if (socket_count == 0 && timeout_ms == -1) {
// No sockets and infinite wait - but we have timers? Wait for timer
if (ua->timeout_heap->size > 0) {
timeout_ms = (int)timeval_to_ms(&poll_timeout);
} else {
// Nothing to do - return immediately
ua->last_poll_exit_us = get_time_us();
return;
}
}
DEBUG_DEBUG(DEBUG_CATEGORY_SYS, "poll(%d sockets, %zu timers, timeout=%dms)",
socket_count, ua->timeout_heap->size, timeout_ms);
#if HAS_EPOLL
// Use epoll on Linux if available

7
tools/chatgui-android/app/src/main/java/com/utun/chat/data/ConfigProvider.kt

@ -339,6 +339,13 @@ class ConfigProvider(private val context: Context) {
appendLine()
appendLine("[debug]")
appendLine("console_level=info")
val dbgCat = getString("debug.categories") ?: ""
if (dbgCat.isNotEmpty()) {
for (entry in dbgCat.split(",")) {
val trimmed = entry.trim()
if (trimmed.isNotEmpty()) appendLine(trimmed)
}
}
val udpIp = getString("log_udp.ip") ?: ""
val udpPort = getInt("log_udp.port")
if (udpIp.isNotEmpty() && udpPort > 0) {

9
tools/chatgui-android/app/src/main/java/com/utun/chat/ui/screens/SettingsScreen.kt

@ -28,10 +28,11 @@ import java.util.UUID
private val LEVELS = listOf("NONE", "ERROR", "WARN", "INFO", "DEBUG", "TRACE")
private val CATEGORIES = listOf(
"UASYNC", "LL_QUEUE", "CONNECTION", "ETCP", "CRYPTO", "MEMORY",
"TIMING", "CONFIG", "TUN", "ROUTING", "TIMERS", "NORMALIZER", "BGP",
"SOCKET", "CONTROL", "DUMP", "TRAFFIC", "DEBUG", "GENERAL", "NAT",
"KEEPALIVE", "ETCPROUTE", "BBR", "ETCP_DUMP", "CONNECTIVITY", "DB_SYNC"
"sys", "connection", "etcp", "crypto",
"config", "tun", "routing", "timers", "bgp", "chat",
"socket", "control", "dump", "traffic", "debug", "general",
"nat", "keepalive", "media", "etcp_route", "etcp_dump",
"chat_sync", "member_sync", "proxy"
)
private val PROTOCOLS = listOf("tcp", "udp")

8
tools/chatgui-android/jni_bridge/android_jni_bridge.c

@ -676,7 +676,13 @@ uint64_t utun_bridge_get_my_node_id(void) {
}
void utun_bridge_set_debug_level(const char* category, const char* level) {
bridge_log(BLEV_INFO, "debug %s=%s", category ? category : "all", level ? level : "info");
if (!level) return;
if (!category || !category[0]) {
debug_level_t lvl = debug_level_from_name(level);
debug_set_level(lvl);
} else {
debug_set_category_level_by_name(category, level);
}
}
void utun_bridge_chat_setting_set(const char* name, const char* value) {

13
tools/chatgui-android/libutun_lite/instance_lite.c

@ -219,12 +219,6 @@ static void install_crash_handlers(void) {
sigaction(SIGBUS, &sa, NULL);
}
static void heartbeat_cb(void* arg) {
(void)arg;
DEBUG_INFO(DEBUG_CATEGORY_GENERAL, "heartbeat alive");
uasync_set_timeout(g_ua, 100000, NULL, heartbeat_cb, "hb");
}
/* ── Thread function ── */
static void* instance_thread(void* arg) {
@ -322,10 +316,8 @@ static void* instance_thread(void* arg) {
uasync_mark_running(g_ua);
chat_event_post(CHAT_EVT_SERVICE_STARTED, NULL, 0);
uasync_set_timeout(g_ua, 100000, NULL, heartbeat_cb, "hb");
while (!__atomic_load_n(&g_stop, __ATOMIC_ACQUIRE)) {
uasync_poll(g_ua, 100);
uasync_poll(g_ua, -1);
}
while (__atomic_load_n(&g_do_restart, __ATOMIC_ACQUIRE)) {
@ -380,13 +372,12 @@ static void* instance_thread(void* arg) {
etcp_add_link_status_cbk(g_inst, on_link_status_changed, NULL);
chat_event_post(CHAT_EVT_KEYS_GENERATED, (const uint8_t*)config->global.my_public_key_hex, 64);
uasync_set_timeout(g_ua, 100000, NULL, heartbeat_cb, "hb");
__atomic_store_n(&g_running, 1, __ATOMIC_RELEASE);
uasync_mark_running(g_ua);
chat_event_post(CHAT_EVT_SERVICE_STARTED, NULL, 0);
IL_LOGI("poll exit: restart done, entering new poll loop");
while (!__atomic_load_n(&g_stop, __ATOMIC_ACQUIRE)) uasync_poll(g_ua, 100);
while (!__atomic_load_n(&g_stop, __ATOMIC_ACQUIRE)) uasync_poll(g_ua, -1);
}
IL_LOGI("poll exit: final cleanup");

Loading…
Cancel
Save