diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/lanes.cpp | 51 |
1 files changed, 14 insertions, 37 deletions
diff --git a/src/lanes.cpp b/src/lanes.cpp index 28f95f6..cf443f2 100644 --- a/src/lanes.cpp +++ b/src/lanes.cpp | |||
@@ -1736,55 +1736,32 @@ static const struct luaL_Reg lanes_functions[] = | |||
1736 | { nullptr, nullptr } | 1736 | { nullptr, nullptr } |
1737 | }; | 1737 | }; |
1738 | 1738 | ||
1739 | /* | ||
1740 | * One-time initializations | ||
1741 | * settings table it at position 1 on the stack | ||
1742 | * pushes an error string on the stack in case of problem | ||
1743 | */ | ||
1744 | static void init_once_LOCKED( void) | ||
1745 | { | ||
1746 | #if (defined PLATFORM_OSX) && (defined _UTILBINDTHREADTOCPU) | ||
1747 | chudInitialize(); | ||
1748 | #endif | ||
1749 | } | ||
1750 | |||
1751 | // ################################################################################################# | 1739 | // ################################################################################################# |
1752 | 1740 | ||
1753 | // we are C++20, the flags are default-initialized to 'clear' | ||
1754 | std::atomic_flag s_insideInit; | ||
1755 | std::atomic_flag s_initDone; | ||
1756 | |||
1757 | // upvalue 1: module name | 1741 | // upvalue 1: module name |
1758 | // upvalue 2: module table | 1742 | // upvalue 2: module table |
1759 | // param 1: settings table | 1743 | // param 1: settings table |
1760 | LUAG_FUNC(configure) | 1744 | LUAG_FUNC(configure) |
1761 | { | 1745 | { |
1746 | // start with one-time initializations. | ||
1747 | { | ||
1748 | // C++ guarantees that the static variable initialization is threadsafe. | ||
1749 | static auto _ = std::invoke( | ||
1750 | []() | ||
1751 | { | ||
1752 | #if (defined PLATFORM_OSX) && (defined _UTILBINDTHREADTOCPU) | ||
1753 | chudInitialize(); | ||
1754 | #endif | ||
1755 | return false; | ||
1756 | } | ||
1757 | ); | ||
1758 | } | ||
1759 | |||
1762 | Universe* U = universe_get(L); | 1760 | Universe* U = universe_get(L); |
1763 | bool const from_master_state{ U == nullptr }; | 1761 | bool const from_master_state{ U == nullptr }; |
1764 | char const* name = luaL_checkstring(L, lua_upvalueindex(1)); | 1762 | char const* name = luaL_checkstring(L, lua_upvalueindex(1)); |
1765 | ASSERT_L(lua_type(L, 1) == LUA_TTABLE); | 1763 | ASSERT_L(lua_type(L, 1) == LUA_TTABLE); |
1766 | 1764 | ||
1767 | /* | ||
1768 | ** Making one-time initializations. | ||
1769 | ** | ||
1770 | ** When the host application is single-threaded (and all threading happens via Lanes) | ||
1771 | ** there is no problem. But if the host is multithreaded, we need to lock around the | ||
1772 | ** initializations. | ||
1773 | */ | ||
1774 | if (s_insideInit.test_and_set()) | ||
1775 | { | ||
1776 | // blocks until flag value is no longer the one passed in parameter | ||
1777 | s_initDone.wait(false); | ||
1778 | } | ||
1779 | else | ||
1780 | { | ||
1781 | // we are the first to enter here, because s_insideInit was false. | ||
1782 | // and we are the only one, because it's now true. | ||
1783 | init_once_LOCKED(); | ||
1784 | std::ignore = s_initDone.test_and_set(); | ||
1785 | s_initDone.notify_all(); | ||
1786 | } | ||
1787 | |||
1788 | STACK_GROW(L, 4); | 1765 | STACK_GROW(L, 4); |
1789 | STACK_CHECK_START_ABS(L, 1); // settings | 1766 | STACK_CHECK_START_ABS(L, 1); // settings |
1790 | 1767 | ||