aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKévin Petit <kpet@free.fr>2023-08-19 11:15:17 +0100
committerGitHub <noreply@github.com>2023-08-19 11:15:17 +0100
commit0702f2ecee4b250818a7fe289508ef9c54c1b48e (patch)
tree6278f0c4127ae1ad75326972a27a96221ad9d352
parentdf53e02a12453340f418c8544291e7b3c08e3aa5 (diff)
downloadOpenCL-CTS-0702f2ecee4b250818a7fe289508ef9c54c1b48e.tar.gz
Make genrand_int32 thread safe (#1797)
The initialisation code is clearly meant to be run once but the volatile flag did not guarantee that at all: - Volatile does not mean atomic and loading the flag vs. other writes was not safe. - Multiple threads could have loaded 0 and performed the initialisation resulting in write collisions. Rely on std::call_once to provide the guarantee. This issue was flagged by TSAN. Signed-off-by: Kévin Petit <kpet@free.fr>
-rw-r--r--test_common/harness/mt19937.cpp10
1 files changed, 5 insertions, 5 deletions
diff --git a/test_common/harness/mt19937.cpp b/test_common/harness/mt19937.cpp
index f5665deb..2d503eb5 100644
--- a/test_common/harness/mt19937.cpp
+++ b/test_common/harness/mt19937.cpp
@@ -51,6 +51,7 @@
#include "harness/alloc.h"
#ifdef __SSE2__
+#include <mutex>
#include <emmintrin.h>
#endif
@@ -107,7 +108,7 @@ cl_uint genrand_int32(MTdata d)
/* mag01[x] = x * MATRIX_A for x=0,1 */
static const cl_uint mag01[2] = { 0x0UL, MATRIX_A };
#ifdef __SSE2__
- static volatile int init = 0;
+ static std::once_flag init_flag;
static union {
__m128i v;
cl_uint s[4];
@@ -123,8 +124,7 @@ cl_uint genrand_int32(MTdata d)
int kk;
#ifdef __SSE2__
- if (0 == init)
- {
+ auto init_fn = []() {
upper_mask.s[0] = upper_mask.s[1] = upper_mask.s[2] =
upper_mask.s[3] = UPPER_MASK;
lower_mask.s[0] = lower_mask.s[1] = lower_mask.s[2] =
@@ -134,8 +134,8 @@ cl_uint genrand_int32(MTdata d)
MATRIX_A;
c0.s[0] = c0.s[1] = c0.s[2] = c0.s[3] = (cl_uint)0x9d2c5680UL;
c1.s[0] = c1.s[1] = c1.s[2] = c1.s[3] = (cl_uint)0xefc60000UL;
- init = 1;
- }
+ };
+ std::call_once(init_flag, init_fn);
#endif
kk = 0;