Skip to content

Commit aca650f

Browse files
authored
Enable testing for __sync_fetch_and_nand. NFC (#15620)
Contrary to the comments there these atomics ops seem to work fine these days. The only exception is that __sync_fetch_and_nand doesn't work under wasm2js due to a current binaryen limitation. See WebAssembly/binaryen#4358
1 parent 4b9840b commit aca650f

File tree

5 files changed

+18
-103
lines changed

5 files changed

+18
-103
lines changed

tests/pthread/test_pthread_gcc_64bit_atomic_fetch_and_op.cpp

Lines changed: 1 addition & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -16,23 +16,6 @@
1616

1717
#define T uint64_t
1818

19-
#if 0
20-
// TEMP to make this test pass:
21-
// Our Clang backend doesn't define this builtin function, so implement it ourselves.
22-
// The current Atomics spec doesn't have the nand atomic op either, so must use a cas loop.
23-
// TODO: Move this to Clang backend?
24-
T __sync_fetch_and_nand(T *ptr, T x)
25-
{
26-
for(;;)
27-
{
28-
T old = emscripten_atomic_load_u32(ptr);
29-
T newVal = ~(old & x);
30-
T old2 = emscripten_atomic_cas_u32(ptr, old, newVal);
31-
if (old2 == old) return old;
32-
}
33-
}
34-
#endif
35-
3619
void *thread_fetch_and_add(void *arg)
3720
{
3821
for(int i = 0; i < 10000; ++i)
@@ -69,19 +52,15 @@ void *thread_fetch_and_xor(void *arg)
6952
__sync_fetch_and_xor((T*)&fetch_and_xor_data, *(T*)arg);
7053
pthread_exit(0);
7154
}
72-
#if 0
7355

74-
// XXX NAND support does not exist in Atomics API.
75-
#if 0
7656
volatile long fetch_and_nand_data = 0;
7757
void *thread_fetch_and_nand(void *arg)
7858
{
7959
for(int i = 0; i < 9999; ++i) // Odd number of times so that the operation doesn't cancel itself out.
8060
__sync_fetch_and_nand((long*)&fetch_and_nand_data, (long)arg);
8161
pthread_exit(0);
8262
}
83-
#endif
84-
#endif
63+
8564
T threadArg[NUM_THREADS];
8665
pthread_t thread[NUM_THREADS];
8766

@@ -178,8 +157,6 @@ int main()
178157
}
179158
}
180159
}
181-
// XXX NAND support does not exist in Atomics API.
182-
#if 0
183160
{
184161
T x = 5;
185162
T y = __sync_fetch_and_nand(&x, 9);
@@ -194,7 +171,6 @@ int main()
194171
assert(fetch_and_nand_data == -1);
195172
}
196173
}
197-
#endif
198174

199175
return 0;
200176
}

tests/pthread/test_pthread_gcc_64bit_atomic_op_and_fetch.cpp

Lines changed: 4 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -16,23 +16,6 @@
1616

1717
#define T uint64_t
1818

19-
#if 0
20-
// TEMP to make this test pass:
21-
// Our Clang backend doesn't define this builtin function, so implement it ourselves.
22-
// The current Atomics spec doesn't have the nand atomic op either, so must use a cas loop.
23-
// TODO: Move this to Clang backend?
24-
T __sync_nand_and_fetch(T *ptr, T x)
25-
{
26-
for(;;)
27-
{
28-
T old = emscripten_atomic_load_u32(ptr);
29-
T newVal = ~(old & x);
30-
T old2 = emscripten_atomic_cas_u32(ptr, old, newVal);
31-
if (old2 == old) return old;
32-
}
33-
}
34-
#endif
35-
3619
void *thread_add_and_fetch(void *arg)
3720
{
3821
for(int i = 0; i < 10000; ++i)
@@ -69,19 +52,15 @@ void *thread_xor_and_fetch(void *arg)
6952
__sync_xor_and_fetch((T*)&xor_and_fetch_data, *(T*)arg);
7053
pthread_exit(0);
7154
}
72-
#if 0
7355

74-
// XXX NAND support does not exist in Atomics API.
75-
#if 0
76-
volatile long nand_and_fetch_data = 0;
56+
volatile T nand_and_fetch_data = 0;
7757
void *thread_nand_and_fetch(void *arg)
7858
{
7959
for(int i = 0; i < 9999; ++i) // Odd number of times so that the operation doesn't cancel itself out.
80-
__sync_nand_and_fetch((long*)&nand_and_fetch_data, (long)arg);
60+
__sync_nand_and_fetch((T*)&nand_and_fetch_data, (T)arg);
8161
pthread_exit(0);
8262
}
83-
#endif
84-
#endif
63+
8564
T threadArg[NUM_THREADS];
8665
pthread_t thread[NUM_THREADS];
8766

@@ -178,12 +157,10 @@ int main()
178157
}
179158
}
180159
}
181-
// XXX NAND support does not exist in Atomics API.
182-
#if 0
183160
{
184161
T x = 5;
185162
T y = __sync_nand_and_fetch(&x, 9);
186-
assert(y == 5);
163+
assert(y == -2);
187164
assert(x == -2);
188165
const int oddNThreads = NUM_THREADS-1;
189166
for(int x = 0; x < 100; ++x) // Test a few times for robustness, since this test is so short-lived.
@@ -194,7 +171,6 @@ int main()
194171
assert(nand_and_fetch_data == -1);
195172
}
196173
}
197-
#endif
198174

199175
return 0;
200176
}

tests/pthread/test_pthread_gcc_atomic_fetch_and_op.cpp

Lines changed: 4 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -16,23 +16,6 @@
1616

1717
#define T int
1818

19-
#if 0
20-
// TEMP to make this test pass:
21-
// Our Clang backend doesn't define this builtin function, so implement it ourselves.
22-
// The current Atomics spec doesn't have the nand atomic op either, so must use a cas loop.
23-
// TODO: Move this to Clang backend?
24-
T __sync_fetch_and_nand(T *ptr, T x)
25-
{
26-
for(;;)
27-
{
28-
T old = emscripten_atomic_load_u32(ptr);
29-
T newVal = ~(old & x);
30-
T old2 = emscripten_atomic_cas_u32(ptr, old, newVal);
31-
if (old2 == old) return old;
32-
}
33-
}
34-
#endif
35-
3619
void *thread_fetch_and_add(void *arg)
3720
{
3821
for(int i = 0; i < 10000; ++i)
@@ -72,15 +55,13 @@ void *thread_fetch_and_xor(void *arg)
7255
}
7356

7457
// XXX NAND support does not exist in Atomics API.
75-
#if 0
7658
volatile long fetch_and_nand_data = 0;
7759
void *thread_fetch_and_nand(void *arg)
7860
{
7961
for(int i = 0; i < 9999; ++i) // Odd number of times so that the operation doesn't cancel itself out.
8062
__sync_fetch_and_nand(&fetch_and_nand_data, (long)arg);
8163
pthread_exit(0);
8264
}
83-
#endif
8465

8566
pthread_t thread[NUM_THREADS];
8667

@@ -161,12 +142,6 @@ int main()
161142
}
162143
}
163144

164-
// Test that regex replacing also works on these.
165-
emscripten_atomic_fence();
166-
__sync_synchronize();
167-
168-
// XXX NAND support does not exist in Atomics API.
169-
#if 0
170145
{
171146
T x = 5;
172147
T y = __sync_fetch_and_nand(&x, 9);
@@ -181,7 +156,10 @@ int main()
181156
assert(fetch_and_nand_data == -1);
182157
}
183158
}
184-
#endif
159+
160+
// Test that regex replacing also works on these.
161+
emscripten_atomic_fence();
162+
__sync_synchronize();
185163

186164
return 0;
187165
}

tests/pthread/test_pthread_gcc_atomic_op_and_fetch.cpp

Lines changed: 0 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -16,23 +16,6 @@
1616

1717
#define T int
1818

19-
#if 0
20-
// TEMP to make this test pass:
21-
// Our Clang backend doesn't define this builtin function, so implement it ourselves.
22-
// The current Atomics spec doesn't have the nand atomic op either, so must use a cas loop.
23-
// TODO: Move this to Clang backend?
24-
T __sync_nand_and_fetch(T *ptr, T x)
25-
{
26-
for(;;)
27-
{
28-
T old = emscripten_atomic_load_u32(ptr);
29-
T newVal = ~(old & x);
30-
T old2 = emscripten_atomic_cas_u32(ptr, old, newVal);
31-
if (old2 == old) return newVal;
32-
}
33-
}
34-
#endif
35-
3619
void *thread_add_and_fetch(void *arg)
3720
{
3821
for(int i = 0; i < 10000; ++i)
@@ -71,16 +54,13 @@ void *thread_xor_and_fetch(void *arg)
7154
pthread_exit(0);
7255
}
7356

74-
// XXX NAND support does not exist in Atomics API.
75-
#if 0
7657
volatile long nand_and_fetch_data = 0;
7758
void *thread_nand_and_fetch(void *arg)
7859
{
7960
for(int i = 0; i < 9999; ++i) // Odd number of times so that the operation doesn't cancel itself out.
8061
__sync_nand_and_fetch((long*)&nand_and_fetch_data, (long)arg);
8162
pthread_exit(0);
8263
}
83-
#endif
8464

8565
pthread_t thread[NUM_THREADS];
8666

@@ -160,8 +140,6 @@ int main()
160140
}
161141
}
162142
}
163-
// XXX NAND support does not exist in Atomics API.
164-
#if 0
165143
{
166144
T x = 5;
167145
T y = __sync_nand_and_fetch(&x, 9);
@@ -176,7 +154,6 @@ int main()
176154
assert(nand_and_fetch_data == -1);
177155
}
178156
}
179-
#endif
180157

181158
return 0;
182159
}

tests/test_browser.py

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3802,6 +3802,7 @@ def test_pthread_main_thread_blocking(self, name):
38023802
# Test the old GCC atomic __sync_fetch_and_op builtin operations.
38033803
@requires_threads
38043804
def test_pthread_gcc_atomic_fetch_and_op(self):
3805+
self.emcc_args += ['-Wno-sync-fetch-and-nand-semantics-changed']
38053806
for opt in [[], ['-O1'], ['-O2'], ['-O3'], ['-Os']]:
38063807
for debug in [[], ['-g']]:
38073808
args = opt + debug
@@ -3812,19 +3813,26 @@ def test_pthread_gcc_atomic_fetch_and_op(self):
38123813
@also_with_wasm2js
38133814
@requires_threads
38143815
def test_pthread_gcc_64bit_atomic_fetch_and_op(self):
3816+
if not self.is_wasm():
3817+
self.skipTest('https://github.com/WebAssembly/binaryen/issues/4358')
3818+
self.emcc_args += ['-Wno-sync-fetch-and-nand-semantics-changed']
38153819
self.btest_exit(test_file('pthread/test_pthread_gcc_64bit_atomic_fetch_and_op.cpp'), args=['-s', 'INITIAL_MEMORY=64MB', '-O3', '-s', 'USE_PTHREADS', '-s', 'PTHREAD_POOL_SIZE=8'])
38163820

38173821
# Test the old GCC atomic __sync_op_and_fetch builtin operations.
38183822
@also_with_wasm2js
38193823
@requires_threads
38203824
def test_pthread_gcc_atomic_op_and_fetch(self):
3825+
self.emcc_args += ['-Wno-sync-fetch-and-nand-semantics-changed']
38213826
self.btest_exit(test_file('pthread/test_pthread_gcc_atomic_op_and_fetch.cpp'), args=['-s', 'INITIAL_MEMORY=64MB', '-O3', '-s', 'USE_PTHREADS', '-s', 'PTHREAD_POOL_SIZE=8'])
38223827

38233828
# 64 bit version of the above test.
38243829
@also_with_wasm2js
38253830
@requires_threads
38263831
def test_pthread_gcc_64bit_atomic_op_and_fetch(self):
3827-
self.btest_exit(test_file('pthread/test_pthread_gcc_64bit_atomic_op_and_fetch.cpp'), args=['-s', 'INITIAL_MEMORY=64MB', '-O3', '-s', 'USE_PTHREADS', '-s', 'PTHREAD_POOL_SIZE=8'])
3832+
if not self.is_wasm():
3833+
self.skipTest('https://github.com/WebAssembly/binaryen/issues/4358')
3834+
self.emcc_args += ['-Wno-sync-fetch-and-nand-semantics-changed', '--profiling-funcs']
3835+
self.btest_exit(test_file('pthread/test_pthread_gcc_64bit_atomic_op_and_fetch.cpp'), args=['-s', 'INITIAL_MEMORY=64MB', '-s', 'USE_PTHREADS', '-O2', '-s', 'PTHREAD_POOL_SIZE=8'])
38283836

38293837
# Tests the rest of the remaining GCC atomics after the two above tests.
38303838
@also_with_wasm2js

0 commit comments

Comments
 (0)