diff --git a/src/iris_buffer.h b/src/iris_buffer.h index 775c5d5..3e55d54 100644 --- a/src/iris_buffer.h +++ b/src/iris_buffer.h @@ -46,6 +46,7 @@ namespace iris { using value_type = element_t; iris_buffer_t() noexcept : size(0) { + buffer = nullptr; static_assert(storage_size >= 3 * sizeof(size_t) / sizeof(element_t), "must has stock storage of at least 3 pointer size."); static_assert(std::is_trivially_constructible::value, "must be trivially constructible."); static_assert(std::is_trivially_destructible::value, "must be trivially destructible."); diff --git a/src/iris_common.h b/src/iris_common.h index 63ca6e1..8c506aa 100644 --- a/src/iris_common.h +++ b/src/iris_common.h @@ -2389,7 +2389,7 @@ namespace iris { } else { element_t value = std::move(queue.top()); queue.pop(); - return std::move(value); + return value; } } @@ -2537,6 +2537,7 @@ namespace iris { amount = m; } else { host = nullptr; + amount = amount_t(); } } diff --git a/src/iris_coroutine.h b/src/iris_coroutine.h index e49c701..5e82ccf 100644 --- a/src/iris_coroutine.h +++ b/src/iris_coroutine.h @@ -176,8 +176,11 @@ namespace iris { // notice that we do not initialize `caller` here, let `await_suspend` do // parallel_priority: ~size_t(0) means no parallization, other value indicates the dispatch priority of parallel routines template - iris_awaitable_t(warp_t* target_warp, callable_t&& f, size_t p) noexcept : target(target_warp), parallel_priority(p), func(std::forward(f)) { + iris_awaitable_t(warp_t* target_warp, callable_t&& f, size_t p) noexcept : caller(nullptr), target(target_warp), parallel_priority(p), func(std::forward(f)) { IRIS_ASSERT(target_warp != nullptr || parallel_priority == ~size_t(0)); + if constexpr (!std::is_void_v) { + ret = return_t(); + } } // always suspended @@ -667,7 +670,7 @@ namespace iris { struct info_base_warp_t { std::coroutine_handle<> handle; - warp_t* warp; + warp_t* warp = nullptr; }; struct info_base_t { @@ -807,7 +810,7 @@ namespace iris { std::atomic_thread_fence(std::memory_order_acquire); if (in_index != out_index) { auto handle = std::move(handles[in_index]); - handles[in_index] = info_t { nullptr, nullptr }; + handles[in_index] = info_t(nullptr, nullptr); iris_sync_t::dispatch(std::move(handle)); std::atomic_thread_fence(std::memory_order_release); in_index = out_index; diff --git a/src/iris_dispatcher.h b/src/iris_dispatcher.h index 5c59596..ddab5d1 100644 --- a/src/iris_dispatcher.h +++ b/src/iris_dispatcher.h @@ -430,7 +430,10 @@ namespace iris { (*p).execute_parallel(); } - if ((*p).suspend_count.load(std::memory_order_acquire) <= 1) { + IRIS_ASSERT((*p).is_suspended()); + + // nobody else suspend this warp + if ((*p).suspend_count.load(std::memory_order_acquire) == 1) { // execute remaining if /* constexpr */ (execute_remaining) { (*p).template execute_internal(); @@ -580,7 +583,7 @@ namespace iris { async_worker.execute_task(p); execute_counter++; - if ((!force && suspend_count.load(std::memory_order_relaxed) != 0) || *warp_ptr != this) { + if ((!force && is_suspended()) || *warp_ptr != this) { return; } @@ -622,7 +625,7 @@ namespace iris { execute_counter++; counter = next_version; - if ((!force && suspend_count.load(std::memory_order_relaxed) != 0) || *warp_ptr != this) + if ((!force && is_suspended()) || *warp_ptr != this) return; } @@ -641,14 +644,14 @@ namespace iris { void execute() noexcept(noexcept(std::declval().template execute_internal())) { IRIS_PROFILE_SCOPE(__FUNCTION__); - if (suspend_count.load(std::memory_order_acquire) == 0) { + if (!is_suspended()) { // try to acquire execution, if it fails, there must be another thread doing the same thing // and it's ok to return immediately. preempt_guard_t preempt_guard(*this, 0); if (preempt_guard) { execute_parallel(); - if (suspend_count.load(std::memory_order_acquire) == 0) { // double check for suspend_count + if (!is_suspended()) { // double check for suspend_count execute_internal(); preempt_guard.cleanup(); @@ -982,7 +985,7 @@ namespace iris { complete(true); } - void validate(routine_t* from, routine_t* to) const noexcept { + static void validate(routine_t* from, routine_t* to) noexcept { IRIS_ASSERT(from != to); for (size_t i = 0; i < sizeof(to->next_tasks) / sizeof(to->next_tasks[0]); i++) { diff --git a/src/iris_lua.h b/src/iris_lua.h index 1c9e18e..7d97fd8 100644 --- a/src/iris_lua.h +++ b/src/iris_lua.h @@ -89,7 +89,7 @@ namespace iris { template static size_t get_hash() noexcept { - static size_t hash = std::hash()(typeid(type_t).name()) & 0xFFFFFFFF; + static size_t hash = std::hash()(typeid(type_t).name()) & 0xFFFFFFFF; // compatible with tagged pointer trick by LuaJIT return hash; } @@ -145,7 +145,7 @@ namespace iris { return value != LUA_REFNIL; } - int get() const noexcept { + int get_ref_value() const noexcept { return value; } @@ -255,6 +255,7 @@ namespace iris { int value; }; + // ref_t for types template struct reftype_t : ref_t { using type_t = subtype_t; @@ -270,7 +271,7 @@ namespace iris { return *this; } - const void* get_type_hash() noexcept { + const void* get_type_hash() const noexcept { return reinterpret_cast(get_hash()); } @@ -287,6 +288,7 @@ namespace iris { return *this; } + // for chain expressions reftype_t&& make_registry(iris_lua_t lua, bool enable = true) && { const void* hash = get_type_hash(); if (hash != nullptr) { @@ -301,6 +303,7 @@ namespace iris { } }; + // ref_t for custom types template struct refptr_t : ref_t { refptr_t(int v = LUA_REFNIL, type_t* p = nullptr) noexcept : ref_t(v), ptr(p) {} @@ -514,6 +517,7 @@ namespace iris { return refptr_t(luaL_ref(L, LUA_REGISTRYINDEX), p); } + // make object from registry meta template refptr_t make_registry_object_view(type_t* object) { return make_object_view(get_registry(reinterpret_cast(get_hash())), object); @@ -563,6 +567,7 @@ namespace iris { luaL_Buffer* buffer; }; + // build string from C-style formatted construction template ref_t make_string(const char* fmt, args_t&&... args) { IRIS_PROFILE_SCOPE(__FUNCTION__); @@ -573,6 +578,7 @@ namespace iris { return ref_t(luaL_ref(L, LUA_REGISTRYINDEX)); } + // build string from customized function template ref_t make_string(func_t&& func) { IRIS_PROFILE_SCOPE(__FUNCTION__); @@ -586,6 +592,7 @@ namespace iris { return ref_t(luaL_ref(L, LUA_REGISTRYINDEX)); } + // make ref from a given value template ref_t make_value(value_t&& value) { lua_State* L = state; @@ -607,6 +614,7 @@ namespace iris { int level; }; + // get from context template value_t get_context(key_t&& key) { auto guard = write_fence(); @@ -661,6 +669,7 @@ namespace iris { lua_rawset(L, LUA_REGISTRYINDEX); } + // get lua registry table template void set_registry(key_t&& key) { auto guard = write_fence(); @@ -696,6 +705,7 @@ namespace iris { lua_setglobal(L, key.data()); } + // set lua global table template void set_global(std::string_view key) { auto guard = write_fence(); @@ -705,7 +715,7 @@ namespace iris { lua_setglobal(L, key.data()); } - // define a variable by value + // set 'current' lua table, usually used in lua_registar callbacks template void set_current(key_t&& key, value_t&& value) { auto guard = write_fence(); @@ -718,7 +728,8 @@ namespace iris { lua_rawset(L, -3); } - // define a bound member function/property + // set 'current' lua table, usually used in lua_registar callbacks + // spec for constexpr ptr (methods, properties) template void set_current(key_t&& key) { auto guard = write_fence(); @@ -1661,6 +1672,7 @@ namespace iris { } } + // spec for constexpr ptr template static void push_variable(lua_State* L) { if constexpr (std::is_convertible_v || std::is_convertible_v) { @@ -1757,6 +1769,7 @@ namespace iris { } } + // transfer variable between different states template static int cross_transfer_variable(lua_State* L, lua_t& target, int index, int recursion_source, int recursion_target, int recursion_index) { stack_guard_t guard(L); diff --git a/test/iris_tree_demo.cpp b/test/iris_tree_demo.cpp index 29a1ebc..a5d5f8f 100644 --- a/test/iris_tree_demo.cpp +++ b/test/iris_tree_demo.cpp @@ -60,6 +60,7 @@ box build_box_randomly() noexcept { } struct queryer { + queryer() : count(0) {} size_t count; box bounding; bool operator () (const sample_tree::base& tree) noexcept { @@ -72,7 +73,6 @@ struct queryer { size_t fast_query(sample_tree*& root, const box& box) noexcept { queryer q; q.bounding = box; - q.count = 0; IRIS_ASSERT(root->get_parent() == nullptr); root->query(box, q);