aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorBenoit Germain <benoit.germain@ubisoft.com>2024-04-05 09:45:00 +0200
committerBenoit Germain <benoit.germain@ubisoft.com>2024-04-05 09:45:00 +0200
commitb6c00dc091ec43971a78b043ed57204beba59e9b (patch)
treec44a43df6445ab0148cfdf92b69d1775fd557fbe /src
parentc64f9dcd61c1ad7bef3dbf5b7647a2a2da23ac0f (diff)
downloadlanes-b6c00dc091ec43971a78b043ed57204beba59e9b.tar.gz
lanes-b6c00dc091ec43971a78b043ed57204beba59e9b.tar.bz2
lanes-b6c00dc091ec43971a78b043ed57204beba59e9b.zip
C++ migration: one-time inits are sequenced with std::atomic_flag
Diffstat (limited to 'src')
-rw-r--r--src/lanes.cpp44
1 files changed, 14 insertions, 30 deletions
diff --git a/src/lanes.cpp b/src/lanes.cpp
index 5fb81a3..08584a2 100644
--- a/src/lanes.cpp
+++ b/src/lanes.cpp
@@ -99,6 +99,8 @@ THE SOFTWARE.
99# include <sys/types.h> 99# include <sys/types.h>
100#endif 100#endif
101 101
102#include <atomic>
103
102// forwarding (will do things better later) 104// forwarding (will do things better later)
103static void tracking_add(Lane* lane_); 105static void tracking_add(Lane* lane_);
104 106
@@ -1866,7 +1868,9 @@ static void init_once_LOCKED( void)
1866 1868
1867// ################################################################################################# 1869// #################################################################################################
1868 1870
1869static volatile long s_initCount = 0; 1871// we are C++20, the flags are default-initialized to 'clear'
1872std::atomic_flag s_insideInit;
1873std::atomic_flag s_initDone;
1870 1874
1871// upvalue 1: module name 1875// upvalue 1: module name
1872// upvalue 2: module table 1876// upvalue 2: module table
@@ -1885,39 +1889,19 @@ LUAG_FUNC(configure)
1885 ** there is no problem. But if the host is multithreaded, we need to lock around the 1889 ** there is no problem. But if the host is multithreaded, we need to lock around the
1886 ** initializations. 1890 ** initializations.
1887 */ 1891 */
1888#if THREADAPI == THREADAPI_WINDOWS 1892 if (s_insideInit.test_and_set())
1889 { 1893 {
1890 static volatile int /*bool*/ go_ahead; // = 0 1894 // blocks until flag value is no longer the one passed in parameter
1891 if (InterlockedCompareExchange(&s_initCount, 1, 0) == 0) 1895 s_initDone.wait(false);
1892 {
1893 init_once_LOCKED();
1894 go_ahead = 1; // let others pass
1895 }
1896 else
1897 {
1898 while (!go_ahead)
1899 {
1900 Sleep(1);
1901 } // changes threads
1902 }
1903 } 1896 }
1904#else // THREADAPI == THREADAPI_PTHREAD 1897 else
1905 if (s_initCount == 0)
1906 { 1898 {
1907 static pthread_mutex_t my_lock = PTHREAD_MUTEX_INITIALIZER; 1899 // we are the first to enter here, because s_insideInit was false.
1908 pthread_mutex_lock(&my_lock); 1900 // and we are the only one, because it's now true.
1909 { 1901 init_once_LOCKED();
1910 // Recheck now that we're within the lock 1902 std::ignore = s_initDone.test_and_set();
1911 // 1903 s_initDone.notify_all();
1912 if (s_initCount == 0)
1913 {
1914 init_once_LOCKED();
1915 s_initCount = 1;
1916 }
1917 }
1918 pthread_mutex_unlock(&my_lock);
1919 } 1904 }
1920#endif // THREADAPI == THREADAPI_PTHREAD
1921 1905
1922 STACK_GROW(L, 4); 1906 STACK_GROW(L, 4);
1923 STACK_CHECK_START_ABS(L, 1); // settings 1907 STACK_CHECK_START_ABS(L, 1); // settings