diff options
| author | Benoit Germain <benoit.germain@ubisoft.com> | 2024-04-05 09:45:00 +0200 |
|---|---|---|
| committer | Benoit Germain <benoit.germain@ubisoft.com> | 2024-04-05 09:45:00 +0200 |
| commit | b6c00dc091ec43971a78b043ed57204beba59e9b (patch) | |
| tree | c44a43df6445ab0148cfdf92b69d1775fd557fbe /src | |
| parent | c64f9dcd61c1ad7bef3dbf5b7647a2a2da23ac0f (diff) | |
| download | lanes-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.cpp | 44 |
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) |
| 103 | static void tracking_add(Lane* lane_); | 105 | static void tracking_add(Lane* lane_); |
| 104 | 106 | ||
| @@ -1866,7 +1868,9 @@ static void init_once_LOCKED( void) | |||
| 1866 | 1868 | ||
| 1867 | // ################################################################################################# | 1869 | // ################################################################################################# |
| 1868 | 1870 | ||
| 1869 | static volatile long s_initCount = 0; | 1871 | // we are C++20, the flags are default-initialized to 'clear' |
| 1872 | std::atomic_flag s_insideInit; | ||
| 1873 | std::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 |
