mirror of
https://github.com/KhronosGroup/OpenCL-CTS.git
synced 2026-03-25 16:29:03 +00:00
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>
This commit is contained in:
@@ -51,6 +51,7 @@
|
|||||||
#include "harness/alloc.h"
|
#include "harness/alloc.h"
|
||||||
|
|
||||||
#ifdef __SSE2__
|
#ifdef __SSE2__
|
||||||
|
#include <mutex>
|
||||||
#include <emmintrin.h>
|
#include <emmintrin.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -107,7 +108,7 @@ cl_uint genrand_int32(MTdata d)
|
|||||||
/* mag01[x] = x * MATRIX_A for x=0,1 */
|
/* mag01[x] = x * MATRIX_A for x=0,1 */
|
||||||
static const cl_uint mag01[2] = { 0x0UL, MATRIX_A };
|
static const cl_uint mag01[2] = { 0x0UL, MATRIX_A };
|
||||||
#ifdef __SSE2__
|
#ifdef __SSE2__
|
||||||
static volatile int init = 0;
|
static std::once_flag init_flag;
|
||||||
static union {
|
static union {
|
||||||
__m128i v;
|
__m128i v;
|
||||||
cl_uint s[4];
|
cl_uint s[4];
|
||||||
@@ -123,8 +124,7 @@ cl_uint genrand_int32(MTdata d)
|
|||||||
int kk;
|
int kk;
|
||||||
|
|
||||||
#ifdef __SSE2__
|
#ifdef __SSE2__
|
||||||
if (0 == init)
|
auto init_fn = []() {
|
||||||
{
|
|
||||||
upper_mask.s[0] = upper_mask.s[1] = upper_mask.s[2] =
|
upper_mask.s[0] = upper_mask.s[1] = upper_mask.s[2] =
|
||||||
upper_mask.s[3] = UPPER_MASK;
|
upper_mask.s[3] = UPPER_MASK;
|
||||||
lower_mask.s[0] = lower_mask.s[1] = lower_mask.s[2] =
|
lower_mask.s[0] = lower_mask.s[1] = lower_mask.s[2] =
|
||||||
@@ -134,8 +134,8 @@ cl_uint genrand_int32(MTdata d)
|
|||||||
MATRIX_A;
|
MATRIX_A;
|
||||||
c0.s[0] = c0.s[1] = c0.s[2] = c0.s[3] = (cl_uint)0x9d2c5680UL;
|
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;
|
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
|
#endif
|
||||||
|
|
||||||
kk = 0;
|
kk = 0;
|
||||||
|
|||||||
Reference in New Issue
Block a user