refactor shared heap api and test case

This commit is contained in:
TL 2025-11-24 21:36:49 +08:00
parent 10808b1019
commit d01a3be96a
4 changed files with 61 additions and 87 deletions

View File

@ -358,24 +358,27 @@ wasm_runtime_unchain_shared_heaps(WASMSharedHeap *head, bool entire_chain)
return cur; return cur;
} }
/* Destroy and recycle a shared heap(or head of shared heap chain), return next /* Destroy and recycle a shared heap(or head of shared heap chain), return
* node in the shared heap chain */ * next node in the shared heap chain through new_head */
static WASMSharedHeap * static bool
wasm_runtime_destroy_shared_heap_head(WASMSharedHeap *head) wasm_runtime_destroy_shared_heap_head(WASMSharedHeap *head,
WASMSharedHeap **new_head)
{ {
WASMSharedHeap *cur = NULL, *prev = NULL, *new_head = NULL; WASMSharedHeap *cur = NULL, *prev = NULL, *next_head = NULL;
bool head_found = false, is_chain_head = true; bool head_found = false, is_chain_head = true;
if (!head) { if (!head) {
LOG_WARNING("Invalid shared heap to destroy."); LOG_WARNING("Invalid shared heap to destroy.");
return NULL; return false;
} }
*new_head = NULL;
os_mutex_lock(&shared_heap_list_lock); os_mutex_lock(&shared_heap_list_lock);
if (head->attached_count != 0) { if (head->attached_count != 0) {
LOG_WARNING("To destroy shared heap, it needs to be detached first."); LOG_WARNING("To destroy shared heap, it needs to be detached first.");
os_mutex_unlock(&shared_heap_list_lock); os_mutex_unlock(&shared_heap_list_lock);
return NULL; return false;
} }
for (cur = shared_heap_list; cur; cur = cur->next) { for (cur = shared_heap_list; cur; cur = cur->next) {
@ -387,16 +390,16 @@ wasm_runtime_destroy_shared_heap_head(WASMSharedHeap *head)
if (!head_found) { if (!head_found) {
LOG_WARNING("Shared heap %p isn't tracked by runtime.", head); LOG_WARNING("Shared heap %p isn't tracked by runtime.", head);
os_mutex_unlock(&shared_heap_list_lock); os_mutex_unlock(&shared_heap_list_lock);
return NULL; return false;
} }
if (!is_chain_head) { if (!is_chain_head) {
LOG_WARNING("Shared heap %p isn't the head of a shared heap chain.", LOG_WARNING("Shared heap %p isn't the head of a shared heap chain.",
head); head);
os_mutex_unlock(&shared_heap_list_lock); os_mutex_unlock(&shared_heap_list_lock);
return NULL; return false;
} }
new_head = head->chain_next; next_head = head->chain_next;
if (head == shared_heap_list) { if (head == shared_heap_list) {
shared_heap_list = head->next; shared_heap_list = head->next;
destroy_shared_heap_node(head); destroy_shared_heap_node(head);
@ -419,18 +422,29 @@ wasm_runtime_destroy_shared_heap_head(WASMSharedHeap *head)
LOG_VERBOSE("Destroyed shared heap %p", head); LOG_VERBOSE("Destroyed shared heap %p", head);
return new_head; *new_head = next_head;
return true;
} }
WASMSharedHeap * bool
wasm_runtime_destroy_shared_heap(WASMSharedHeap *head, bool entire_chain) wasm_runtime_destroy_shared_heap(WASMSharedHeap *head, bool entire_chain,
WASMSharedHeap **new_head)
{ {
WASMSharedHeap *new_head = NULL; WASMSharedHeap *next_head = NULL;
do {
new_head = wasm_runtime_destroy_shared_heap_head(head);
} while (entire_chain && new_head);
return new_head; do {
if (!wasm_runtime_destroy_shared_heap_head(head, &next_head)) {
return false;
}
head = next_head;
} while (entire_chain && head);
if (new_head) {
*new_head = next_head;
}
return true;
} }
static uint8 * static uint8 *

View File

@ -95,8 +95,9 @@ wasm_runtime_chain_shared_heaps(WASMSharedHeap *head, WASMSharedHeap *body);
WASMSharedHeap * WASMSharedHeap *
wasm_runtime_unchain_shared_heaps(WASMSharedHeap *head, bool entire_chain); wasm_runtime_unchain_shared_heaps(WASMSharedHeap *head, bool entire_chain);
WASMSharedHeap * bool
wasm_runtime_destroy_shared_heap(WASMSharedHeap *head, bool entire_chain); wasm_runtime_destroy_shared_heap(WASMSharedHeap *head, bool entire_chain,
WASMSharedHeap **new_head);
bool bool
wasm_runtime_attach_shared_heap(WASMModuleInstanceCommon *module_inst, wasm_runtime_attach_shared_heap(WASMModuleInstanceCommon *module_inst,

View File

@ -2408,17 +2408,19 @@ wasm_runtime_unchain_shared_heaps(wasm_shared_heap_t head, bool entire_chain);
/** /**
* Destroy a shared heap or shared heap chain starting from the given head. * Destroy a shared heap or shared heap chain starting from the given head.
* If `entire_chain` is true, destroy the whole chain; otherwise, destroy only * If `entire_chain` is true, destroy the whole chain; otherwise, destroy only
* the head and return the new head of the chain. The shared heap chain must be * the head and return the new head of the chain through `new_head`. The shared
* detached before destruction, and only the chain head registered with the * heap chain must be detached before destruction, and only the chain head
* runtime can be destroyed. * registered with the runtime can be destroyed.
* *
* @param head The head of the shared heap chain to be destroyed. * @param head The head of the shared heap chain to be destroyed.
* @param entire_chain Whether to destroy the entire chain. * @param entire_chain Whether to destroy the entire chain.
* @return The new head of the shared heap chain when `entire_chain` is false; * @param new_head The new head of the shared heap chain when `entire_chain` is
* NULL otherwise. * false; NULL otherwise.
* @return True if destruction succeeds; false otherwise.
*/ */
WASM_RUNTIME_API_EXTERN wasm_shared_heap_t WASM_RUNTIME_API_EXTERN bool
wasm_runtime_destroy_shared_heap(wasm_shared_heap_t head, bool entire_chain); wasm_runtime_destroy_shared_heap(wasm_shared_heap_t head, bool entire_chain,
wasm_shared_heap_t *new_head);
/** /**
* Attach a shared heap, it can be the head of shared heap chain, in that case, * Attach a shared heap, it can be the head of shared heap chain, in that case,

View File

@ -334,8 +334,9 @@ TEST_F(shared_heap_test, test_destroy_shared_heap_head_only)
ASSERT_NE(nullptr, second); ASSERT_NE(nullptr, second);
WASMSharedHeap *new_head = WASMSharedHeap *new_head = nullptr;
wasm_runtime_destroy_shared_heap(shared_heap_chain, false); ASSERT_TRUE(
wasm_runtime_destroy_shared_heap(shared_heap_chain, false, &new_head));
ASSERT_EQ(second, new_head); ASSERT_EQ(second, new_head);
ASSERT_EQ(nullptr, new_head->chain_next); ASSERT_EQ(nullptr, new_head->chain_next);
@ -355,8 +356,10 @@ TEST_F(shared_heap_test, test_destroy_shared_heap_entire_chain)
FAIL() << "Failed to create shared heap"; FAIL() << "Failed to create shared heap";
} }
EXPECT_EQ(nullptr, WASMSharedHeap *new_head = nullptr;
wasm_runtime_destroy_shared_heap(shared_heap_chain, true)); EXPECT_TRUE(
wasm_runtime_destroy_shared_heap(shared_heap_chain, true, &new_head));
EXPECT_EQ(nullptr, new_head);
} }
TEST_F(shared_heap_test, test_destroy_shared_heap_not_chain_head) TEST_F(shared_heap_test, test_destroy_shared_heap_not_chain_head)
@ -372,14 +375,16 @@ TEST_F(shared_heap_test, test_destroy_shared_heap_not_chain_head)
ASSERT_NE(nullptr, body); ASSERT_NE(nullptr, body);
EXPECT_EQ(nullptr, wasm_runtime_destroy_shared_heap(body, true)); WASMSharedHeap *new_head = nullptr;
EXPECT_FALSE(wasm_runtime_destroy_shared_heap(body, true, &new_head));
EXPECT_EQ(body, shared_heap_chain->chain_next); EXPECT_EQ(body, shared_heap_chain->chain_next);
test_shared_heap(shared_heap_chain, "test.wasm", "test", 0, argv); test_shared_heap(shared_heap_chain, "test.wasm", "test", 0, argv);
EXPECT_EQ(10, argv[0]); EXPECT_EQ(10, argv[0]);
EXPECT_EQ(nullptr, EXPECT_TRUE(
wasm_runtime_destroy_shared_heap(shared_heap_chain, true)); wasm_runtime_destroy_shared_heap(shared_heap_chain, true, &new_head));
EXPECT_EQ(nullptr, new_head);
} }
TEST_F(shared_heap_test, test_destroy_shared_heap_when_attached) TEST_F(shared_heap_test, test_destroy_shared_heap_when_attached)
@ -395,63 +400,15 @@ TEST_F(shared_heap_test, test_destroy_shared_heap_when_attached)
ASSERT_TRUE(wasm_runtime_attach_shared_heap(module_env.wasm_module_inst, ASSERT_TRUE(wasm_runtime_attach_shared_heap(module_env.wasm_module_inst,
shared_heap)); shared_heap));
EXPECT_EQ(nullptr, wasm_runtime_destroy_shared_heap(shared_heap, true)); WASMSharedHeap *new_head = nullptr;
EXPECT_FALSE(
wasm_runtime_destroy_shared_heap(shared_heap, true, &new_head));
wasm_runtime_detach_shared_heap(module_env.wasm_module_inst); wasm_runtime_detach_shared_heap(module_env.wasm_module_inst);
destroy_module_env(module_env); destroy_module_env(module_env);
EXPECT_EQ(nullptr, wasm_runtime_destroy_shared_heap(shared_heap, true)); EXPECT_TRUE(wasm_runtime_destroy_shared_heap(shared_heap, true, &new_head));
} EXPECT_EQ(nullptr, new_head);
TEST_F(shared_heap_test, test_destroy_invalid_shared_heap)
{
WASMSharedHeap fake_shared_heap = {};
EXPECT_EQ(nullptr,
wasm_runtime_destroy_shared_heap(&fake_shared_heap, true));
}
TEST_F(shared_heap_test, test_destroy_shared_heap_untracked_next_head_only)
{
WASMSharedHeap *shared_heap_chain = nullptr;
WASMSharedHeap *body = nullptr;
WASMSharedHeap fake_shared_heap = {};
uint32 BUF_SIZE = os_getpagesize();
create_test_shared_heap_chain(preallocated_buf, BUF_SIZE, preallocated_buf2,
BUF_SIZE, &shared_heap_chain);
body = shared_heap_chain->chain_next;
ASSERT_NE(nullptr, body);
shared_heap_chain->chain_next = &fake_shared_heap;
EXPECT_EQ(NULL, wasm_runtime_destroy_shared_heap(shared_heap_chain, false));
shared_heap_chain->chain_next = body;
EXPECT_EQ(body, wasm_runtime_destroy_shared_heap(shared_heap_chain, false));
EXPECT_EQ(nullptr, wasm_runtime_destroy_shared_heap(body, true));
}
TEST_F(shared_heap_test, test_destroy_shared_heap_untracked_next_entire_chain)
{
WASMSharedHeap *shared_heap_chain = nullptr;
WASMSharedHeap *body = nullptr;
WASMSharedHeap fake_shared_heap = {};
uint32 BUF_SIZE = os_getpagesize();
create_test_shared_heap_chain(NULL, BUF_SIZE, NULL, BUF_SIZE,
&shared_heap_chain);
body = shared_heap_chain->chain_next;
ASSERT_NE(nullptr, body);
shared_heap_chain->chain_next = &fake_shared_heap;
EXPECT_EQ(nullptr,
wasm_runtime_destroy_shared_heap(shared_heap_chain, true));
shared_heap_chain->chain_next = body;
EXPECT_EQ(nullptr,
wasm_runtime_destroy_shared_heap(shared_heap_chain, true));
} }
TEST_F(shared_heap_test, test_shared_heap_rmw) TEST_F(shared_heap_test, test_shared_heap_rmw)