vcomp: Implement _vcomp_reduction_{u,i}8 and add tests.
[wine.git] / dlls / vcomp / tests / vcomp.c
blob088f25680fdbb9a9f02331ed54933fda7abb183e
1 /*
2 * Unit test suite for vcomp
4 * Copyright 2012 Dan Kegel
5 * Copyright 2015-2016 Sebastian Lackner
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
22 #include <stdio.h>
23 #include "wine/test.h"
25 static char vcomp_manifest_file[MAX_PATH];
26 static HANDLE vcomp_actctx_hctx;
27 static ULONG_PTR vcomp_actctx_cookie;
28 static HMODULE vcomp_handle;
30 static HANDLE (WINAPI *pCreateActCtxA)(ACTCTXA*);
31 static BOOL (WINAPI *pActivateActCtx)(HANDLE, ULONG_PTR*);
32 static BOOL (WINAPI *pDeactivateActCtx)(DWORD, ULONG_PTR);
33 static VOID (WINAPI *pReleaseActCtx)(HANDLE);
35 typedef CRITICAL_SECTION *omp_lock_t;
36 typedef CRITICAL_SECTION *omp_nest_lock_t;
38 static void (CDECL *p_vcomp_atomic_add_i1)(char *dest, char val);
39 static void (CDECL *p_vcomp_atomic_add_i2)(short *dest, short val);
40 static void (CDECL *p_vcomp_atomic_add_i4)(int *dest, int val);
41 static void (CDECL *p_vcomp_atomic_add_i8)(LONG64 *dest, LONG64 val);
42 static void (CDECL *p_vcomp_atomic_add_r4)(float *dest, float val);
43 static void (CDECL *p_vcomp_atomic_add_r8)(double *dest, double val);
44 static void (CDECL *p_vcomp_atomic_and_i1)(char *dest, char val);
45 static void (CDECL *p_vcomp_atomic_and_i2)(short *dest, short val);
46 static void (CDECL *p_vcomp_atomic_and_i4)(int *dest, int val);
47 static void (CDECL *p_vcomp_atomic_and_i8)(LONG64 *dest, LONG64 val);
48 static void (CDECL *p_vcomp_atomic_div_i1)(char *dest, char val);
49 static void (CDECL *p_vcomp_atomic_div_i2)(short *dest, short val);
50 static void (CDECL *p_vcomp_atomic_div_i4)(int *dest, int val);
51 static void (CDECL *p_vcomp_atomic_div_i8)(LONG64 *dest, LONG64 val);
52 static void (CDECL *p_vcomp_atomic_div_r4)(float *dest, float val);
53 static void (CDECL *p_vcomp_atomic_div_r8)(double *dest, double val);
54 static void (CDECL *p_vcomp_atomic_div_ui1)(unsigned char *dest, unsigned char val);
55 static void (CDECL *p_vcomp_atomic_div_ui2)(unsigned short *dest, unsigned short val);
56 static void (CDECL *p_vcomp_atomic_div_ui4)(unsigned int *dest, unsigned int val);
57 static void (CDECL *p_vcomp_atomic_div_ui8)(ULONG64 *dest, ULONG64 val);
58 static void (CDECL *p_vcomp_atomic_mul_i1)(char *dest, char val);
59 static void (CDECL *p_vcomp_atomic_mul_i2)(short *dest, short val);
60 static void (CDECL *p_vcomp_atomic_mul_i4)(int *dest, int val);
61 static void (CDECL *p_vcomp_atomic_mul_i8)(LONG64 *dest, LONG64 val);
62 static void (CDECL *p_vcomp_atomic_mul_r4)(float *dest, float val);
63 static void (CDECL *p_vcomp_atomic_mul_r8)(double *dest, double val);
64 static void (CDECL *p_vcomp_atomic_or_i1)(char *dest, char val);
65 static void (CDECL *p_vcomp_atomic_or_i2)(short *dest, short val);
66 static void (CDECL *p_vcomp_atomic_or_i4)(int *dest, int val);
67 static void (CDECL *p_vcomp_atomic_or_i8)(LONG64 *dest, LONG64 val);
68 static void (CDECL *p_vcomp_atomic_shl_i1)(char *dest, unsigned int val);
69 static void (CDECL *p_vcomp_atomic_shl_i2)(short *dest, unsigned int val);
70 static void (CDECL *p_vcomp_atomic_shl_i4)(int *dest, int val);
71 static void (CDECL *p_vcomp_atomic_shl_i8)(LONG64 *dest, unsigned int val);
72 static void (CDECL *p_vcomp_atomic_shr_i1)(char *dest, unsigned int val);
73 static void (CDECL *p_vcomp_atomic_shr_i2)(short *dest, unsigned int val);
74 static void (CDECL *p_vcomp_atomic_shr_i4)(int *dest, int val);
75 static void (CDECL *p_vcomp_atomic_shr_i8)(LONG64 *dest, unsigned int val);
76 static void (CDECL *p_vcomp_atomic_shr_ui1)(unsigned char *dest, unsigned int val);
77 static void (CDECL *p_vcomp_atomic_shr_ui2)(unsigned short *dest, unsigned int val);
78 static void (CDECL *p_vcomp_atomic_shr_ui4)(unsigned int *dest, unsigned int val);
79 static void (CDECL *p_vcomp_atomic_shr_ui8)(ULONG64 *dest, unsigned int val);
80 static void (CDECL *p_vcomp_atomic_sub_i1)(char *dest, char val);
81 static void (CDECL *p_vcomp_atomic_sub_i2)(short *dest, short val);
82 static void (CDECL *p_vcomp_atomic_sub_i4)(int *dest, int val);
83 static void (CDECL *p_vcomp_atomic_sub_i8)(LONG64 *dest, LONG64 val);
84 static void (CDECL *p_vcomp_atomic_sub_r4)(float *dest, float val);
85 static void (CDECL *p_vcomp_atomic_sub_r8)(double *dest, double val);
86 static void (CDECL *p_vcomp_atomic_xor_i1)(char *dest, char val);
87 static void (CDECL *p_vcomp_atomic_xor_i2)(short *dest, short val);
88 static void (CDECL *p_vcomp_atomic_xor_i4)(int *dest, int val);
89 static void (CDECL *p_vcomp_atomic_xor_i8)(LONG64 *dest, LONG64 val);
90 static void (CDECL *p_vcomp_barrier)(void);
91 static void (CDECL *p_vcomp_enter_critsect)(CRITICAL_SECTION **critsect);
92 static void (CDECL *p_vcomp_flush)(void);
93 static void (CDECL *p_vcomp_for_dynamic_init)(unsigned int flags, unsigned int first, unsigned int last,
94 int step, unsigned int chunksize);
95 static int (CDECL *p_vcomp_for_dynamic_next)(unsigned int *begin, unsigned int *end);
96 static void (CDECL *p_vcomp_for_static_end)(void);
97 static void (CDECL *p_vcomp_for_static_init)(int first, int last, int step, int chunksize, unsigned int *loops,
98 int *begin, int *end, int *next, int *lastchunk);
99 static void (CDECL *p_vcomp_for_static_simple_init)(unsigned int first, unsigned int last, int step,
100 BOOL increment, unsigned int *begin, unsigned int *end);
101 static void (WINAPIV *p_vcomp_fork)(BOOL ifval, int nargs, void *wrapper, ...);
102 static int (CDECL *p_vcomp_get_thread_num)(void);
103 static void (CDECL *p_vcomp_leave_critsect)(CRITICAL_SECTION *critsect);
104 static int (CDECL *p_vcomp_master_begin)(void);
105 static void (CDECL *p_vcomp_master_end)(void);
106 static void (CDECL *p_vcomp_reduction_i1)(unsigned int flags, char *dest, char val);
107 static void (CDECL *p_vcomp_reduction_i2)(unsigned int flags, short *dest, short val);
108 static void (CDECL *p_vcomp_reduction_i4)(unsigned int flags, int *dest, int val);
109 static void (CDECL *p_vcomp_reduction_i8)(unsigned int flags, LONG64 *dest, LONG64 val);
110 static void (CDECL *p_vcomp_reduction_u1)(unsigned int flags, unsigned char *dest, unsigned char val);
111 static void (CDECL *p_vcomp_reduction_u2)(unsigned int flags, unsigned short *dest, unsigned short val);
112 static void (CDECL *p_vcomp_reduction_u4)(unsigned int flags, unsigned int *dest, unsigned int val);
113 static void (CDECL *p_vcomp_reduction_u8)(unsigned int flags, ULONG64 *dest, ULONG64 val);
114 static void (CDECL *p_vcomp_sections_init)(int n);
115 static int (CDECL *p_vcomp_sections_next)(void);
116 static void (CDECL *p_vcomp_set_num_threads)(int num_threads);
117 static int (CDECL *p_vcomp_single_begin)(int flags);
118 static void (CDECL *p_vcomp_single_end)(void);
119 static void (CDECL *pomp_destroy_lock)(omp_lock_t *lock);
120 static void (CDECL *pomp_destroy_nest_lock)(omp_nest_lock_t *lock);
121 static int (CDECL *pomp_get_max_threads)(void);
122 static int (CDECL *pomp_get_nested)(void);
123 static int (CDECL *pomp_get_num_threads)(void);
124 static int (CDECL *pomp_get_thread_num)(void);
125 static int (CDECL *pomp_in_parallel)(void);
126 static void (CDECL *pomp_init_lock)(omp_lock_t *lock);
127 static void (CDECL *pomp_init_nest_lock)(omp_nest_lock_t *lock);
128 static void (CDECL *pomp_set_lock)(omp_lock_t *lock);
129 static void (CDECL *pomp_set_nest_lock)(omp_nest_lock_t *lock);
130 static void (CDECL *pomp_set_nested)(int nested);
131 static void (CDECL *pomp_set_num_threads)(int num_threads);
132 static int (CDECL *pomp_test_lock)(omp_lock_t *lock);
133 static int (CDECL *pomp_test_nest_lock)(omp_nest_lock_t *lock);
134 static void (CDECL *pomp_unset_lock)(omp_lock_t *lock);
135 static void (CDECL *pomp_unset_nest_lock)(omp_nest_lock_t *lock);
137 #define VCOMP_DYNAMIC_FLAGS_STATIC 0x01
138 #define VCOMP_DYNAMIC_FLAGS_CHUNKED 0x02
139 #define VCOMP_DYNAMIC_FLAGS_GUIDED 0x03
140 #define VCOMP_DYNAMIC_FLAGS_INCREMENT 0x40
142 #define VCOMP_REDUCTION_FLAGS_ADD 0x100
143 #define VCOMP_REDUCTION_FLAGS_MUL 0x200
144 #define VCOMP_REDUCTION_FLAGS_AND 0x300
145 #define VCOMP_REDUCTION_FLAGS_OR 0x400
146 #define VCOMP_REDUCTION_FLAGS_XOR 0x500
147 #define VCOMP_REDUCTION_FLAGS_BOOL_AND 0x600
148 #define VCOMP_REDUCTION_FLAGS_BOOL_OR 0x700
150 #ifdef __i386__
151 #define ARCH "x86"
152 #elif defined(__x86_64__)
153 #define ARCH "amd64"
154 #elif defined __arm__
155 #define ARCH "arm"
156 #elif defined __aarch64__
157 #define ARCH "arm64"
158 #else
159 #define ARCH "none"
160 #endif
162 static const char vcomp_manifest[] =
163 "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n"
164 "<assembly xmlns=\"urn:schemas-microsoft-com:asm.v1\" manifestVersion=\"1.0\">\n"
165 " <assemblyIdentity\n"
166 " type=\"win32\"\n"
167 " name=\"Wine.vcomp.Test\"\n"
168 " version=\"1.0.0.0\"\n"
169 " processorArchitecture=\"" ARCH "\"\n"
170 " />\n"
171 "<description>Wine vcomp test suite</description>\n"
172 "<dependency>\n"
173 " <dependentAssembly>\n"
174 " <assemblyIdentity\n"
175 " type=\"win32\"\n"
176 " name=\"Microsoft.VC80.OpenMP\"\n"
177 " version=\"8.0.50608.0\"\n"
178 " processorArchitecture=\"" ARCH "\"\n"
179 " publicKeyToken=\"1fc8b3b9a1e18e3b\"\n"
180 " />\n"
181 " </dependentAssembly>\n"
182 "</dependency>\n"
183 "</assembly>\n";
185 #undef ARCH
187 static const char *debugstr_longlong(ULONGLONG ll)
189 static char str[17];
190 if (sizeof(ll) > sizeof(unsigned long) && ll >> 32)
191 sprintf(str, "%lx%08lx", (unsigned long)(ll >> 32), (unsigned long)ll);
192 else
193 sprintf(str, "%lx", (unsigned long)ll);
194 return str;
197 static void create_vcomp_manifest(void)
199 char temp_path[MAX_PATH];
200 HMODULE kernel32;
201 DWORD written;
202 ACTCTXA ctx;
203 HANDLE file;
205 kernel32 = GetModuleHandleA("kernel32.dll");
206 pCreateActCtxA = (void *)GetProcAddress(kernel32, "CreateActCtxA");
207 pActivateActCtx = (void *)GetProcAddress(kernel32, "ActivateActCtx");
208 pDeactivateActCtx = (void *)GetProcAddress(kernel32, "DeactivateActCtx");
209 pReleaseActCtx = (void *)GetProcAddress(kernel32, "ReleaseActCtx");
210 if (!pCreateActCtxA) return;
212 if (!GetTempPathA(sizeof(temp_path), temp_path) ||
213 !GetTempFileNameA(temp_path, "vcomp", 0, vcomp_manifest_file))
215 ok(0, "failed to create manifest file\n");
216 return;
219 file = CreateFileA(vcomp_manifest_file, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
220 if (file == INVALID_HANDLE_VALUE)
222 ok(0, "failed to open manifest file\n");
223 return;
226 if (!WriteFile(file, vcomp_manifest, sizeof(vcomp_manifest) - 1, &written, NULL))
227 written = 0;
228 CloseHandle(file);
230 if (written != sizeof(vcomp_manifest) - 1)
232 ok(0, "failed to write manifest file\n");
233 DeleteFileA(vcomp_manifest_file);
234 return;
237 memset(&ctx, 0, sizeof(ctx));
238 ctx.cbSize = sizeof(ctx);
239 ctx.lpSource = vcomp_manifest_file;
240 vcomp_actctx_hctx = pCreateActCtxA(&ctx);
241 if (!vcomp_actctx_hctx)
243 ok(0, "failed to create activation context\n");
244 DeleteFileA(vcomp_manifest_file);
245 return;
248 if (!pActivateActCtx(vcomp_actctx_hctx, &vcomp_actctx_cookie))
250 win_skip("failed to activate context\n");
251 pReleaseActCtx(vcomp_actctx_hctx);
252 DeleteFileA(vcomp_manifest_file);
253 vcomp_actctx_hctx = NULL;
257 static void release_vcomp(void)
259 if (vcomp_handle)
260 FreeLibrary(vcomp_handle);
262 if (vcomp_actctx_hctx)
264 pDeactivateActCtx(0, vcomp_actctx_cookie);
265 pReleaseActCtx(vcomp_actctx_hctx);
266 DeleteFileA(vcomp_manifest_file);
270 #define VCOMP_GET_PROC(func) \
271 do \
273 p ## func = (void *)GetProcAddress(vcomp_handle, #func); \
274 if (!p ## func) trace("Failed to get address for %s\n", #func); \
276 while (0)
278 static BOOL init_vcomp(void)
280 create_vcomp_manifest();
282 vcomp_handle = LoadLibraryA("vcomp.dll");
283 if (!vcomp_handle)
285 win_skip("vcomp.dll not installed\n");
286 release_vcomp();
287 return FALSE;
290 VCOMP_GET_PROC(_vcomp_atomic_add_i1);
291 VCOMP_GET_PROC(_vcomp_atomic_add_i2);
292 VCOMP_GET_PROC(_vcomp_atomic_add_i4);
293 VCOMP_GET_PROC(_vcomp_atomic_add_i8);
294 VCOMP_GET_PROC(_vcomp_atomic_add_r4);
295 VCOMP_GET_PROC(_vcomp_atomic_add_r8);
296 VCOMP_GET_PROC(_vcomp_atomic_and_i1);
297 VCOMP_GET_PROC(_vcomp_atomic_and_i2);
298 VCOMP_GET_PROC(_vcomp_atomic_and_i4);
299 VCOMP_GET_PROC(_vcomp_atomic_and_i8);
300 VCOMP_GET_PROC(_vcomp_atomic_div_i1);
301 VCOMP_GET_PROC(_vcomp_atomic_div_i2);
302 VCOMP_GET_PROC(_vcomp_atomic_div_i4);
303 VCOMP_GET_PROC(_vcomp_atomic_div_i8);
304 VCOMP_GET_PROC(_vcomp_atomic_div_r4);
305 VCOMP_GET_PROC(_vcomp_atomic_div_r8);
306 VCOMP_GET_PROC(_vcomp_atomic_div_ui1);
307 VCOMP_GET_PROC(_vcomp_atomic_div_ui2);
308 VCOMP_GET_PROC(_vcomp_atomic_div_ui4);
309 VCOMP_GET_PROC(_vcomp_atomic_div_ui8);
310 VCOMP_GET_PROC(_vcomp_atomic_mul_i1);
311 VCOMP_GET_PROC(_vcomp_atomic_mul_i2);
312 VCOMP_GET_PROC(_vcomp_atomic_mul_i4);
313 VCOMP_GET_PROC(_vcomp_atomic_mul_i8);
314 VCOMP_GET_PROC(_vcomp_atomic_mul_r4);
315 VCOMP_GET_PROC(_vcomp_atomic_mul_r8);
316 VCOMP_GET_PROC(_vcomp_atomic_or_i1);
317 VCOMP_GET_PROC(_vcomp_atomic_or_i2);
318 VCOMP_GET_PROC(_vcomp_atomic_or_i4);
319 VCOMP_GET_PROC(_vcomp_atomic_or_i8);
320 VCOMP_GET_PROC(_vcomp_atomic_shl_i1);
321 VCOMP_GET_PROC(_vcomp_atomic_shl_i2);
322 VCOMP_GET_PROC(_vcomp_atomic_shl_i4);
323 VCOMP_GET_PROC(_vcomp_atomic_shl_i8);
324 VCOMP_GET_PROC(_vcomp_atomic_shr_i1);
325 VCOMP_GET_PROC(_vcomp_atomic_shr_i2);
326 VCOMP_GET_PROC(_vcomp_atomic_shr_i4);
327 VCOMP_GET_PROC(_vcomp_atomic_shr_i8);
328 VCOMP_GET_PROC(_vcomp_atomic_shr_ui1);
329 VCOMP_GET_PROC(_vcomp_atomic_shr_ui2);
330 VCOMP_GET_PROC(_vcomp_atomic_shr_ui4);
331 VCOMP_GET_PROC(_vcomp_atomic_shr_ui8);
332 VCOMP_GET_PROC(_vcomp_atomic_sub_i1);
333 VCOMP_GET_PROC(_vcomp_atomic_sub_i2);
334 VCOMP_GET_PROC(_vcomp_atomic_sub_i4);
335 VCOMP_GET_PROC(_vcomp_atomic_sub_i8);
336 VCOMP_GET_PROC(_vcomp_atomic_sub_r4);
337 VCOMP_GET_PROC(_vcomp_atomic_sub_r8);
338 VCOMP_GET_PROC(_vcomp_atomic_xor_i1);
339 VCOMP_GET_PROC(_vcomp_atomic_xor_i2);
340 VCOMP_GET_PROC(_vcomp_atomic_xor_i4);
341 VCOMP_GET_PROC(_vcomp_atomic_xor_i8);
342 VCOMP_GET_PROC(_vcomp_barrier);
343 VCOMP_GET_PROC(_vcomp_enter_critsect);
344 VCOMP_GET_PROC(_vcomp_flush);
345 VCOMP_GET_PROC(_vcomp_for_dynamic_init);
346 VCOMP_GET_PROC(_vcomp_for_dynamic_next);
347 VCOMP_GET_PROC(_vcomp_for_static_end);
348 VCOMP_GET_PROC(_vcomp_for_static_init);
349 VCOMP_GET_PROC(_vcomp_for_static_simple_init);
350 VCOMP_GET_PROC(_vcomp_fork);
351 VCOMP_GET_PROC(_vcomp_get_thread_num);
352 VCOMP_GET_PROC(_vcomp_leave_critsect);
353 VCOMP_GET_PROC(_vcomp_master_begin);
354 VCOMP_GET_PROC(_vcomp_master_end);
355 VCOMP_GET_PROC(_vcomp_reduction_i1);
356 VCOMP_GET_PROC(_vcomp_reduction_i2);
357 VCOMP_GET_PROC(_vcomp_reduction_i4);
358 VCOMP_GET_PROC(_vcomp_reduction_i8);
359 VCOMP_GET_PROC(_vcomp_reduction_u1);
360 VCOMP_GET_PROC(_vcomp_reduction_u2);
361 VCOMP_GET_PROC(_vcomp_reduction_u4);
362 VCOMP_GET_PROC(_vcomp_reduction_u8);
363 VCOMP_GET_PROC(_vcomp_sections_init);
364 VCOMP_GET_PROC(_vcomp_sections_next);
365 VCOMP_GET_PROC(_vcomp_set_num_threads);
366 VCOMP_GET_PROC(_vcomp_single_begin);
367 VCOMP_GET_PROC(_vcomp_single_end);
368 VCOMP_GET_PROC(omp_destroy_lock);
369 VCOMP_GET_PROC(omp_destroy_nest_lock);
370 VCOMP_GET_PROC(omp_get_max_threads);
371 VCOMP_GET_PROC(omp_get_nested);
372 VCOMP_GET_PROC(omp_get_num_threads);
373 VCOMP_GET_PROC(omp_get_thread_num);
374 VCOMP_GET_PROC(omp_in_parallel);
375 VCOMP_GET_PROC(omp_init_lock);
376 VCOMP_GET_PROC(omp_init_nest_lock);
377 VCOMP_GET_PROC(omp_set_lock);
378 VCOMP_GET_PROC(omp_set_nest_lock);
379 VCOMP_GET_PROC(omp_set_nested);
380 VCOMP_GET_PROC(omp_set_num_threads);
381 VCOMP_GET_PROC(omp_test_lock);
382 VCOMP_GET_PROC(omp_test_nest_lock);
383 VCOMP_GET_PROC(omp_unset_lock);
384 VCOMP_GET_PROC(omp_unset_nest_lock);
386 return TRUE;
389 #undef VCOMP_GET_PROC
391 static void CDECL num_threads_cb2(int parallel, LONG *count)
393 int is_parallel = pomp_in_parallel();
394 ok(is_parallel == parallel, "expected %d, got %d\n", parallel, is_parallel);
396 InterlockedIncrement(count);
399 static void CDECL num_threads_cb(BOOL nested, int parallel, int nested_threads, LONG *count)
401 int is_parallel, num_threads, thread_num;
402 LONG thread_count;
404 InterlockedIncrement(count);
405 p_vcomp_barrier();
407 num_threads = pomp_get_num_threads();
408 ok(num_threads == *count, "expected num_threads == %d, got %d\n", *count, num_threads);
409 thread_num = pomp_get_thread_num();
410 ok(thread_num >= 0 && thread_num < num_threads,
411 "expected thread_num in range [0, %d], got %d\n", num_threads - 1, thread_num);
412 ok(thread_num == p_vcomp_get_thread_num(),
413 "expected _vcomp_get_thread_num to return the same value\n");
415 is_parallel = pomp_in_parallel();
416 ok(is_parallel == parallel, "expected %d, got %d\n", parallel, is_parallel);
418 thread_count = 0;
419 p_vcomp_fork(TRUE, 2, num_threads_cb2, TRUE, &thread_count);
420 if (nested)
421 ok(thread_count == nested_threads, "expected %d threads, got %d\n", nested_threads, thread_count);
422 else
423 ok(thread_count == 1, "expected 1 thread, got %d\n", thread_count);
425 is_parallel = pomp_in_parallel();
426 ok(is_parallel == parallel, "expected %d, got %d\n", parallel, is_parallel);
428 thread_count = 0;
429 p_vcomp_fork(FALSE, 2, num_threads_cb2, parallel, &thread_count);
430 ok(thread_count == 1, "expected 1 thread, got %d\n", thread_count);
432 is_parallel = pomp_in_parallel();
433 ok(is_parallel == parallel, "expected %d, got %d\n", parallel, is_parallel);
435 p_vcomp_set_num_threads(4);
436 thread_count = 0;
437 p_vcomp_fork(TRUE, 2, num_threads_cb2, TRUE, &thread_count);
438 if (nested)
439 ok(thread_count == 4, "expected 4 threads, got %d\n", thread_count);
440 else
441 ok(thread_count == 1, "expected 1 thread, got %d\n", thread_count);
443 is_parallel = pomp_in_parallel();
444 ok(is_parallel == parallel, "expected %d, got %d\n", parallel, is_parallel);
447 static void test_omp_get_num_threads(BOOL nested)
449 int is_nested, is_parallel, max_threads, num_threads, thread_num;
450 LONG thread_count;
452 ok(pomp_get_thread_num != p_vcomp_get_thread_num,
453 "expected omp_get_thread_num != _vcomp_get_thread_num\n");
455 pomp_set_nested(nested);
456 is_nested = pomp_get_nested();
457 ok(is_nested == nested, "expected %d, got %d\n", nested, is_nested);
459 max_threads = pomp_get_max_threads();
460 ok(max_threads >= 1, "expected max_threads >= 1, got %d\n", max_threads);
461 thread_num = pomp_get_thread_num();
462 ok(thread_num == 0, "expected thread_num == 0, got %d\n", thread_num);
464 is_parallel = pomp_in_parallel();
465 ok(is_parallel == FALSE, "expected FALSE, got %d\n", is_parallel);
467 num_threads = pomp_get_num_threads();
468 ok(num_threads == 1, "expected num_threads == 1, got %d\n", num_threads);
469 thread_count = 0;
470 p_vcomp_fork(TRUE, 4, num_threads_cb, nested, TRUE, max_threads, &thread_count);
471 ok(thread_count == max_threads, "expected %d threads, got %d\n", max_threads, thread_count);
473 is_parallel = pomp_in_parallel();
474 ok(is_parallel == FALSE, "expected FALSE, got %d\n", is_parallel);
476 num_threads = pomp_get_num_threads();
477 ok(num_threads == 1, "expected num_threads == 1, got %d\n", num_threads);
478 thread_count = 0;
479 p_vcomp_fork(FALSE, 4, num_threads_cb, TRUE, FALSE, max_threads, &thread_count);
480 ok(thread_count == 1, "expected 1 thread, got %d\n", thread_count);
482 is_parallel = pomp_in_parallel();
483 ok(is_parallel == FALSE, "expected FALSE, got %d\n", is_parallel);
485 pomp_set_num_threads(1);
486 num_threads = pomp_get_num_threads();
487 ok(num_threads == 1, "expected num_threads == 1, got %d\n", num_threads);
488 thread_count = 0;
489 p_vcomp_fork(TRUE, 4, num_threads_cb, nested, TRUE, 1, &thread_count);
490 ok(thread_count == 1, "expected 1 thread, got %d\n", thread_count);
492 is_parallel = pomp_in_parallel();
493 ok(is_parallel == FALSE, "expected FALSE, got %d\n", is_parallel);
495 pomp_set_num_threads(2);
496 num_threads = pomp_get_num_threads();
497 ok(num_threads == 1, "expected num_threads == 1, got %d\n", num_threads);
498 thread_count = 0;
499 p_vcomp_fork(TRUE, 4, num_threads_cb, nested, TRUE, 2, &thread_count);
500 ok(thread_count == 2, "expected 2 threads, got %d\n", thread_count);
502 pomp_set_num_threads(4);
503 num_threads = pomp_get_num_threads();
504 ok(num_threads == 1, "expected num_threads == 1, got %d\n", num_threads);
505 thread_count = 0;
506 p_vcomp_fork(TRUE, 4, num_threads_cb, nested, TRUE, 4, &thread_count);
507 ok(thread_count == 4, "expected 4 threads, got %d\n", thread_count);
509 p_vcomp_set_num_threads(8);
510 num_threads = pomp_get_num_threads();
511 ok(num_threads == 1, "expected num_threads == 1, got %d\n", num_threads);
512 thread_count = 0;
513 p_vcomp_fork(TRUE, 4, num_threads_cb, nested, TRUE, 4, &thread_count);
514 ok(thread_count == 8, "expected 8 threads, got %d\n", thread_count);
515 thread_count = 0;
516 p_vcomp_fork(TRUE, 4, num_threads_cb, nested, TRUE, 4, &thread_count);
517 ok(thread_count == 4, "expected 4 threads, got %d\n", thread_count);
519 p_vcomp_set_num_threads(0);
520 num_threads = pomp_get_num_threads();
521 ok(num_threads == 1, "expected num_threads == 1, got %d\n", num_threads);
522 thread_count = 0;
523 p_vcomp_fork(TRUE, 4, num_threads_cb, nested, TRUE, 4, &thread_count);
524 ok(thread_count == 4, "expected 4 threads, got %d\n", thread_count);
526 pomp_set_num_threads(0);
527 num_threads = pomp_get_num_threads();
528 ok(num_threads == 1, "expected num_threads == 1, got %d\n", num_threads);
529 thread_count = 0;
530 p_vcomp_fork(TRUE, 4, num_threads_cb, nested, TRUE, 4, &thread_count);
531 ok(thread_count == 4, "expected 4 threads, got %d\n", thread_count);
533 pomp_set_num_threads(max_threads);
534 pomp_set_nested(FALSE);
537 static void CDECL fork_ptr_cb(LONG *a, LONG *b, LONG *c, LONG *d, LONG *e)
539 InterlockedIncrement(a);
540 InterlockedIncrement(b);
541 InterlockedIncrement(c);
542 InterlockedIncrement(d);
543 InterlockedIncrement(e);
546 static void CDECL fork_uintptr_cb(UINT_PTR a, UINT_PTR b, UINT_PTR c, UINT_PTR d, UINT_PTR e)
548 ok(a == 1, "expected a == 1, got %p\n", (void *)a);
549 ok(b == MAXUINT_PTR - 2, "expected b == MAXUINT_PTR - 2, got %p\n", (void *)b);
550 ok(c == 3, "expected c == 3, got %p\n", (void *)c);
551 ok(d == MAXUINT_PTR - 4, "expected d == MAXUINT_PTR - 4, got %p\n", (void *)d);
552 ok(e == 5, "expected e == 5, got %p\n", (void *)e);
555 #ifdef __i386__
556 static void CDECL fork_float_cb(float a, float b, float c, float d, float e)
558 ok(1.4999 < a && a < 1.5001, "expected a == 1.5, got %f\n", a);
559 ok(2.4999 < b && b < 2.5001, "expected b == 2.5, got %f\n", b);
560 ok(3.4999 < c && c < 3.5001, "expected c == 3.5, got %f\n", c);
561 ok(4.4999 < d && d < 4.5001, "expected d == 4.5, got %f\n", d);
562 ok(5.4999 < e && e < 5.5001, "expected e == 5.5, got %f\n", e);
564 #endif
566 static void test_vcomp_fork(void)
568 LONG a, b, c, d, e;
569 int max_threads = pomp_get_max_threads();
570 pomp_set_num_threads(4);
572 a = 0; b = 1; c = 2; d = 3; e = 4;
573 p_vcomp_fork(FALSE, 5, fork_ptr_cb, &a, &b, &c, &d, &e);
574 ok(a == 1, "expected a == 1, got %d\n", a);
575 ok(b == 2, "expected b == 2, got %d\n", b);
576 ok(c == 3, "expected c == 3, got %d\n", c);
577 ok(d == 4, "expected d == 4, got %d\n", d);
578 ok(e == 5, "expected e == 5, got %d\n", e);
580 a = 0; b = 1; c = 2; d = 3; e = 4;
581 p_vcomp_fork(TRUE, 5, fork_ptr_cb, &a, &b, &c, &d, &e);
582 ok(a == 4, "expected a == 4, got %d\n", a);
583 ok(b == 5, "expected b == 5, got %d\n", b);
584 ok(c == 6, "expected c == 6, got %d\n", c);
585 ok(d == 7, "expected d == 7, got %d\n", d);
586 ok(e == 8, "expected e == 8, got %d\n", e);
588 p_vcomp_fork(TRUE, 5, fork_uintptr_cb, (UINT_PTR)1, (UINT_PTR)(MAXUINT_PTR - 2),
589 (UINT_PTR)3, (UINT_PTR)(MAXUINT_PTR - 4), (UINT_PTR)5);
591 #ifdef __i386__
593 void (CDECL *func)(BOOL, int, void *, float, float, float, float, float) = (void *)p_vcomp_fork;
594 func(TRUE, 5, fork_float_cb, 1.5f, 2.5f, 3.5f, 4.5f, 5.5f);
596 #else
597 skip("skipping float test on non-x86\n");
598 #endif
600 pomp_set_num_threads(max_threads);
603 static void CDECL section_cb(LONG *a, LONG *b, LONG *c)
605 int i;
607 p_vcomp_sections_init(20);
608 while ((i = p_vcomp_sections_next()) != -1)
610 InterlockedIncrement(a);
611 Sleep(1);
614 p_vcomp_sections_init(30);
615 while ((i = p_vcomp_sections_next()) != -1)
617 InterlockedIncrement(b);
618 Sleep(1);
621 p_vcomp_sections_init(40);
622 while ((i = p_vcomp_sections_next()) != -1)
624 InterlockedIncrement(c);
625 Sleep(1);
629 static void test_vcomp_sections_init(void)
631 LONG a, b, c;
632 int max_threads = pomp_get_max_threads();
633 int i;
635 if (0)
637 /* calling _vcomp_sections_next without prior _vcomp_sections_init
638 * returns uninitialized memory on Windows. */
639 i = p_vcomp_sections_next();
640 ok(i == -1, "expected -1, got %d\n", i);
643 a = b = c = 0;
644 section_cb(&a, &b, &c);
645 ok(a == 20, "expected a == 20, got %d\n", a);
646 ok(b == 30, "expected b == 30, got %d\n", b);
647 ok(c == 40, "expected c == 40, got %d\n", c);
649 for (i = 1; i <= 4; i++)
651 pomp_set_num_threads(i);
653 a = b = c = 0;
654 p_vcomp_fork(TRUE, 3, section_cb, &a, &b, &c);
655 ok(a == 20, "expected a == 20, got %d\n", a);
656 ok(b == 30, "expected b == 30, got %d\n", b);
657 ok(c == 40, "expected c == 40, got %d\n", c);
659 a = b = c = 0;
660 p_vcomp_fork(FALSE, 3, section_cb, &a, &b, &c);
661 ok(a == 20, "expected a == 20, got %d\n", a);
662 ok(b == 30, "expected b == 30, got %d\n", b);
663 ok(c == 40, "expected c == 40, got %d\n", c);
666 pomp_set_num_threads(max_threads);
669 static void my_for_static_simple_init(BOOL dynamic, unsigned int first, unsigned int last, int step,
670 BOOL increment, unsigned int *begin, unsigned int *end)
672 unsigned int iterations, per_thread, remaining;
673 int num_threads = pomp_get_num_threads();
674 int thread_num = pomp_get_thread_num();
676 if (!dynamic && num_threads == 1)
678 *begin = first;
679 *end = last;
680 return;
683 if (step <= 0)
685 *begin = 0;
686 *end = increment ? -1 : 1;
687 return;
690 if (increment)
691 iterations = 1 + (last - first) / step;
692 else
694 iterations = 1 + (first - last) / step;
695 step *= -1;
698 per_thread = iterations / num_threads;
699 remaining = iterations - per_thread * num_threads;
701 if (thread_num < remaining)
702 per_thread++;
703 else if (per_thread)
704 first += remaining * step;
705 else
707 *begin = first;
708 *end = first - step;
709 return;
712 *begin = first + per_thread * thread_num * step;
713 *end = *begin + (per_thread - 1) * step;
717 static void CDECL for_static_simple_cb(void)
719 static const struct
721 unsigned int first;
722 unsigned int last;
723 int step;
725 tests[] =
727 { 0, 0, 1 }, /* 0 */
728 { 0, 1, 1 },
729 { 0, 2, 1 },
730 { 0, 3, 1 },
731 { 0, 100, 0 },
732 { 0, 100, 1 },
733 { 0, 100, 2 },
734 { 0, 100, 3 },
735 { 0, 100, -1 },
736 { 0, 100, -2 },
737 { 0, 100, -3 }, /* 10 */
738 { 0, 100, 10 },
739 { 0, 100, 50 },
740 { 0, 100, 100 },
741 { 0, 100, 150 },
742 { 0, 0x80000000, 1 },
743 { 0, 0xfffffffe, 1 },
744 { 0, 0xffffffff, 1 },
745 { 50, 50, 0 },
746 { 50, 50, 1 },
747 { 50, 50, 2 }, /* 20 */
748 { 50, 50, 3 },
749 { 50, 50, -1 },
750 { 50, 50, -2 },
751 { 50, 50, -3 },
752 { 100, 200, 1 },
753 { 100, 200, 5 },
754 { 100, 200, 10 },
755 { 100, 200, 50 },
756 { 100, 200, 100 },
757 { 100, 200, 150 }, /* 30 */
759 int num_threads = pomp_get_num_threads();
760 int thread_num = pomp_get_thread_num();
761 int i;
763 for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++)
765 unsigned int my_begin, my_end, begin, end;
767 begin = end = 0xdeadbeef;
768 my_for_static_simple_init(FALSE, tests[i].first, tests[i].last, tests[i].step, FALSE, &my_begin, &my_end);
769 p_vcomp_for_static_simple_init(tests[i].first, tests[i].last, tests[i].step, FALSE, &begin, &end);
771 ok(begin == my_begin, "test %d, thread %d/%d: expected begin == %u, got %u\n",
772 i, thread_num, num_threads, my_begin, begin);
773 ok(end == my_end, "test %d, thread %d/%d: expected end == %u, got %u\n",
774 i, thread_num, num_threads, my_end, end);
776 p_vcomp_for_static_end();
777 p_vcomp_barrier();
779 begin = end = 0xdeadbeef;
780 my_for_static_simple_init(FALSE, tests[i].first, tests[i].last, tests[i].step, TRUE, &my_begin, &my_end);
781 p_vcomp_for_static_simple_init(tests[i].first, tests[i].last, tests[i].step, TRUE, &begin, &end);
783 ok(begin == my_begin, "test %d, thread %d/%d: expected begin == %u, got %u\n",
784 i, thread_num, num_threads, my_begin, begin);
785 ok(end == my_end, "test %d, thread %d/%d: expected end == %u, got %u\n",
786 i, thread_num, num_threads, my_end, end);
788 p_vcomp_for_static_end();
789 p_vcomp_barrier();
791 if (tests[i].first == tests[i].last) continue;
793 begin = end = 0xdeadbeef;
794 my_for_static_simple_init(FALSE, tests[i].last, tests[i].first, tests[i].step, FALSE, &my_begin, &my_end);
795 p_vcomp_for_static_simple_init(tests[i].last, tests[i].first, tests[i].step, FALSE, &begin, &end);
797 ok(begin == my_begin, "test %d, thread %d/%d: expected begin == %u, got %u\n",
798 i, thread_num, num_threads, my_begin, begin);
799 ok(end == my_end, "test %d, thread %d/%d: expected end == %u, got %u\n",
800 i, thread_num, num_threads, my_end, end);
802 p_vcomp_for_static_end();
803 p_vcomp_barrier();
805 begin = end = 0xdeadbeef;
806 my_for_static_simple_init(FALSE, tests[i].last, tests[i].first, tests[i].step, TRUE, &my_begin, &my_end);
807 p_vcomp_for_static_simple_init(tests[i].last, tests[i].first, tests[i].step, TRUE, &begin, &end);
809 ok(begin == my_begin, "test %d, thread %d/%d: expected begin == %u, got %u\n",
810 i, thread_num, num_threads, my_begin, begin);
811 ok(end == my_end, "test %d, thread %d/%d: expected end == %u, got %u\n",
812 i, thread_num, num_threads, my_end, end);
814 p_vcomp_for_static_end();
815 p_vcomp_barrier();
819 static void test_vcomp_for_static_simple_init(void)
821 int max_threads = pomp_get_max_threads();
822 int i;
824 for_static_simple_cb();
826 for (i = 1; i <= 4; i++)
828 pomp_set_num_threads(i);
829 p_vcomp_fork(TRUE, 0, for_static_simple_cb);
830 p_vcomp_fork(FALSE, 0, for_static_simple_cb);
833 pomp_set_num_threads(max_threads);
836 #define VCOMP_FOR_STATIC_BROKEN_LOOP 1
837 #define VCOMP_FOR_STATIC_BROKEN_NEXT 2
839 static DWORD CDECL my_for_static_init(int first, int last, int step, int chunksize, unsigned int *loops,
840 int *begin, int *end, int *next, int *lastchunk)
842 unsigned int iterations, num_chunks, per_thread, remaining;
843 int num_threads = pomp_get_num_threads();
844 int thread_num = pomp_get_thread_num();
846 if (num_threads == 1 && chunksize != 1)
848 *loops = 1;
849 *begin = first;
850 *end = last;
851 *next = 0;
852 *lastchunk = first;
853 return 0;
856 if (first == last)
858 *loops = !thread_num;
859 if (!thread_num)
861 /* The value in *next on Windows is either uninitialized, or contains
862 * garbage. The value shouldn't matter for *loops <= 1, so no need to
863 * reproduce that. */
864 *begin = first;
865 *end = last;
866 *next = 0;
867 *lastchunk = first;
869 return thread_num ? 0 : VCOMP_FOR_STATIC_BROKEN_NEXT;
872 if (step <= 0)
874 /* The total number of iterations depends on the number of threads here,
875 * which doesn't make any sense. This is most likely a bug in the Windows
876 * implementation. */
877 return VCOMP_FOR_STATIC_BROKEN_LOOP;
880 if (first < last)
881 iterations = 1 + (last - first) / step;
882 else
884 iterations = 1 + (first - last) / step;
885 step *= -1;
888 if (chunksize < 1)
889 chunksize = 1;
891 num_chunks = ((DWORD64)iterations + chunksize - 1) / chunksize;
892 per_thread = num_chunks / num_threads;
893 remaining = num_chunks - per_thread * num_threads;
895 *loops = per_thread + (thread_num < remaining);
896 *begin = first + thread_num * chunksize * step;
897 *end = *begin + (chunksize - 1) * step;
898 *next = chunksize * num_threads * step;
899 *lastchunk = first + (num_chunks - 1) * chunksize * step;
900 return 0;
903 static void CDECL for_static_cb(void)
905 static const struct
907 int first;
908 int last;
909 int step;
910 int chunksize;
912 tests[] =
914 { 0, 0, 1, 1 }, /* 0 */
915 { 0, 1, 1, 1 },
916 { 0, 2, 1, 1 },
917 { 0, 3, 1, 1 },
918 { 0, 100, 1, 0 },
919 { 0, 100, 1, 1 },
920 { 0, 100, 1, 5 },
921 { 0, 100, 1, 10 },
922 { 0, 100, 1, 50 },
923 { 0, 100, 1, 100 },
924 { 0, 100, 1, 150 }, /* 10 */
925 { 0, 100, 3, 0 },
926 { 0, 100, 3, 1 },
927 { 0, 100, 3, 5 },
928 { 0, 100, 3, 10 },
929 { 0, 100, 3, 50 },
930 { 0, 100, 3, 100 },
931 { 0, 100, 3, 150 },
932 { 0, 100, 5, 1 },
933 { 0, 100, -3, 0 },
934 { 0, 100, -3, 1 }, /* 20 */
935 { 0, 100, -3, 5 },
936 { 0, 100, -3, 10 },
937 { 0, 100, -3, 50 },
938 { 0, 100, -3, 100 },
939 { 0, 100, -3, 150 },
940 { 0, 100, 10, 1 },
941 { 0, 100, 50, 1 },
942 { 0, 100, 100, 1 },
943 { 0, 100, 150, 1 },
944 { 0, 0x10000000, 1, 123 }, /* 30 */
945 { 0, 0x20000000, 1, 123 },
946 { 0, 0x40000000, 1, 123 },
947 { 0, -0x80000000, 1, 123 },
948 { 50, 50, 1, 1 },
949 { 50, 50, 1, 2 },
950 { 50, 50, 1, -1 },
951 { 50, 50, 1, -2 },
952 { 50, 50, 2, 1 },
953 { 50, 50, 3, 1 },
954 { 100, 200, 3, 1 }, /* 40 */
955 { 100, 200, 3, -1 },
956 { 0x7ffffffe, -0x80000000, 1, 123 },
957 { 0x7fffffff, -0x80000000, 1, 123 },
959 int num_threads = pomp_get_num_threads();
960 int thread_num = pomp_get_thread_num();
961 int i;
963 for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++)
965 int my_begin, my_end, my_next, my_lastchunk;
966 int begin, end, next, lastchunk;
967 unsigned int my_loops, loops;
968 DWORD broken_flags;
970 my_loops = my_begin = my_end = my_next = my_lastchunk = 0xdeadbeef;
971 loops = begin = end = next = lastchunk = 0xdeadbeef;
972 broken_flags = my_for_static_init(tests[i].first, tests[i].last, tests[i].step, tests[i].chunksize,
973 &my_loops, &my_begin, &my_end, &my_next, &my_lastchunk);
974 p_vcomp_for_static_init(tests[i].first, tests[i].last, tests[i].step, tests[i].chunksize,
975 &loops, &begin, &end, &next, &lastchunk);
977 if (broken_flags & VCOMP_FOR_STATIC_BROKEN_LOOP)
979 ok(loops == 0 || loops == 1, "test %d, thread %d/%d: expected loops == 0 or 1, got %u\n",
980 i, thread_num, num_threads, loops);
982 else
984 ok(loops == my_loops, "test %d, thread %d/%d: expected loops == %u, got %u\n",
985 i, thread_num, num_threads, my_loops, loops);
986 ok(begin == my_begin, "test %d, thread %d/%d: expected begin == %d, got %d\n",
987 i, thread_num, num_threads, my_begin, begin);
988 ok(end == my_end, "test %d, thread %d/%d: expected end == %d, got %d\n",
989 i, thread_num, num_threads, my_end, end);
990 ok(next == my_next || broken(broken_flags & VCOMP_FOR_STATIC_BROKEN_NEXT),
991 "test %d, thread %d/%d: expected next == %d, got %d\n", i, thread_num, num_threads, my_next, next);
992 ok(lastchunk == my_lastchunk, "test %d, thread %d/%d: expected lastchunk == %d, got %d\n",
993 i, thread_num, num_threads, my_lastchunk, lastchunk);
996 p_vcomp_for_static_end();
997 p_vcomp_barrier();
999 if (tests[i].first == tests[i].last) continue;
1001 my_loops = my_begin = my_end = my_next = my_lastchunk = 0xdeadbeef;
1002 loops = begin = end = next = lastchunk = 0xdeadbeef;
1003 broken_flags = my_for_static_init(tests[i].last, tests[i].first, tests[i].step, tests[i].chunksize,
1004 &my_loops, &my_begin, &my_end, &my_next, &my_lastchunk);
1005 p_vcomp_for_static_init(tests[i].last, tests[i].first, tests[i].step, tests[i].chunksize,
1006 &loops, &begin, &end, &next, &lastchunk);
1008 if (broken_flags & VCOMP_FOR_STATIC_BROKEN_LOOP)
1010 ok(loops == 0 || loops == 1, "test %d, thread %d/%d: expected loops == 0 or 1, got %u\n",
1011 i, thread_num, num_threads, loops);
1013 else
1015 ok(loops == my_loops, "test %d, thread %d/%d: expected loops == %u, got %u\n",
1016 i, thread_num, num_threads, my_loops, loops);
1017 ok(begin == my_begin, "test %d, thread %d/%d: expected begin == %d, got %d\n",
1018 i, thread_num, num_threads, my_begin, begin);
1019 ok(end == my_end, "test %d, thread %d/%d: expected end == %d, got %d\n",
1020 i, thread_num, num_threads, my_end, end);
1021 ok(next == my_next || broken(broken_flags & VCOMP_FOR_STATIC_BROKEN_NEXT),
1022 "test %d, thread %d/%d: expected next == %d, got %d\n", i, thread_num, num_threads, my_next, next);
1023 ok(lastchunk == my_lastchunk, "test %d, thread %d/%d: expected lastchunk == %d, got %d\n",
1024 i, thread_num, num_threads, my_lastchunk, lastchunk);
1027 p_vcomp_for_static_end();
1028 p_vcomp_barrier();
1032 #undef VCOMP_FOR_STATIC_BROKEN_LOOP
1033 #undef VCOMP_FOR_STATIC_BROKEN_NEXT
1035 static void test_vcomp_for_static_init(void)
1037 int max_threads = pomp_get_max_threads();
1038 int i;
1040 for_static_cb();
1042 for (i = 1; i <= 4; i++)
1044 pomp_set_num_threads(i);
1045 p_vcomp_fork(TRUE, 0, for_static_cb);
1046 p_vcomp_fork(FALSE, 0, for_static_cb);
1049 pomp_set_num_threads(max_threads);
1052 static void CDECL for_dynamic_static_cb(void)
1054 unsigned int my_begin, my_end, begin, end;
1055 int ret;
1057 begin = end = 0xdeadbeef;
1058 my_for_static_simple_init(TRUE, 0, 1000, 7, TRUE, &my_begin, &my_end);
1059 p_vcomp_for_dynamic_init(VCOMP_DYNAMIC_FLAGS_STATIC | VCOMP_DYNAMIC_FLAGS_INCREMENT, 0, 1000, 7, 1);
1060 ret = p_vcomp_for_dynamic_next(&begin, &end);
1061 ok(ret == TRUE, "expected ret == TRUE, got %d\n", ret);
1062 ok(begin == my_begin, "expected begin == %u, got %u\n", my_begin, begin);
1063 ok(end == my_end, "expected end == %u, got %u\n", my_end, end);
1064 ret = p_vcomp_for_dynamic_next(&begin, &end);
1065 ok(ret == FALSE, "expected ret == FALSE, got %d\n", ret);
1067 begin = end = 0xdeadbeef;
1068 my_for_static_simple_init(TRUE, 1000, 0, 7, FALSE, &my_begin, &my_end);
1069 p_vcomp_for_dynamic_init(VCOMP_DYNAMIC_FLAGS_STATIC, 1000, 0, 7, 1);
1070 ret = p_vcomp_for_dynamic_next(&begin, &end);
1071 ok(ret == TRUE, "expected ret == TRUE, got %d\n", ret);
1072 ok(begin == my_begin, "expected begin == %u, got %u\n", my_begin, begin);
1073 ok(end == my_end, "expected end == %u, got %u\n", my_end, end);
1074 ret = p_vcomp_for_dynamic_next(&begin, &end);
1075 ok(ret == FALSE, "expected ret == FALSE, got %d\n", ret);
1077 begin = end = 0xdeadbeef;
1078 my_for_static_simple_init(TRUE, 0, 1000, 7, TRUE, &my_begin, &my_end);
1079 p_vcomp_for_dynamic_init(VCOMP_DYNAMIC_FLAGS_STATIC | VCOMP_DYNAMIC_FLAGS_INCREMENT, 0, 1000, 7, 5);
1080 ret = p_vcomp_for_dynamic_next(&begin, &end);
1081 ok(ret == TRUE, "expected ret == TRUE, got %d\n", ret);
1082 ok(begin == my_begin, "expected begin == %u, got %u\n", my_begin, begin);
1083 ok(end == my_end, "expected end == %u, got %u\n", my_end, end);
1084 ret = p_vcomp_for_dynamic_next(&begin, &end);
1085 ok(ret == FALSE, "expected ret == FALSE, got %d\n", ret);
1087 begin = end = 0xdeadbeef;
1088 my_for_static_simple_init(TRUE, 1000, 0, 7, FALSE, &my_begin, &my_end);
1089 p_vcomp_for_dynamic_init(VCOMP_DYNAMIC_FLAGS_STATIC, 1000, 0, 7, 5);
1090 ret = p_vcomp_for_dynamic_next(&begin, &end);
1091 ok(ret == TRUE, "expected ret == TRUE, got %d\n", ret);
1092 ok(begin == my_begin, "expected begin == %u, got %u\n", my_begin, begin);
1093 ok(end == my_end, "expected end == %u, got %u\n", my_end, end);
1094 ret = p_vcomp_for_dynamic_next(&begin, &end);
1095 ok(ret == FALSE, "expected ret == FALSE, got %d\n", ret);
1098 static void CDECL for_dynamic_chunked_cb(LONG *a, LONG *b, LONG *c, LONG *d)
1100 unsigned int begin, end;
1102 p_vcomp_for_dynamic_init(VCOMP_DYNAMIC_FLAGS_CHUNKED | VCOMP_DYNAMIC_FLAGS_INCREMENT, 0, 1000, 7, 1);
1103 while (p_vcomp_for_dynamic_next(&begin, &end))
1105 if (begin == 994) ok(end == 1000, "expected end == 1000, got %u\n", end);
1106 else ok(begin == end, "expected begin == end, got %u and %u\n", begin, end);
1107 InterlockedExchangeAdd(a, begin);
1110 p_vcomp_for_dynamic_init(VCOMP_DYNAMIC_FLAGS_CHUNKED, 1000, 0, 7, 1);
1111 while (p_vcomp_for_dynamic_next(&begin, &end))
1113 if (begin == 6) ok(end == 0, "expected end == 0, got %u\n", end);
1114 else ok(begin == end, "expected begin == end, got %u and %u\n", begin, end);
1115 InterlockedExchangeAdd(b, begin);
1118 p_vcomp_for_dynamic_init(VCOMP_DYNAMIC_FLAGS_CHUNKED | VCOMP_DYNAMIC_FLAGS_INCREMENT, 0, 1000, 7, 5);
1119 while (p_vcomp_for_dynamic_next(&begin, &end))
1121 if (begin == 980) ok(end == 1000, "expected end == 1000, got %u\n", end);
1122 else ok(begin + 28 == end, "expected begin + 28 == end, got %u and %u\n", begin + 28, end);
1123 InterlockedExchangeAdd(c, begin);
1126 p_vcomp_for_dynamic_init(VCOMP_DYNAMIC_FLAGS_CHUNKED, 1000, 0, 7, 5);
1127 while (p_vcomp_for_dynamic_next(&begin, &end))
1129 if (begin == 20) ok(end == 0, "expected end == 0, got %u\n", end);
1130 else ok(begin - 28 == end, "expected begin - 28 == end, got %u and %u\n", begin - 28, end);
1131 InterlockedExchangeAdd(d, begin);
1135 static void CDECL for_dynamic_guided_cb(unsigned int flags, LONG *a, LONG *b, LONG *c, LONG *d)
1137 int num_threads = pomp_get_num_threads();
1138 unsigned int begin, end;
1140 p_vcomp_for_dynamic_init(flags | VCOMP_DYNAMIC_FLAGS_INCREMENT, 0, 1000, 7, 1);
1141 while (p_vcomp_for_dynamic_next(&begin, &end))
1143 ok(num_threads != 1 || (begin == 0 && end == 1000),
1144 "expected begin == 0 and end == 1000, got %u and %u\n", begin, end);
1145 InterlockedExchangeAdd(a, begin);
1148 p_vcomp_for_dynamic_init(flags, 1000, 0, 7, 1);
1149 while (p_vcomp_for_dynamic_next(&begin, &end))
1151 ok(num_threads != 1 || (begin == 1000 && end == 0),
1152 "expected begin == 1000 and end == 0, got %u and %u\n", begin, end);
1153 InterlockedExchangeAdd(b, begin);
1156 p_vcomp_for_dynamic_init(flags | VCOMP_DYNAMIC_FLAGS_INCREMENT, 0, 1000, 7, 5);
1157 while (p_vcomp_for_dynamic_next(&begin, &end))
1159 ok(num_threads != 1 || (begin == 0 && end == 1000),
1160 "expected begin == 0 and end == 1000, got %u and %u\n", begin, end);
1161 InterlockedExchangeAdd(c, begin);
1164 p_vcomp_for_dynamic_init(flags, 1000, 0, 7, 5);
1165 while (p_vcomp_for_dynamic_next(&begin, &end))
1167 ok(num_threads != 1 || (begin == 1000 && end == 0),
1168 "expected begin == 1000 and end == 0, got %u and %u\n", begin, end);
1169 InterlockedExchangeAdd(d, begin);
1173 static void test_vcomp_for_dynamic_init(void)
1175 static const int guided_a[] = {0, 6041, 9072, 11179};
1176 static const int guided_b[] = {1000, 1959, 2928, 3821};
1177 static const int guided_c[] = {0, 4067, 6139, 7273};
1178 static const int guided_d[] = {1000, 1933, 2861, 3727};
1179 LONG a, b, c, d;
1180 int max_threads = pomp_get_max_threads();
1181 int i;
1183 /* test static scheduling */
1184 for_dynamic_static_cb();
1186 for (i = 1; i <= 4; i++)
1188 pomp_set_num_threads(i);
1189 p_vcomp_fork(TRUE, 0, for_dynamic_static_cb);
1190 p_vcomp_fork(FALSE, 0, for_dynamic_static_cb);
1193 /* test chunked scheduling */
1194 a = b = c = d = 0;
1195 for_dynamic_chunked_cb(&a, &b, &c, &d);
1196 ok(a == 71071, "expected a == 71071, got %d\n", a);
1197 ok(b == 71929, "expected b == 71929, got %d\n", b);
1198 ok(c == 14210, "expected c == 14210, got %d\n", c);
1199 ok(d == 14790, "expected d == 14790, got %d\n", d);
1201 for (i = 1; i <= 4; i++)
1203 pomp_set_num_threads(i);
1205 a = b = c = d = 0;
1206 p_vcomp_fork(TRUE, 4, for_dynamic_chunked_cb, &a, &b, &c, &d);
1207 ok(a == 71071, "expected a == 71071, got %d\n", a);
1208 ok(b == 71929, "expected b == 71929, got %d\n", b);
1209 ok(c == 14210, "expected c == 14210, got %d\n", c);
1210 ok(d == 14790, "expected d == 14790, got %d\n", d);
1212 a = b = c = d = 0;
1213 p_vcomp_fork(FALSE, 4, for_dynamic_chunked_cb, &a, &b, &c, &d);
1214 ok(a == 71071, "expected a == 71071, got %d\n", a);
1215 ok(b == 71929, "expected b == 71929, got %d\n", b);
1216 ok(c == 14210, "expected c == 14210, got %d\n", c);
1217 ok(d == 14790, "expected d == 14790, got %d\n", d);
1220 /* test guided scheduling */
1221 a = b = c = d = 0;
1222 for_dynamic_guided_cb(VCOMP_DYNAMIC_FLAGS_GUIDED, &a, &b, &c, &d);
1223 ok(a == guided_a[0], "expected a == %d, got %d\n", guided_a[0], a);
1224 ok(b == guided_b[0], "expected b == %d, got %d\n", guided_b[0], b);
1225 ok(c == guided_c[0], "expected c == %d, got %d\n", guided_c[0], c);
1226 ok(d == guided_d[0], "expected d == %d, got %d\n", guided_d[0], d);
1228 for (i = 1; i <= 4; i++)
1230 pomp_set_num_threads(i);
1232 a = b = c = d = 0;
1233 p_vcomp_fork(TRUE, 5, for_dynamic_guided_cb, VCOMP_DYNAMIC_FLAGS_GUIDED, &a, &b, &c, &d);
1234 ok(a == guided_a[i - 1], "expected a == %d, got %d\n", guided_a[i - 1], a);
1235 ok(b == guided_b[i - 1], "expected b == %d, got %d\n", guided_b[i - 1], b);
1236 ok(c == guided_c[i - 1], "expected c == %d, got %d\n", guided_c[i - 1], c);
1237 ok(d == guided_d[i - 1], "expected d == %d, got %d\n", guided_d[i - 1], d);
1239 a = b = c = d = 0;
1240 p_vcomp_fork(FALSE, 5, for_dynamic_guided_cb, VCOMP_DYNAMIC_FLAGS_GUIDED, &a, &b, &c, &d);
1241 ok(a == guided_a[0], "expected a == %d, got %d\n", guided_a[0], a);
1242 ok(b == guided_b[0], "expected b == %d, got %d\n", guided_b[0], b);
1243 ok(c == guided_c[0], "expected c == %d, got %d\n", guided_c[0], c);
1244 ok(d == guided_d[0], "expected d == %d, got %d\n", guided_d[0], d);
1247 /* test with empty flags */
1248 a = b = c = d = 0;
1249 for_dynamic_guided_cb(0, &a, &b, &c, &d);
1250 ok(a == guided_a[0], "expected a == %d, got %d\n", guided_a[0], a);
1251 ok(b == guided_b[0], "expected b == %d, got %d\n", guided_b[0], b);
1252 ok(c == guided_c[0], "expected c == %d, got %d\n", guided_c[0], c);
1253 ok(d == guided_d[0], "expected d == %d, got %d\n", guided_d[0], d);
1255 for (i = 1; i <= 4; i++)
1257 pomp_set_num_threads(i);
1259 a = b = c = d = 0;
1260 p_vcomp_fork(TRUE, 5, for_dynamic_guided_cb, 0, &a, &b, &c, &d);
1261 ok(a == guided_a[i - 1], "expected a == %d, got %d\n", guided_a[i - 1], a);
1262 ok(b == guided_b[i - 1], "expected b == %d, got %d\n", guided_b[i - 1], b);
1263 ok(c == guided_c[i - 1], "expected c == %d, got %d\n", guided_c[i - 1], c);
1264 ok(d == guided_d[i - 1], "expected d == %d, got %d\n", guided_d[i - 1], d);
1266 a = b = c = d = 0;
1267 p_vcomp_fork(FALSE, 5, for_dynamic_guided_cb, 0, &a, &b, &c, &d);
1268 ok(a == guided_a[0], "expected a == %d, got %d\n", guided_a[0], a);
1269 ok(b == guided_b[0], "expected b == %d, got %d\n", guided_b[0], b);
1270 ok(c == guided_c[0], "expected c == %d, got %d\n", guided_c[0], c);
1271 ok(d == guided_d[0], "expected d == %d, got %d\n", guided_d[0], d);
1274 pomp_set_num_threads(max_threads);
1277 static void CDECL master_cb(HANDLE semaphore)
1279 int num_threads = pomp_get_num_threads();
1280 int thread_num = pomp_get_thread_num();
1282 if (p_vcomp_master_begin())
1284 ok(thread_num == 0, "expected thread_num == 0, got %d\n", thread_num);
1285 if (num_threads >= 2)
1287 DWORD result = WaitForSingleObject(semaphore, 1000);
1288 ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %u\n", result);
1290 p_vcomp_master_end();
1293 if (thread_num == 1)
1294 ReleaseSemaphore(semaphore, 1, NULL);
1297 static void test_vcomp_master_begin(void)
1299 int max_threads = pomp_get_max_threads();
1300 HANDLE semaphore;
1301 int i;
1303 semaphore = CreateSemaphoreA(NULL, 0, 1, NULL);
1304 ok(semaphore != NULL, "CreateSemaphoreA failed %u\n", GetLastError());
1306 master_cb(semaphore);
1308 for (i = 1; i <= 4; i++)
1310 pomp_set_num_threads(i);
1311 p_vcomp_fork(TRUE, 1, master_cb, semaphore);
1312 p_vcomp_fork(FALSE, 1, master_cb, semaphore);
1315 CloseHandle(semaphore);
1316 pomp_set_num_threads(max_threads);
1319 static void CDECL single_cb(int flags, HANDLE semaphore)
1321 int num_threads = pomp_get_num_threads();
1323 if (p_vcomp_single_begin(flags))
1325 if (num_threads >= 2)
1327 DWORD result = WaitForSingleObject(semaphore, 1000);
1328 ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %u\n", result);
1331 p_vcomp_single_end();
1333 if (p_vcomp_single_begin(flags))
1335 if (num_threads >= 2)
1336 ReleaseSemaphore(semaphore, 1, NULL);
1338 p_vcomp_single_end();
1341 static void test_vcomp_single_begin(void)
1343 int max_threads = pomp_get_max_threads();
1344 HANDLE semaphore;
1345 int i;
1347 semaphore = CreateSemaphoreA(NULL, 0, 1, NULL);
1348 ok(semaphore != NULL, "CreateSemaphoreA failed %u\n", GetLastError());
1350 single_cb(0, semaphore);
1351 single_cb(1, semaphore);
1353 for (i = 1; i <= 4; i++)
1355 pomp_set_num_threads(i);
1356 p_vcomp_fork(TRUE, 2, single_cb, 0, semaphore);
1357 p_vcomp_fork(TRUE, 2, single_cb, 1, semaphore);
1358 p_vcomp_fork(FALSE, 2, single_cb, 0, semaphore);
1359 p_vcomp_fork(FALSE, 2, single_cb, 1, semaphore);
1362 CloseHandle(semaphore);
1363 pomp_set_num_threads(max_threads);
1366 static void CDECL critsect_cb(LONG *a)
1368 static CRITICAL_SECTION *critsect;
1369 LONG tmp;
1371 p_vcomp_enter_critsect(&critsect);
1372 tmp = *a;
1373 Sleep(50);
1374 *a = tmp + 1;
1375 p_vcomp_leave_critsect(critsect);
1377 ok(critsect != NULL, "expected critsect != NULL\n");
1379 EnterCriticalSection(critsect);
1380 tmp = *a;
1381 Sleep(50);
1382 *a = tmp + 1;
1383 LeaveCriticalSection(critsect);
1386 static void test_vcomp_enter_critsect(void)
1388 int max_threads = pomp_get_max_threads();
1389 LONG a;
1390 int i;
1392 a = 0;
1393 critsect_cb(&a);
1394 ok(a == 2, "expected a == 2, got %d\n", a);
1396 for (i = 1; i <= 4; i++)
1398 pomp_set_num_threads(i);
1400 a = 0;
1401 p_vcomp_fork(TRUE, 1, critsect_cb, &a);
1402 ok(a == 2 * i, "expected a == %d, got %d\n", 2 * i, a);
1404 a = 0;
1405 p_vcomp_fork(FALSE, 1, critsect_cb, &a);
1406 ok(a == 2, "expected a == 2, got %d\n", a);
1409 pomp_set_num_threads(max_threads);
1412 static void test_vcomp_flush(void)
1414 p_vcomp_flush();
1415 p_vcomp_flush();
1416 p_vcomp_flush();
1419 static void test_omp_init_lock(void)
1421 omp_lock_t lock;
1422 int ret;
1424 pomp_init_lock(&lock);
1426 /* test omp_set_lock */
1427 pomp_set_lock(&lock);
1428 pomp_unset_lock(&lock);
1430 /* test omp_test_lock */
1431 ret = pomp_test_lock(&lock);
1432 ok(ret == 1, "expected ret == 1, got %d\n", ret);
1433 ret = pomp_test_lock(&lock);
1434 ok(ret == 0, "expected ret == 0, got %d\n", ret);
1435 pomp_unset_lock(&lock);
1437 /* test with EnterCriticalSection */
1438 EnterCriticalSection(lock);
1439 ret = pomp_test_lock(&lock);
1440 todo_wine
1441 ok(ret == 1, "expected ret == 1, got %d\n", ret);
1442 if (ret)
1444 ret = pomp_test_lock(&lock);
1445 ok(ret == 0, "expected ret == 0, got %d\n", ret);
1446 pomp_unset_lock(&lock);
1448 LeaveCriticalSection(lock);
1450 pomp_destroy_lock(&lock);
1453 static void test_omp_init_nest_lock(void)
1455 omp_nest_lock_t lock;
1456 int ret;
1458 ok(pomp_init_nest_lock == pomp_init_lock, "expected omp_init_nest_lock == %p, got %p\n",
1459 pomp_init_lock, pomp_init_nest_lock);
1460 ok(pomp_destroy_nest_lock == pomp_destroy_lock, "expected omp_destroy_nest_lock == %p, got %p\n",
1461 pomp_destroy_lock, pomp_destroy_nest_lock);
1463 pomp_init_nest_lock(&lock);
1465 /* test omp_set_nest_lock */
1466 pomp_set_nest_lock(&lock);
1467 pomp_set_nest_lock(&lock);
1468 pomp_unset_nest_lock(&lock);
1469 pomp_unset_nest_lock(&lock);
1471 /* test omp_test_nest_lock */
1472 ret = pomp_test_nest_lock(&lock);
1473 ok(ret == 1, "expected ret == 1, got %d\n", ret);
1474 ret = pomp_test_nest_lock(&lock);
1475 ok(ret == 2, "expected ret == 2, got %d\n", ret);
1476 ret = pomp_test_nest_lock(&lock);
1477 ok(ret == 3, "expected ret == 3, got %d\n", ret);
1478 pomp_unset_nest_lock(&lock);
1479 pomp_unset_nest_lock(&lock);
1480 pomp_unset_nest_lock(&lock);
1482 /* test with EnterCriticalSection */
1483 EnterCriticalSection(lock);
1484 ret = pomp_test_nest_lock(&lock);
1485 todo_wine
1486 ok(ret == 1, "expected ret == 1, got %d\n", ret);
1487 pomp_unset_nest_lock(&lock);
1488 LeaveCriticalSection(lock);
1490 pomp_destroy_nest_lock(&lock);
1493 static void test_atomic_integer8(void)
1495 struct
1497 void (CDECL *func)(char *, char);
1498 char v1, v2, expected;
1500 tests1[] =
1502 { p_vcomp_atomic_add_i1, 0x11, 0x77, -0x78 },
1503 { p_vcomp_atomic_and_i1, 0x11, 0x77, 0x11 },
1504 { p_vcomp_atomic_div_i1, 0x77, 0x11, 7 },
1505 { p_vcomp_atomic_div_i1, 0x77, -0x11, -7 },
1506 { p_vcomp_atomic_mul_i1, 0x11, 0x77, -0x19 },
1507 { p_vcomp_atomic_mul_i1, 0x11, -0x77, 0x19 },
1508 { p_vcomp_atomic_or_i1, 0x11, 0x77, 0x77 },
1509 { p_vcomp_atomic_sub_i1, 0x11, 0x77, -0x66 },
1510 { p_vcomp_atomic_xor_i1, 0x11, 0x77, 0x66 },
1512 struct
1514 void (CDECL *func)(char *, unsigned int);
1515 char v1;
1516 unsigned int v2;
1517 char expected;
1519 tests2[] =
1521 { p_vcomp_atomic_shl_i1, 0x11, 3, -0x78 },
1522 { p_vcomp_atomic_shl_i1, -0x11, 3, 0x78 },
1523 { p_vcomp_atomic_shr_i1, 0x11, 3, 2 },
1524 { p_vcomp_atomic_shr_i1, -0x11, 3, -3 },
1525 #if defined(__i386__) || defined(__x86_64__)
1526 { p_vcomp_atomic_shl_i1, 0x11, 11, 0 },
1527 { p_vcomp_atomic_shl_i1, 0x11, 19, 0 },
1528 { p_vcomp_atomic_shl_i1, 0x11, 35, -0x78 },
1529 { p_vcomp_atomic_shr_i1, 0x11, 11, 0 },
1530 { p_vcomp_atomic_shr_i1, 0x11, 19, 0 },
1531 { p_vcomp_atomic_shr_i1, 0x11, 35, 2 },
1532 #endif
1534 struct
1536 void (CDECL *func)(unsigned char *, unsigned char);
1537 unsigned char v1, v2, expected;
1539 tests3[] =
1541 { p_vcomp_atomic_div_ui1, 0x77, 0x11, 7 },
1542 { p_vcomp_atomic_div_ui1, 0x77, 0xef, 0 },
1544 struct
1546 void (CDECL *func)(unsigned char *, unsigned int);
1547 unsigned char v1;
1548 unsigned int v2;
1549 unsigned char expected;
1551 tests4[] =
1553 { p_vcomp_atomic_shr_ui1, 0x11, 3, 2 },
1554 { p_vcomp_atomic_shr_ui1, 0xef, 3, 0x1d },
1555 #if defined(__i386__) || defined(__x86_64__)
1556 { p_vcomp_atomic_shr_ui1, 0x11, 11, 0 },
1557 { p_vcomp_atomic_shr_ui1, 0x11, 19, 0 },
1558 { p_vcomp_atomic_shr_ui1, 0x11, 35, 2 },
1559 #endif
1561 int i;
1563 for (i = 0; i < sizeof(tests1)/sizeof(tests1[0]); i++)
1565 char val = tests1[i].v1;
1566 tests1[i].func(&val, tests1[i].v2);
1567 ok(val == tests1[i].expected, "test %d: expected val == %d, got %d\n", i, tests1[i].expected, val);
1569 for (i = 0; i < sizeof(tests2)/sizeof(tests2[0]); i++)
1571 char val = tests2[i].v1;
1572 tests2[i].func(&val, tests2[i].v2);
1573 ok(val == tests2[i].expected, "test %d: expected val == %d, got %d\n", i, tests2[i].expected, val);
1575 for (i = 0; i < sizeof(tests3)/sizeof(tests3[0]); i++)
1577 unsigned char val = tests3[i].v1;
1578 tests3[i].func(&val, tests3[i].v2);
1579 ok(val == tests3[i].expected, "test %d: expected val == %u, got %u\n", i, tests3[i].expected, val);
1581 for (i = 0; i < sizeof(tests4)/sizeof(tests4[0]); i++)
1583 unsigned char val = tests4[i].v1;
1584 tests4[i].func(&val, tests4[i].v2);
1585 ok(val == tests4[i].expected, "test %d: expected val == %u, got %u\n", i, tests4[i].expected, val);
1589 static void test_atomic_integer16(void)
1591 struct
1593 void (CDECL *func)(short *, short);
1594 short v1, v2, expected;
1596 tests1[] =
1598 { p_vcomp_atomic_add_i2, 0x1122, 0x7766, -0x7778 },
1599 { p_vcomp_atomic_and_i2, 0x1122, 0x7766, 0x1122 },
1600 { p_vcomp_atomic_div_i2, 0x7766, 0x1122, 6 },
1601 { p_vcomp_atomic_div_i2, 0x7766, -0x1122, -6 },
1602 { p_vcomp_atomic_mul_i2, 0x1122, 0x7766, -0x5e74 },
1603 { p_vcomp_atomic_mul_i2, 0x1122, -0x7766, 0x5e74 },
1604 { p_vcomp_atomic_or_i2, 0x1122, 0x7766, 0x7766 },
1605 { p_vcomp_atomic_sub_i2, 0x1122, 0x7766, -0x6644 },
1606 { p_vcomp_atomic_xor_i2, 0x1122, 0x7766, 0x6644 },
1608 struct
1610 void (CDECL *func)(short *, unsigned int);
1611 short v1;
1612 unsigned int v2;
1613 short expected;
1615 tests2[] =
1617 { p_vcomp_atomic_shl_i2, 0x1122, 3, -0x76f0 },
1618 { p_vcomp_atomic_shl_i2, -0x1122, 3, 0x76f0 },
1619 { p_vcomp_atomic_shr_i2, 0x1122, 3, 0x224 },
1620 { p_vcomp_atomic_shr_i2, -0x1122, 3, -0x225 },
1621 #if defined(__i386__) || defined(__x86_64__)
1622 { p_vcomp_atomic_shl_i2, 0x1122, 19, 0 },
1623 { p_vcomp_atomic_shl_i2, 0x1122, 35, -0x76f0 },
1624 { p_vcomp_atomic_shr_i2, 0x1122, 19, 0 },
1625 { p_vcomp_atomic_shr_i2, 0x1122, 35, 0x224 },
1626 #endif
1628 struct
1630 void (CDECL *func)(unsigned short *, unsigned short);
1631 unsigned short v1, v2, expected;
1633 tests3[] =
1635 { p_vcomp_atomic_div_ui2, 0x7766, 0x1122, 6 },
1636 { p_vcomp_atomic_div_ui2, 0x7766, 0xeede, 0 },
1638 struct
1640 void (CDECL *func)(unsigned short *, unsigned int);
1641 unsigned short v1;
1642 unsigned int v2;
1643 unsigned short expected;
1645 tests4[] =
1647 { p_vcomp_atomic_shr_ui2, 0x1122, 3, 0x224 },
1648 { p_vcomp_atomic_shr_ui2, 0xeede, 3, 0x1ddb },
1649 #if defined(__i386__) || defined(__x86_64__)
1650 { p_vcomp_atomic_shr_ui2, 0x1122, 19, 0 },
1651 { p_vcomp_atomic_shr_ui2, 0x1122, 35, 0x224 },
1652 #endif
1654 int i;
1656 for (i = 0; i < sizeof(tests1)/sizeof(tests1[0]); i++)
1658 short val = tests1[i].v1;
1659 tests1[i].func(&val, tests1[i].v2);
1660 ok(val == tests1[i].expected, "test %d: expected val == %d, got %d\n", i, tests1[i].expected, val);
1662 for (i = 0; i < sizeof(tests2)/sizeof(tests2[0]); i++)
1664 short val = tests2[i].v1;
1665 tests2[i].func(&val, tests2[i].v2);
1666 ok(val == tests2[i].expected, "test %d: expected val == %d, got %d\n", i, tests2[i].expected, val);
1668 for (i = 0; i < sizeof(tests3)/sizeof(tests3[0]); i++)
1670 unsigned short val = tests3[i].v1;
1671 tests3[i].func(&val, tests3[i].v2);
1672 ok(val == tests3[i].expected, "test %d: expected val == %u, got %u\n", i, tests3[i].expected, val);
1674 for (i = 0; i < sizeof(tests4)/sizeof(tests4[0]); i++)
1676 unsigned short val = tests4[i].v1;
1677 tests4[i].func(&val, tests4[i].v2);
1678 ok(val == tests4[i].expected, "test %d: expected val == %u, got %u\n", i, tests4[i].expected, val);
1682 static void test_atomic_integer32(void)
1684 struct
1686 void (CDECL *func)(int *, int);
1687 int v1, v2, expected;
1689 tests1[] =
1691 { p_vcomp_atomic_add_i4, 0x11223344, 0x77665544, -0x77777778 },
1692 { p_vcomp_atomic_and_i4, 0x11223344, 0x77665544, 0x11221144 },
1693 { p_vcomp_atomic_div_i4, 0x77665544, 0x11223344, 6 },
1694 { p_vcomp_atomic_div_i4, 0x77665544, -0x11223344, -6 },
1695 { p_vcomp_atomic_mul_i4, 0x11223344, 0x77665544, -0xecccdf0 },
1696 { p_vcomp_atomic_mul_i4, 0x11223344, -0x77665544, 0xecccdf0 },
1697 { p_vcomp_atomic_or_i4, 0x11223344, 0x77665544, 0x77667744 },
1698 { p_vcomp_atomic_shl_i4, 0x11223344, 3, -0x76ee65e0 },
1699 { p_vcomp_atomic_shl_i4, -0x11223344, 3, 0x76ee65e0 },
1700 { p_vcomp_atomic_shr_i4, 0x11223344, 3, 0x2244668 },
1701 { p_vcomp_atomic_shr_i4, -0x11223344, 3, -0x2244669 },
1702 { p_vcomp_atomic_sub_i4, 0x11223344, 0x77665544, -0x66442200 },
1703 { p_vcomp_atomic_xor_i4, 0x11223344, 0x77665544, 0x66446600 },
1704 #if defined(__i386__) || defined(__x86_64__)
1705 { p_vcomp_atomic_shl_i4, 0x11223344, 35, -0x76ee65e0 },
1706 { p_vcomp_atomic_shr_i4, 0x11223344, 35, 0x2244668 },
1707 #endif
1709 struct
1711 void (CDECL *func)(unsigned int *, unsigned int);
1712 unsigned int v1, v2, expected;
1714 tests2[] =
1716 { p_vcomp_atomic_div_ui4, 0x77665544, 0x11223344, 6 },
1717 { p_vcomp_atomic_div_ui4, 0x77665544, 0xeeddccbc, 0 },
1718 { p_vcomp_atomic_shr_ui4, 0x11223344, 3, 0x2244668 },
1719 { p_vcomp_atomic_shr_ui4, 0xeeddccbc, 3, 0x1ddbb997 },
1720 #if defined(__i386__) || defined(__x86_64__)
1721 { p_vcomp_atomic_shr_ui4, 0x11223344, 35, 0x2244668 },
1722 #endif
1724 int i;
1726 for (i = 0; i < sizeof(tests1)/sizeof(tests1[0]); i++)
1728 int val = tests1[i].v1;
1729 tests1[i].func(&val, tests1[i].v2);
1730 ok(val == tests1[i].expected, "test %d: expected val == %d, got %d\n", i, tests1[i].expected, val);
1732 for (i = 0; i < sizeof(tests2)/sizeof(tests2[0]); i++)
1734 unsigned int val = tests2[i].v1;
1735 tests2[i].func(&val, tests2[i].v2);
1736 ok(val == tests2[i].expected, "test %d: expected val == %u, got %u\n", i, tests2[i].expected, val);
1740 static void test_atomic_integer64(void)
1742 struct
1744 void (CDECL *func)(LONG64 *, LONG64);
1745 LONG64 v1, v2, expected;
1747 tests1[] =
1749 { p_vcomp_atomic_add_i8, 0x1122334455667788, 0x7766554433221100, -0x7777777777777778 },
1750 { p_vcomp_atomic_and_i8, 0x1122334455667788, 0x7766554433221100, 0x1122114411221100 },
1751 { p_vcomp_atomic_div_i8, 0x7766554433221100, 0x1122334455667788, 6 },
1752 { p_vcomp_atomic_div_i8, 0x7766554433221100, -0x1122334455667788, -6 },
1753 { p_vcomp_atomic_mul_i8, 0x1122334455667788, 0x7766554433221100, 0x3e963337c6000800 },
1754 { p_vcomp_atomic_mul_i8, 0x1122334455667788, -0x7766554433221100, 0xc169ccc839fff800 },
1755 { p_vcomp_atomic_or_i8, 0x1122334455667788, 0x7766554433221100, 0x7766774477667788 },
1756 { p_vcomp_atomic_sub_i8, 0x1122334455667788, 0x7766554433221100, -0x664421ffddbb9978 },
1757 { p_vcomp_atomic_xor_i8, 0x1122334455667788, 0x7766554433221100, 0x6644660066446688 },
1759 struct
1761 void (CDECL *func)(LONG64 *, unsigned int);
1762 LONG64 v1;
1763 unsigned int v2;
1764 LONG64 expected;
1765 BOOL todo;
1767 tests2[] =
1769 { p_vcomp_atomic_shl_i8, 0x1122334455667788, 3, -0x76ee65dd54cc43c0 },
1770 { p_vcomp_atomic_shl_i8, 0x1122334455667788, 60, 0x8000000000000000 },
1771 { p_vcomp_atomic_shl_i8, -0x1122334455667788, 3, 0x76ee65dd54cc43c0 },
1772 { p_vcomp_atomic_shr_i8, 0x1122334455667788, 3, 0x22446688aaccef1 },
1773 { p_vcomp_atomic_shr_i8, 0x1122334455667788, 60, 1 },
1774 { p_vcomp_atomic_shr_i8, -0x1122334455667788, 3, -0x22446688aaccef1 },
1775 #if defined(__i386__)
1776 { p_vcomp_atomic_shl_i8, 0x1122334455667788, 64, 0, TRUE },
1777 { p_vcomp_atomic_shl_i8, 0x1122334455667788, 67, 0, TRUE },
1778 { p_vcomp_atomic_shr_i8, 0x1122334455667788, 64, 0, TRUE },
1779 { p_vcomp_atomic_shr_i8, 0x1122334455667788, 67, 0, TRUE },
1780 #elif defined(__x86_64__)
1781 { p_vcomp_atomic_shl_i8, 0x1122334455667788, 64, 0x1122334455667788 },
1782 { p_vcomp_atomic_shl_i8, 0x1122334455667788, 67, -0x76ee65dd54cc43c0 },
1783 { p_vcomp_atomic_shr_i8, 0x1122334455667788, 64, 0x1122334455667788 },
1784 { p_vcomp_atomic_shr_i8, 0x1122334455667788, 67, 0x22446688aaccef1 },
1785 #endif
1787 struct
1789 void (CDECL *func)(ULONG64 *, ULONG64);
1790 ULONG64 v1, v2, expected;
1792 tests3[] =
1794 { p_vcomp_atomic_div_ui8, 0x7766554455667788, 0x1122334433221100, 6 },
1795 { p_vcomp_atomic_div_ui8, 0x7766554455667788, 0xeeddccbbaa998878, 0 },
1797 struct
1799 void (CDECL *func)(ULONG64 *, unsigned int);
1800 ULONG64 v1;
1801 unsigned int v2;
1802 ULONG64 expected;
1803 BOOL todo;
1805 tests4[] =
1807 { p_vcomp_atomic_shr_ui8, 0x1122334455667788, 3, 0x22446688aaccef1 },
1808 { p_vcomp_atomic_shr_ui8, 0x1122334455667788, 60, 1 },
1809 { p_vcomp_atomic_shr_ui8, 0xeeddccbbaa998878, 3, 0x1ddbb9977553310f },
1810 #if defined(__i386__)
1811 { p_vcomp_atomic_shr_ui8, 0x1122334455667788, 64, 0, TRUE },
1812 { p_vcomp_atomic_shr_ui8, 0x1122334455667788, 67, 0, TRUE },
1813 #elif defined(__x86_64__)
1814 { p_vcomp_atomic_shr_ui8, 0x1122334455667788, 64, 0x1122334455667788 },
1815 { p_vcomp_atomic_shr_ui8, 0x1122334455667788, 67, 0x22446688aaccef1 },
1816 #endif
1818 int i;
1820 for (i = 0; i < sizeof(tests1)/sizeof(tests1[0]); i++)
1822 LONG64 val = tests1[i].v1;
1823 tests1[i].func(&val, tests1[i].v2);
1824 ok(val == tests1[i].expected, "test %d: unexpectedly got %s\n", i, debugstr_longlong(val));
1826 for (i = 0; i < sizeof(tests2)/sizeof(tests2[0]); i++)
1828 LONG64 val = tests2[i].v1;
1829 tests2[i].func(&val, tests2[i].v2);
1830 todo_wine_if(tests2[i].todo)
1831 ok(val == tests2[i].expected, "test %d: unexpectedly got %s\n", i, debugstr_longlong(val));
1833 for (i = 0; i < sizeof(tests3)/sizeof(tests3[0]); i++)
1835 ULONG64 val = tests3[i].v1;
1836 tests3[i].func(&val, tests3[i].v2);
1837 ok(val == tests3[i].expected, "test %d: unexpectedly got %s\n", i, debugstr_longlong(val));
1839 for (i = 0; i < sizeof(tests4)/sizeof(tests4[0]); i++)
1841 ULONG64 val = tests4[i].v1;
1842 tests4[i].func(&val, tests4[i].v2);
1843 todo_wine_if(tests4[i].todo)
1844 ok(val == tests4[i].expected, "test %d: unexpectedly got %s\n", i, debugstr_longlong(val));
1848 static void test_atomic_float(void)
1850 struct
1852 void (CDECL *func)(float *, float);
1853 float v1, v2, expected;
1855 tests[] =
1857 { p_vcomp_atomic_add_r4, 42.0, 17.0, 42.0 + 17.0 },
1858 { p_vcomp_atomic_div_r4, 42.0, 17.0, 42.0 / 17.0 },
1859 { p_vcomp_atomic_mul_r4, 42.0, 17.0, 42.0 * 17.0 },
1860 { p_vcomp_atomic_sub_r4, 42.0, 17.0, 42.0 - 17.0 },
1862 int i;
1864 for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++)
1866 float val = tests[i].v1;
1867 tests[i].func(&val, tests[i].v2);
1868 ok(tests[i].expected - 0.001 < val && val < tests[i].expected + 0.001,
1869 "test %d: expected val == %f, got %f\n", i, tests[i].expected, val);
1873 static void test_atomic_double(void)
1875 struct
1877 void (CDECL *func)(double *, double);
1878 double v1, v2, expected;
1880 tests[] =
1882 { p_vcomp_atomic_add_r8, 42.0, 17.0, 42.0 + 17.0 },
1883 { p_vcomp_atomic_div_r8, 42.0, 17.0, 42.0 / 17.0 },
1884 { p_vcomp_atomic_mul_r8, 42.0, 17.0, 42.0 * 17.0 },
1885 { p_vcomp_atomic_sub_r8, 42.0, 17.0, 42.0 - 17.0 },
1887 int i;
1889 for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++)
1891 double val = tests[i].v1;
1892 tests[i].func(&val, tests[i].v2);
1893 ok(tests[i].expected - 0.001 < val && val < tests[i].expected + 0.001,
1894 "test %d: expected val == %f, got %f\n", i, tests[i].expected, val);
1898 static void test_reduction_integer8(void)
1900 static const struct
1902 unsigned int flags;
1903 char v1, v2, expected;
1905 tests[] =
1907 { 0x000, 0x11, 0x77, -0x78 },
1908 { VCOMP_REDUCTION_FLAGS_ADD, 0x11, 0x77, -0x78 },
1909 { VCOMP_REDUCTION_FLAGS_MUL, 0x11, 0x77, -0x19 },
1910 { VCOMP_REDUCTION_FLAGS_MUL, 0x11, -0x77, 0x19 },
1911 { VCOMP_REDUCTION_FLAGS_AND, 0x11, 0x77, 0x11 },
1912 { VCOMP_REDUCTION_FLAGS_OR, 0x11, 0x77, 0x77 },
1913 { VCOMP_REDUCTION_FLAGS_XOR, 0x11, 0x77, 0x66 },
1914 { VCOMP_REDUCTION_FLAGS_BOOL_AND, 1, 2, 1 },
1915 { VCOMP_REDUCTION_FLAGS_BOOL_OR, 0, 2, 1 },
1916 { 0x800, 0, 2, 1 },
1917 { 0x900, 0, 2, 1 },
1918 { 0xa00, 0, 2, 1 },
1919 { 0xb00, 0, 2, 1 },
1920 { 0xc00, 0, 2, 1 },
1921 { 0xd00, 0, 2, 1 },
1922 { 0xe00, 0, 2, 1 },
1923 { 0xf00, 0, 2, 1 },
1925 int i;
1927 for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++)
1929 char val = tests[i].v1;
1930 p_vcomp_reduction_i1(tests[i].flags, &val, tests[i].v2);
1931 ok(val == tests[i].expected, "test %d: expected val == %d, got %d\n", i, tests[i].expected, val);
1933 for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++)
1935 unsigned char val = tests[i].v1;
1936 p_vcomp_reduction_u1(tests[i].flags, &val, tests[i].v2);
1937 ok(val == (unsigned char)tests[i].expected,
1938 "test %d: expected val == %u, got %u\n", i, (unsigned char)tests[i].expected, val);
1942 static void test_reduction_integer16(void)
1944 static const struct
1946 unsigned int flags;
1947 short v1, v2, expected;
1949 tests[] =
1951 { 0x000, 0x1122, 0x7766, -0x7778 },
1952 { VCOMP_REDUCTION_FLAGS_ADD, 0x1122, 0x7766, -0x7778 },
1953 { VCOMP_REDUCTION_FLAGS_MUL, 0x1122, 0x7766, -0x5e74 },
1954 { VCOMP_REDUCTION_FLAGS_MUL, 0x1122, -0x7766, 0x5e74 },
1955 { VCOMP_REDUCTION_FLAGS_AND, 0x1122, 0x7766, 0x1122 },
1956 { VCOMP_REDUCTION_FLAGS_OR, 0x1122, 0x7766, 0x7766 },
1957 { VCOMP_REDUCTION_FLAGS_XOR, 0x1122, 0x7766, 0x6644 },
1958 { VCOMP_REDUCTION_FLAGS_BOOL_AND, 1, 2, 1 },
1959 { VCOMP_REDUCTION_FLAGS_BOOL_OR, 0, 2, 1 },
1960 { 0x800, 0, 2, 1 },
1961 { 0x900, 0, 2, 1 },
1962 { 0xa00, 0, 2, 1 },
1963 { 0xb00, 0, 2, 1 },
1964 { 0xc00, 0, 2, 1 },
1965 { 0xd00, 0, 2, 1 },
1966 { 0xe00, 0, 2, 1 },
1967 { 0xf00, 0, 2, 1 },
1969 int i;
1971 for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++)
1973 short val = tests[i].v1;
1974 p_vcomp_reduction_i2(tests[i].flags, &val, tests[i].v2);
1975 ok(val == tests[i].expected, "test %d: expected val == %d, got %d\n", i, tests[i].expected, val);
1977 for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++)
1979 unsigned short val = tests[i].v1;
1980 p_vcomp_reduction_u2(tests[i].flags, &val, tests[i].v2);
1981 ok(val == (unsigned short)tests[i].expected,
1982 "test %d: expected val == %u, got %u\n", i, (unsigned short)tests[i].expected, val);
1986 static void CDECL reduction_cb(int *a, int *b)
1988 p_vcomp_reduction_i4(VCOMP_REDUCTION_FLAGS_ADD, a, 1);
1989 p_vcomp_reduction_i4(VCOMP_REDUCTION_FLAGS_ADD | 0xfffff0ff, b, 1);
1992 static void test_reduction_integer32(void)
1994 static const struct
1996 unsigned int flags;
1997 int v1, v2, expected;
1999 tests[] =
2001 { 0x000, 0x11223344, 0x77665544, -0x77777778 },
2002 { VCOMP_REDUCTION_FLAGS_ADD, 0x11223344, 0x77665544, -0x77777778 },
2003 { VCOMP_REDUCTION_FLAGS_MUL, 0x11223344, 0x77665544, -0xecccdf0 },
2004 { VCOMP_REDUCTION_FLAGS_MUL, 0x11223344, -0x77665544, 0xecccdf0 },
2005 { VCOMP_REDUCTION_FLAGS_AND, 0x11223344, 0x77665544, 0x11221144 },
2006 { VCOMP_REDUCTION_FLAGS_OR, 0x11223344, 0x77665544, 0x77667744 },
2007 { VCOMP_REDUCTION_FLAGS_XOR, 0x11223344, 0x77665544, 0x66446600 },
2008 { VCOMP_REDUCTION_FLAGS_BOOL_AND, 0, 0, 0 },
2009 { VCOMP_REDUCTION_FLAGS_BOOL_AND, 0, 2, 0 },
2010 { VCOMP_REDUCTION_FLAGS_BOOL_AND, 1, 0, 0 },
2011 { VCOMP_REDUCTION_FLAGS_BOOL_AND, 1, 2, 1 },
2012 { VCOMP_REDUCTION_FLAGS_BOOL_AND, 2, 0, 0 },
2013 { VCOMP_REDUCTION_FLAGS_BOOL_AND, 2, 2, 1 },
2014 { VCOMP_REDUCTION_FLAGS_BOOL_OR, 0, 0, 0 },
2015 { VCOMP_REDUCTION_FLAGS_BOOL_OR, 0, 2, 1 },
2016 { VCOMP_REDUCTION_FLAGS_BOOL_OR, 1, 0, 1 },
2017 { VCOMP_REDUCTION_FLAGS_BOOL_OR, 1, 2, 1 },
2018 { VCOMP_REDUCTION_FLAGS_BOOL_OR, 2, 0, 2 },
2019 { VCOMP_REDUCTION_FLAGS_BOOL_OR, 2, 2, 2 },
2020 { 0x800, 0, 2, 1 },
2021 { 0x900, 0, 2, 1 },
2022 { 0xa00, 0, 2, 1 },
2023 { 0xb00, 0, 2, 1 },
2024 { 0xc00, 0, 2, 1 },
2025 { 0xd00, 0, 2, 1 },
2026 { 0xe00, 0, 2, 1 },
2027 { 0xf00, 0, 2, 1 },
2029 int max_threads = pomp_get_max_threads();
2030 int a, b, i;
2032 a = b = 42;
2033 reduction_cb(&a, &b);
2034 ok(a == 43, "expected a == 43, got %d\n", a);
2035 ok(b == 43, "expected b == 43, got %d\n", b);
2037 for (i = 1; i <= 4; i++)
2039 pomp_set_num_threads(i);
2041 a = b = 42;
2042 p_vcomp_fork(TRUE, 2, reduction_cb, &a, &b);
2043 ok(a == 42 + i, "expected a == %d, got %d\n", 42 + i, a);
2044 ok(b == 42 + i, "expected b == %d, got %d\n", 42 + i, b);
2046 a = b = 42;
2047 p_vcomp_fork(FALSE, 2, reduction_cb, &a, &b);
2048 ok(a == 43, "expected a == 43, got %d\n", a);
2049 ok(b == 43, "expected b == 43, got %d\n", b);
2052 pomp_set_num_threads(max_threads);
2054 for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++)
2056 int val = tests[i].v1;
2057 p_vcomp_reduction_i4(tests[i].flags, &val, tests[i].v2);
2058 ok(val == tests[i].expected, "test %d: expected val == %d, got %d\n", i, tests[i].expected, val);
2060 for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++)
2062 unsigned int val = tests[i].v1;
2063 p_vcomp_reduction_u4(tests[i].flags, &val, tests[i].v2);
2064 ok(val == tests[i].expected, "test %d: expected val == %u, got %u\n", i, tests[i].expected, val);
2068 static void test_reduction_integer64(void)
2070 static const struct
2072 unsigned int flags;
2073 LONG64 v1, v2, expected;
2075 tests[] =
2077 { 0x000, 0x1122334455667788, 0x7766554433221100, -0x7777777777777778 },
2078 { VCOMP_REDUCTION_FLAGS_ADD, 0x1122334455667788, 0x7766554433221100, -0x7777777777777778 },
2079 { VCOMP_REDUCTION_FLAGS_MUL, 0x1122334455667788, 0x7766554433221100, 0x3e963337c6000800 },
2080 { VCOMP_REDUCTION_FLAGS_MUL, 0x1122334455667788, -0x7766554433221100, 0xc169ccc839fff800 },
2081 { VCOMP_REDUCTION_FLAGS_AND, 0x1122334455667788, 0x7766554433221100, 0x1122114411221100 },
2082 { VCOMP_REDUCTION_FLAGS_OR, 0x1122334455667788, 0x7766554433221100, 0x7766774477667788 },
2083 { VCOMP_REDUCTION_FLAGS_XOR, 0x1122334455667788, 0x7766554433221100, 0x6644660066446688 },
2084 { VCOMP_REDUCTION_FLAGS_BOOL_AND, 1, 2, 1 },
2085 { VCOMP_REDUCTION_FLAGS_BOOL_OR, 0, 2, 1 },
2086 { 0x800, 0, 2, 1 },
2087 { 0x900, 0, 2, 1 },
2088 { 0xa00, 0, 2, 1 },
2089 { 0xb00, 0, 2, 1 },
2090 { 0xc00, 0, 2, 1 },
2091 { 0xd00, 0, 2, 1 },
2092 { 0xe00, 0, 2, 1 },
2093 { 0xf00, 0, 2, 1 },
2095 int i;
2097 for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++)
2099 LONG64 val = tests[i].v1;
2100 p_vcomp_reduction_i8(tests[i].flags, &val, tests[i].v2);
2101 ok(val == tests[i].expected, "test %d: unexpectedly got %s\n", i, debugstr_longlong(val));
2103 for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++)
2105 ULONG64 val = tests[i].v1;
2106 p_vcomp_reduction_u8(tests[i].flags, &val, tests[i].v2);
2107 ok(val == tests[i].expected, "test %d: unexpectedly got %s\n", i, debugstr_longlong(val));
2111 START_TEST(vcomp)
2113 if (!init_vcomp())
2114 return;
2116 test_omp_get_num_threads(FALSE);
2117 test_omp_get_num_threads(TRUE);
2118 test_vcomp_fork();
2119 test_vcomp_sections_init();
2120 test_vcomp_for_static_simple_init();
2121 test_vcomp_for_static_init();
2122 test_vcomp_for_dynamic_init();
2123 test_vcomp_master_begin();
2124 test_vcomp_single_begin();
2125 test_vcomp_enter_critsect();
2126 test_vcomp_flush();
2127 test_omp_init_lock();
2128 test_omp_init_nest_lock();
2129 test_atomic_integer8();
2130 test_atomic_integer16();
2131 test_atomic_integer32();
2132 test_atomic_integer64();
2133 test_atomic_float();
2134 test_atomic_double();
2135 test_reduction_integer8();
2136 test_reduction_integer16();
2137 test_reduction_integer32();
2138 test_reduction_integer64();
2140 release_vcomp();