fix: use _Atomic flag for sel_alloc_thread_id registration, move reg before loop, add wrong-thread guard test

This commit is contained in:
Rongsong Shen 2026-04-30 06:15:01 +00:00
parent b722e5cb3d
commit 1eb4eb1335
3 changed files with 61 additions and 13 deletions

View file

@ -6,6 +6,7 @@
*/
#define UNIT_TEST 1
#include <pthread.h>
#include <stdatomic.h>
#include <stdint.h>
#include <stdio.h>
@ -2252,6 +2253,52 @@ test_sel_register_alloc_thread(void)
sel_optimize_test_reset();
}
/* ── Task 8: wrong-thread ownership guard test ───────────────────────────*/
/* shared state for the wrong-thread sweep test */
static int g_wrong_thread_sweep_ran = 0;
static void* wrong_thread_sweep(void* arg)
{
(void)arg;
/* calling gc_sweep from the wrong thread must hit the ownership guard
* and return without sweeping — nodes must remain intact */
gc_sweep_select_nodes(NULL, 0);
g_wrong_thread_sweep_ran = 1;
return NULL;
}
static void
test_sel_wrong_thread_guard(void)
{
sel_optimize_test_reset();
sel_optimize_set(1);
sel_node_table_init();
/* Register THIS thread as the allocator */
sel_register_alloc_thread();
/* Allocate a node that should survive the wrong-thread sweep */
xce_select_node_t* n = makeSelectNode(SEL_TRUE, 0, 0);
TEST_ASSERT_NOT_NULL(n);
/* Spawn a different thread to call gc_sweep — guard must block it */
pthread_t tid;
g_wrong_thread_sweep_ran = 0;
int rc = pthread_create(&tid, NULL, wrong_thread_sweep, NULL);
TEST_ASSERT_EQUAL_INT(0, rc);
pthread_join(tid, NULL);
TEST_ASSERT_EQUAL_INT(1, g_wrong_thread_sweep_ran);
/* Node must still exist (wrong-thread sweep was blocked) */
/* GC from correct thread: mark then sweep normally */
gc_clear_marks();
gc_sweep_select_nodes(NULL, 0);
sel_node_table_fini();
sel_optimize_test_reset();
}
/* ── Top-level runner ─────────────────────────────────────────────────────*/
void
@ -2365,6 +2412,7 @@ test_select(void)
/* ── Task 8: sel_alloc_thread_id ownership check ─────────────────── */
RUN_TEST(test_sel_register_alloc_thread);
RUN_TEST(test_sel_wrong_thread_guard);
xstring_table_fini();
}