vcomp: Add _vcomp_for_static_init_i8 implementation.

Signed-off-by: Piotr Caban <piotr@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Piotr Caban 2021-10-26 18:55:08 +02:00 committed by Alexandre Julliard
parent a75c1aa78e
commit 750ef2a5fb
8 changed files with 333 additions and 6 deletions

View file

@ -1281,6 +1281,79 @@ void CDECL _vcomp_for_static_init(int first, int last, int step, int chunksize,
*lastchunk = first + (num_chunks - 1) * chunksize * step;
}
void CDECL _vcomp_for_static_init_i8(LONG64 first, LONG64 last, LONG64 step, LONG64 chunksize, ULONG64 *loops,
LONG64 *begin, LONG64 *end, LONG64 *next, LONG64 *lastchunk)
{
ULONG64 iterations, num_chunks, per_thread, remaining;
struct vcomp_thread_data *thread_data = vcomp_init_thread_data();
struct vcomp_team_data *team_data = thread_data->team;
int num_threads = team_data ? team_data->num_threads : 1;
int thread_num = thread_data->thread_num;
LONG64 no_begin, no_lastchunk;
TRACE("(%s, %s, %s, %s, %p, %p, %p, %p, %p)\n",
wine_dbgstr_longlong(first), wine_dbgstr_longlong(last),
wine_dbgstr_longlong(step), wine_dbgstr_longlong(chunksize),
loops, begin, end, next, lastchunk);
if (!begin)
{
begin = &no_begin;
lastchunk = &no_lastchunk;
}
if (num_threads == 1 && chunksize != 1)
{
*loops = 1;
*begin = first;
*end = last;
*next = 0;
*lastchunk = first;
return;
}
if (first == last)
{
*loops = !thread_num;
if (!thread_num)
{
*begin = first;
*end = last;
*next = 0;
*lastchunk = first;
}
return;
}
if (step <= 0)
{
*loops = 0;
return;
}
if (first < last)
iterations = 1 + (last - first) / step;
else
{
iterations = 1 + (first - last) / step;
step *= -1;
}
if (chunksize < 1)
chunksize = 1;
num_chunks = iterations / chunksize;
if (iterations % chunksize) num_chunks++;
per_thread = num_chunks / num_threads;
remaining = num_chunks - per_thread * num_threads;
*loops = per_thread + (thread_num < remaining);
*begin = first + thread_num * chunksize * step;
*end = *begin + (chunksize - 1) * step;
*next = chunksize * num_threads * step;
*lastchunk = first + (num_chunks - 1) * chunksize * step;
}
void CDECL _vcomp_for_static_end(void)
{
TRACE("()\n");

View file

@ -91,6 +91,8 @@ static int (CDECL *p_vcomp_for_dynamic_next)(unsigned int *begin, unsigned i
static void (CDECL *p_vcomp_for_static_end)(void);
static void (CDECL *p_vcomp_for_static_init)(int first, int last, int step, int chunksize, unsigned int *loops,
int *begin, int *end, int *next, int *lastchunk);
static void (CDECL *p_vcomp_for_static_init_i8)(LONG64 first, LONG64 last, LONG64 step, LONG64 chunksize, ULONG64 *loops,
LONG64 *begin, LONG64 *end, LONG64 *next, LONG64 *lastchunk);
static void (CDECL *p_vcomp_for_static_simple_init)(unsigned int first, unsigned int last, int step,
BOOL increment, unsigned int *begin, unsigned int *end);
static void (WINAPIV *p_vcomp_fork)(BOOL ifval, int nargs, void *wrapper, ...);
@ -328,6 +330,7 @@ static BOOL init_vcomp(void)
VCOMP_GET_PROC(_vcomp_for_dynamic_next);
VCOMP_GET_PROC(_vcomp_for_static_end);
VCOMP_GET_PROC(_vcomp_for_static_init);
VCOMP_GET_PROC(_vcomp_for_static_init_i8);
VCOMP_GET_PROC(_vcomp_for_static_simple_init);
VCOMP_GET_PROC(_vcomp_fork);
VCOMP_GET_PROC(_vcomp_get_thread_num);
@ -895,6 +898,71 @@ static DWORD CDECL my_for_static_init(int first, int last, int step, int chunksi
return 0;
}
static DWORD CDECL my_for_static_init_i8(LONG64 first, LONG64 last, LONG64 step, LONG64 chunksize, ULONG64 *loops,
LONG64 *begin, LONG64 *end, LONG64 *next, LONG64 *lastchunk)
{
ULONG64 iterations, num_chunks, per_thread, remaining;
int num_threads = pomp_get_num_threads();
int thread_num = pomp_get_thread_num();
if (num_threads == 1 && chunksize != 1)
{
*loops = 1;
*begin = first;
*end = last;
*next = 0;
*lastchunk = first;
return 0;
}
if (first == last)
{
*loops = !thread_num;
if (!thread_num)
{
/* The value in *next on Windows is either uninitialized, or contains
* garbage. The value shouldn't matter for *loops <= 1, so no need to
* reproduce that. */
*begin = first;
*end = last;
*next = 0;
*lastchunk = first;
}
return thread_num ? 0 : VCOMP_FOR_STATIC_BROKEN_NEXT;
}
if (step <= 0)
{
/* The total number of iterations depends on the number of threads here,
* which doesn't make any sense. This is most likely a bug in the Windows
* implementation. */
return VCOMP_FOR_STATIC_BROKEN_LOOP;
}
if (first < last)
iterations = 1 + (last - first) / step;
else
{
iterations = 1 + (first - last) / step;
step *= -1;
}
if (chunksize < 1)
chunksize = 1;
num_chunks = iterations / chunksize;
if (iterations % chunksize) num_chunks++;
per_thread = num_chunks / num_threads;
remaining = num_chunks - per_thread * num_threads;
*loops = per_thread + (thread_num < remaining);
*begin = first + thread_num * chunksize * step;
*end = *begin + (chunksize - 1) * step;
*next = chunksize * num_threads * step;
*lastchunk = first + (num_chunks - 1) * chunksize * step;
return 0;
}
static void CDECL for_static_cb(void)
{
static const struct
@ -1072,6 +1140,189 @@ static void CDECL for_static_cb(void)
}
}
static void CDECL for_static_i8_cb(void)
{
static const struct
{
LONG64 first;
LONG64 last;
LONG64 step;
LONG64 chunksize;
}
tests[] =
{
{ 0, 0, 1, 1 }, /* 0 */
{ 0, 1, 1, 1 },
{ 0, 2, 1, 1 },
{ 0, 3, 1, 1 },
{ 0, 100, 1, 0 },
{ 0, 100, 1, 1 },
{ 0, 100, 1, 5 },
{ 0, 100, 1, 10 },
{ 0, 100, 1, 50 },
{ 0, 100, 1, 100 },
{ 0, 100, 1, 150 }, /* 10 */
{ 0, 100, 3, 0 },
{ 0, 100, 3, 1 },
{ 0, 100, 3, 5 },
{ 0, 100, 3, 10 },
{ 0, 100, 3, 50 },
{ 0, 100, 3, 100 },
{ 0, 100, 3, 150 },
{ 0, 100, 5, 1 },
{ 0, 100, -3, 0 },
{ 0, 100, -3, 1 }, /* 20 */
{ 0, 100, -3, 5 },
{ 0, 100, -3, 10 },
{ 0, 100, -3, 50 },
{ 0, 100, -3, 100 },
{ 0, 100, -3, 150 },
{ 0, 100, 10, 1 },
{ 0, 100, 50, 1 },
{ 0, 100, 100, 1 },
{ 0, 100, 150, 1 },
{ 0, 0x10000000, 1, 123 }, /* 30 */
{ 0, 0x20000000, 1, 123 },
{ 0, 0x40000000, 1, 123 },
{ 0, -0x80000000, 1, 123 },
{ 50, 50, 1, 1 },
{ 50, 50, 1, 2 },
{ 50, 50, 1, -1 },
{ 50, 50, 1, -2 },
{ 50, 50, 2, 1 },
{ 50, 50, 3, 1 },
{ 100, 200, 3, 1 }, /* 40 */
{ 100, 200, 3, -1 },
{ 0x7ffffffe, -0x80000000, 1, 123 },
{ 0x7fffffff, -0x80000000, 1, 123 },
{ 0x7ffffffffffffffeLL, -0x8000000000000000LL, 1, 123 },
{ 0x7fffffffffffffffLL, -0x8000000000000000LL, 1, 123 },
};
int num_threads = pomp_get_num_threads();
int thread_num = pomp_get_thread_num();
int i;
for (i = 0; i < ARRAY_SIZE(tests); i++)
{
LONG64 my_begin, my_end, my_next, my_lastchunk;
LONG64 begin, end, next, lastchunk;
ULONG64 my_loops, loops;
DWORD broken_flags;
my_loops = my_begin = my_end = my_next = my_lastchunk = -0xdeadbeef;
loops = begin = end = next = lastchunk = -0xdeadbeef;
broken_flags = my_for_static_init_i8(tests[i].first, tests[i].last, tests[i].step, tests[i].chunksize,
&my_loops, &my_begin, &my_end, &my_next, &my_lastchunk);
p_vcomp_for_static_init_i8(tests[i].first, tests[i].last, tests[i].step, tests[i].chunksize,
&loops, &begin, &end, &next, &lastchunk);
if (broken_flags & VCOMP_FOR_STATIC_BROKEN_LOOP)
{
ok(loops == 0 || loops == 1, "test %d, thread %d/%d: expected loops == 0 or 1, got %s\n",
i, thread_num, num_threads, wine_dbgstr_longlong(loops));
}
else
{
ok(loops == my_loops, "test %d, thread %d/%d: expected loops == %s, got %s\n",
i, thread_num, num_threads, wine_dbgstr_longlong(my_loops), wine_dbgstr_longlong(loops));
ok(begin == my_begin, "test %d, thread %d/%d: expected begin == %s, got %s\n",
i, thread_num, num_threads, wine_dbgstr_longlong(my_begin), wine_dbgstr_longlong(begin));
ok(end == my_end, "test %d, thread %d/%d: expected end == %s, got %s\n",
i, thread_num, num_threads, wine_dbgstr_longlong(my_end), wine_dbgstr_longlong(end));
ok(next == my_next || broken(broken_flags & VCOMP_FOR_STATIC_BROKEN_NEXT),
"test %d, thread %d/%d: expected next == %s, got %s\n", i, thread_num, num_threads,
wine_dbgstr_longlong(my_next), wine_dbgstr_longlong(next));
ok(lastchunk == my_lastchunk, "test %d, thread %d/%d: expected lastchunk == %s, got %s\n",
i, thread_num, num_threads, wine_dbgstr_longlong(my_lastchunk), wine_dbgstr_longlong(lastchunk));
}
p_vcomp_for_static_end();
p_vcomp_barrier();
loops = end = next = lastchunk = -0xdeadbeef;
p_vcomp_for_static_init_i8(tests[i].first, tests[i].last, tests[i].step, tests[i].chunksize,
&loops, NULL, &end, &next, &lastchunk);
if (broken_flags & VCOMP_FOR_STATIC_BROKEN_LOOP)
{
ok(loops == 0 || loops == 1, "test %d, thread %d/%d: expected loops == 0 or 1, got %s\n",
i, thread_num, num_threads, wine_dbgstr_longlong(loops));
}
else
{
ok(loops == my_loops, "test %d, thread %d/%d: expected loops == %s, got %s\n",
i, thread_num, num_threads, wine_dbgstr_longlong(my_loops), wine_dbgstr_longlong(loops));
ok(end == my_end, "test %d, thread %d/%d: expected end == %s, got %s\n",
i, thread_num, num_threads, wine_dbgstr_longlong(my_end), wine_dbgstr_longlong(end));
ok(next == my_next || broken(broken_flags & VCOMP_FOR_STATIC_BROKEN_NEXT),
"test %d, thread %d/%d: expected next == %s, got %s\n", i, thread_num, num_threads,
wine_dbgstr_longlong(my_next), wine_dbgstr_longlong(next));
ok(lastchunk == -0xdeadbeef, "test %d, thread %d/%d: expected lastchunk == -0xdeadbeef, got %s\n",
i, thread_num, num_threads, wine_dbgstr_longlong(lastchunk));
}
p_vcomp_for_static_end();
p_vcomp_barrier();
if (tests[i].first == tests[i].last) continue;
my_loops = my_begin = my_end = my_next = my_lastchunk = -0xdeadbeef;
loops = begin = end = next = lastchunk = -0xdeadbeef;
broken_flags = my_for_static_init_i8(tests[i].last, tests[i].first, tests[i].step, tests[i].chunksize,
&my_loops, &my_begin, &my_end, &my_next, &my_lastchunk);
p_vcomp_for_static_init_i8(tests[i].last, tests[i].first, tests[i].step, tests[i].chunksize,
&loops, &begin, &end, &next, &lastchunk);
if (broken_flags & VCOMP_FOR_STATIC_BROKEN_LOOP)
{
ok(loops == 0 || loops == 1, "test %d, thread %d/%d: expected loops == 0 or 1, got %s\n",
i, thread_num, num_threads, wine_dbgstr_longlong(loops));
}
else
{
ok(loops == my_loops, "test %d, thread %d/%d: expected loops == %s, got %s\n",
i, thread_num, num_threads, wine_dbgstr_longlong(my_loops), wine_dbgstr_longlong(loops));
ok(begin == my_begin, "test %d, thread %d/%d: expected begin == %s, got %s\n",
i, thread_num, num_threads, wine_dbgstr_longlong(my_begin), wine_dbgstr_longlong(begin));
ok(end == my_end, "test %d, thread %d/%d: expected end == %s, got %s\n",
i, thread_num, num_threads, wine_dbgstr_longlong(my_end), wine_dbgstr_longlong(end));
ok(next == my_next || broken(broken_flags & VCOMP_FOR_STATIC_BROKEN_NEXT),
"test %d, thread %d/%d: expected next == %s, got %s\n", i, thread_num, num_threads,
wine_dbgstr_longlong(my_next), wine_dbgstr_longlong(next));
ok(lastchunk == my_lastchunk, "test %d, thread %d/%d: expected lastchunk == %s, got %s\n",
i, thread_num, num_threads, wine_dbgstr_longlong(my_lastchunk), wine_dbgstr_longlong(lastchunk));
}
p_vcomp_for_static_end();
p_vcomp_barrier();
loops = end = next = lastchunk = -0xdeadbeef;
p_vcomp_for_static_init_i8(tests[i].last, tests[i].first, tests[i].step, tests[i].chunksize,
&loops, NULL, &end, &next, &lastchunk);
if (broken_flags & VCOMP_FOR_STATIC_BROKEN_LOOP)
{
ok(loops == 0 || loops == 1, "test %d, thread %d/%d: expected loops == 0 or 1, got %s\n",
i, thread_num, num_threads, wine_dbgstr_longlong(loops));
}
else
{
ok(loops == my_loops, "test %d, thread %d/%d: expected loops == %s, got %s\n",
i, thread_num, num_threads, wine_dbgstr_longlong(my_loops), wine_dbgstr_longlong(loops));
ok(end == my_end, "test %d, thread %d/%d: expected end == %s, got %s\n",
i, thread_num, num_threads, wine_dbgstr_longlong(my_end), wine_dbgstr_longlong(end));
ok(next == my_next || broken(broken_flags & VCOMP_FOR_STATIC_BROKEN_NEXT),
"test %d, thread %d/%d: expected next == %s, got %s\n", i, thread_num, num_threads,
wine_dbgstr_longlong(my_next), wine_dbgstr_longlong(next));
ok(lastchunk == -0xdeadbeef, "test %d, thread %d/%d: expected lastchunk == -0xdeadbeef, got %s\n",
i, thread_num, num_threads, wine_dbgstr_longlong(lastchunk));
}
p_vcomp_for_static_end();
p_vcomp_barrier();
}
}
#undef VCOMP_FOR_STATIC_BROKEN_LOOP
#undef VCOMP_FOR_STATIC_BROKEN_NEXT
@ -1081,12 +1332,15 @@ static void test_vcomp_for_static_init(void)
int i;
for_static_cb();
for_static_i8_cb();
for (i = 1; i <= 4; i++)
{
pomp_set_num_threads(i);
p_vcomp_fork(TRUE, 0, for_static_cb);
p_vcomp_fork(FALSE, 0, for_static_cb);
p_vcomp_fork(TRUE, 0, for_static_i8_cb);
p_vcomp_fork(FALSE, 0, for_static_i8_cb);
}
pomp_set_num_threads(max_threads);

View file

@ -61,7 +61,7 @@
@ stub _vcomp_for_dynamic_next_i8
@ cdecl _vcomp_for_static_end()
@ cdecl _vcomp_for_static_init(long long long long ptr ptr ptr ptr ptr)
@ stub _vcomp_for_static_init_i8
@ cdecl _vcomp_for_static_init_i8(int64 int64 int64 int64 ptr ptr ptr ptr ptr)
@ cdecl _vcomp_for_static_simple_init(long long long long ptr ptr)
@ stub _vcomp_for_static_simple_init_i8
@ varargs _vcomp_fork(long long ptr)

View file

@ -61,7 +61,7 @@
@ stub _vcomp_for_dynamic_next_i8
@ cdecl _vcomp_for_static_end()
@ cdecl _vcomp_for_static_init(long long long long ptr ptr ptr ptr ptr)
@ stub _vcomp_for_static_init_i8
@ cdecl _vcomp_for_static_init_i8(int64 int64 int64 int64 ptr ptr ptr ptr ptr)
@ cdecl _vcomp_for_static_simple_init(long long long long ptr ptr)
@ stub _vcomp_for_static_simple_init_i8
@ varargs _vcomp_fork(long long ptr)

View file

@ -62,7 +62,7 @@
@ stub _vcomp_for_dynamic_next_i8
@ cdecl _vcomp_for_static_end()
@ cdecl _vcomp_for_static_init(long long long long ptr ptr ptr ptr ptr)
@ stub _vcomp_for_static_init_i8
@ cdecl _vcomp_for_static_init_i8(int64 int64 int64 int64 ptr ptr ptr ptr ptr)
@ cdecl _vcomp_for_static_simple_init(long long long long ptr ptr)
@ stub _vcomp_for_static_simple_init_i8
@ varargs _vcomp_fork(long long ptr)

View file

@ -62,7 +62,7 @@
@ stub _vcomp_for_dynamic_next_i8
@ cdecl _vcomp_for_static_end()
@ cdecl _vcomp_for_static_init(long long long long ptr ptr ptr ptr ptr)
@ stub _vcomp_for_static_init_i8
@ cdecl _vcomp_for_static_init_i8(int64 int64 int64 int64 ptr ptr ptr ptr ptr)
@ cdecl _vcomp_for_static_simple_init(long long long long ptr ptr)
@ stub _vcomp_for_static_simple_init_i8
@ varargs _vcomp_fork(long long ptr)

View file

@ -62,7 +62,7 @@
@ stub _vcomp_for_dynamic_next_i8
@ cdecl _vcomp_for_static_end()
@ cdecl _vcomp_for_static_init(long long long long ptr ptr ptr ptr ptr)
@ stub _vcomp_for_static_init_i8
@ cdecl _vcomp_for_static_init_i8(int64 int64 int64 int64 ptr ptr ptr ptr ptr)
@ cdecl _vcomp_for_static_simple_init(long long long long ptr ptr)
@ stub _vcomp_for_static_simple_init_i8
@ varargs _vcomp_fork(long long ptr)

View file

@ -61,7 +61,7 @@
@ stub _vcomp_for_dynamic_next_i8
@ cdecl _vcomp_for_static_end() vcomp._vcomp_for_static_end
@ cdecl _vcomp_for_static_init(long long long long ptr ptr ptr ptr ptr) vcomp._vcomp_for_static_init
@ stub _vcomp_for_static_init_i8
@ cdecl _vcomp_for_static_init_i8(int64 int64 int64 int64 ptr ptr ptr ptr ptr) vcomp._vcomp_for_static_init_i8
@ cdecl _vcomp_for_static_simple_init(long long long long ptr ptr) vcomp._vcomp_for_static_simple_init
@ stub _vcomp_for_static_simple_init_i8
@ varargs _vcomp_fork(long long ptr) vcomp._vcomp_fork