Rebase against a90592c8d29d3b145eada90c297405cbd8a9277f.

This commit is contained in:
Sebastian Lackner 2015-07-17 16:00:07 +02:00
parent 36e9309497
commit a37730ab0e
17 changed files with 70 additions and 1385 deletions

View File

@ -1,44 +0,0 @@
From c16a0e4ac4e504a66a3337c0487da33100aab0a5 Mon Sep 17 00:00:00 2001
From: Sebastian Lackner <sebastian@fds-team.de>
Date: Wed, 25 Feb 2015 21:33:36 +0100
Subject: ntdll: Avoid deadlock by using _exit() in NtTerminateProcess.
Other threads are killed with SIGQUIT, so there is no guarantee that we can
terminate properly with exit().
---
dlls/ntdll/process.c | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/dlls/ntdll/process.c b/dlls/ntdll/process.c
index 3ac8d52..d20e107 100644
--- a/dlls/ntdll/process.c
+++ b/dlls/ntdll/process.c
@@ -21,11 +21,16 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
+#include "config.h"
+
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#endif
#include "ntstatus.h"
#define WIN32_NO_STATUS
@@ -60,7 +65,7 @@ NTSTATUS WINAPI NtTerminateProcess( HANDLE handle, LONG exit_code )
self = !ret && reply->self;
}
SERVER_END_REQ;
- if (self && handle) exit( exit_code );
+ if (self && handle) _exit( exit_code );
return ret;
}
--
2.3.0

View File

@ -55,7 +55,7 @@ version()
echo "Copyright (C) 2014-2015 the Wine Staging project authors."
echo ""
echo "Patchset to be applied on upstream Wine:"
echo " commit 2294d3ba456921e83fa5970e0e62855614c9c30c"
echo " commit a90592c8d29d3b145eada90c297405cbd8a9277f"
echo ""
}
@ -3524,14 +3524,12 @@ fi
# Patchset ntdll-Threading
# |
# | Modified files:
# | * dlls/ntdll/process.c, dlls/ntdll/thread.c
# | * dlls/ntdll/thread.c
# |
if test "$enable_ntdll_Threading" -eq 1; then
patch_apply ntdll-Threading/0001-ntdll-Fix-race-condition-when-threads-are-killed-dur.patch
patch_apply ntdll-Threading/0002-ntdll-Avoid-deadlock-by-using-_exit-in-NtTerminatePr.patch
(
echo '+ { "Sebastian Lackner", "ntdll: Fix race-condition when threads are killed during shutdown.", 1 },';
echo '+ { "Sebastian Lackner", "ntdll: Avoid deadlock by using _exit() in NtTerminateProcess.", 1 },';
) >> "$patchlist"
fi
@ -4001,13 +3999,11 @@ fi
# Patchset server-JobObjects
# |
# | Modified files:
# | * dlls/kernel32/tests/process.c, dlls/ntdll/sync.c, server/process.c
# | * dlls/ntdll/sync.c
# |
if test "$enable_server_JobObjects" -eq 1; then
patch_apply server-JobObjects/0001-server-Implement-JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE.patch
patch_apply server-JobObjects/0002-ntdll-Implement-NtQueryInformationJobObject-stub-fun.patch
patch_apply server-JobObjects/0001-ntdll-Implement-NtQueryInformationJobObject-stub-fun.patch
(
echo '+ { "Andrew Cook", "server: Implement JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE.", 1 },';
echo '+ { "Sebastian Lackner", "ntdll: Implement NtQueryInformationJobObject stub function.", 1 },';
) >> "$patchlist"
fi
@ -4459,34 +4455,22 @@ fi
# | * [#31640] Implement various vcomp functions
# |
# | Modified files:
# | * configure.ac, dlls/vcomp/main.c, dlls/vcomp/tests/Makefile.in, dlls/vcomp/tests/vcomp.c, dlls/vcomp/vcomp.spec,
# | dlls/vcomp100/vcomp100.spec, dlls/vcomp90/vcomp90.spec
# | * dlls/vcomp/main.c, dlls/vcomp/tests/vcomp.c, dlls/vcomp/vcomp.spec, dlls/vcomp100/vcomp100.spec,
# | dlls/vcomp90/vcomp90.spec
# |
if test "$enable_vcomp_Functions" -eq 1; then
patch_apply vcomp-Functions/0001-vcomp-Implement-stub-for-_vcomp_fork.patch
patch_apply vcomp-Functions/0002-vcomp-Add-multithreaded-implementation-for-_vcomp_fo.patch
patch_apply vcomp-Functions/0003-vcomp-Implement-_vcomp_barrier.patch
patch_apply vcomp-Functions/0004-vcomp-tests-Add-initial-tests.patch
patch_apply vcomp-Functions/0005-vcomp-tests-Add-additional-tests-for-_vcomp_fork.patch
patch_apply vcomp-Functions/0006-vcomp-Implement-_vcomp_for_static_simple_init-and-_v.patch
patch_apply vcomp-Functions/0007-vcomp-tests-Add-tests-for-_vcomp_for_static_simple_i.patch
patch_apply vcomp-Functions/0008-vcomp-Implement-_vcomp_for_static_init.patch
patch_apply vcomp-Functions/0009-vcomp-tests-Add-tests-for-_vcomp_for_static_init.patch
patch_apply vcomp-Functions/0010-vcomp-Implement-omp_in_parallel.patch
patch_apply vcomp-Functions/0011-vcomp-Implement-_vcomp_sections_init-and-_vcomp_sect.patch
patch_apply vcomp-Functions/0012-vcomp-Implement-_vcomp_for_dynamic_init-and-_vcomp_f.patch
patch_apply vcomp-Functions/0001-vcomp-Implement-_vcomp_for_static_simple_init-and-_v.patch
patch_apply vcomp-Functions/0002-vcomp-tests-Add-tests-for-_vcomp_for_static_simple_i.patch
patch_apply vcomp-Functions/0003-vcomp-Implement-_vcomp_for_static_init.patch
patch_apply vcomp-Functions/0004-vcomp-tests-Add-tests-for-_vcomp_for_static_init.patch
patch_apply vcomp-Functions/0005-vcomp-Implement-omp_in_parallel.patch
patch_apply vcomp-Functions/0006-vcomp-Implement-_vcomp_for_dynamic_init-and-_vcomp_f.patch
(
echo '+ { "Dan Kegel", "vcomp: Implement stub for _vcomp_fork.", 1 },';
echo '+ { "Sebastian Lackner", "vcomp: Add multithreaded implementation for _vcomp_fork.", 1 },';
echo '+ { "Sebastian Lackner", "vcomp: Implement _vcomp_barrier.", 1 },';
echo '+ { "Sebastian Lackner", "vcomp/tests: Add initial tests.", 1 },';
echo '+ { "Dan Kegel", "vcomp/tests: Add additional tests for _vcomp_fork.", 1 },';
echo '+ { "Sebastian Lackner", "vcomp: Implement _vcomp_for_static_simple_init and _vcomp_for_static_end.", 1 },';
echo '+ { "Sebastian Lackner", "vcomp/tests: Add tests for _vcomp_for_static_simple_init.", 1 },';
echo '+ { "Sebastian Lackner", "vcomp: Implement _vcomp_for_static_init.", 1 },';
echo '+ { "Sebastian Lackner", "vcomp/tests: Add tests for _vcomp_for_static_init.", 1 },';
echo '+ { "Sebastian Lackner", "vcomp: Implement omp_in_parallel.", 1 },';
echo '+ { "Sebastian Lackner", "vcomp: Implement _vcomp_sections_init and _vcomp_sections_next and add tests.", 1 },';
echo '+ { "Sebastian Lackner", "vcomp: Implement _vcomp_for_dynamic_init and _vcomp_for_dynamic_next and add tests.", 1 },';
) >> "$patchlist"
fi
@ -5489,7 +5473,7 @@ fi
if test "$enable_winsta_WinStationEnumerateW" -eq 1; then
patch_apply winsta-WinStationEnumerateW/0001-winsta-Add-stub-for-WinStationEnumerateW.patch
(
echo '+ { "Austin English", "winsta: Add stub for WinStationEnumerateW.", 1 },';
echo '+ { "Austin English", "winsta: Add stub for WinStationEnumerateW.", 2 },';
) >> "$patchlist"
fi

View File

@ -1,67 +0,0 @@
From 23d528b7e744e69fa5d857be20f188ce5510c088 Mon Sep 17 00:00:00 2001
From: Andrew Cook <ariscop@gmail.com>
Date: Thu, 26 Feb 2015 13:10:41 +1100
Subject: server: Implement JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE.
---
dlls/kernel32/tests/process.c | 1 -
server/process.c | 17 ++++++++++++++++-
2 files changed, 16 insertions(+), 2 deletions(-)
diff --git a/dlls/kernel32/tests/process.c b/dlls/kernel32/tests/process.c
index c63d6b1..5e04836 100644
--- a/dlls/kernel32/tests/process.c
+++ b/dlls/kernel32/tests/process.c
@@ -2435,7 +2435,6 @@ static void test_KillOnJobClose(void)
CloseHandle(job);
dwret = WaitForSingleObject(pi.hProcess, 1000);
- todo_wine
ok(dwret == WAIT_OBJECT_0, "WaitForSingleObject returned %u\n", dwret);
if (dwret == WAIT_TIMEOUT) TerminateProcess(pi.hProcess, 0);
diff --git a/server/process.c b/server/process.c
index 569a8fe..38bd977 100644
--- a/server/process.c
+++ b/server/process.c
@@ -140,6 +140,7 @@ static void job_dump( struct object *obj, int verbose );
static struct object_type *job_get_type( struct object *obj );
static int job_signaled( struct object *obj, struct wait_queue_entry *entry );
static unsigned int job_map_access( struct object *obj, unsigned int access );
+static int job_close_handle( struct object *, struct process *process, obj_handle_t handle );
static void job_destroy( struct object *obj );
struct job
@@ -170,7 +171,7 @@ static const struct object_ops job_ops =
default_set_sd, /* set_sd */
no_lookup_name, /* lookup_name */
no_open_file, /* open_file */
- no_close_handle, /* close_handle */
+ job_close_handle, /* close_handle */
job_destroy /* destroy */
};
@@ -287,6 +288,20 @@ static void terminate_job( struct job *job, int exit_code )
wake_up( &job->obj, 0 );
}
+static int job_close_handle( struct object *obj, struct process *process, obj_handle_t handle )
+{
+ struct job *job = (struct job *)obj;
+ assert( obj->ops == &job_ops );
+
+ /* If this is the last handle and JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE is set,
+ * then terminate all associcated processes. We can't use the refcount because
+ * processes have a reference to the job object. */
+ if (obj->handle_count == 1 && (job->limit_flags & JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE))
+ terminate_job( job, 0 );
+
+ return 1;
+}
+
static void job_destroy( struct object *obj )
{
struct job *job = (struct job *)obj;
--
2.3.5

View File

@ -1,4 +1,4 @@
From 7b64b41a512320a89e7758db43343ebe99c0f563 Mon Sep 17 00:00:00 2001
From 3ebb9a8afbb3592c6988eb4b6cc2f0872fef45fb Mon Sep 17 00:00:00 2001
From: Sebastian Lackner <sebastian@fds-team.de>
Date: Sat, 11 Jul 2015 18:59:41 +0200
Subject: vcomp: Implement _vcomp_for_static_simple_init and
@ -12,11 +12,11 @@ Subject: vcomp: Implement _vcomp_for_static_simple_init and
4 files changed, 96 insertions(+), 6 deletions(-)
diff --git a/dlls/vcomp/main.c b/dlls/vcomp/main.c
index bcaa4ea..fcbd747 100644
index 0f8a272..7000e1b 100644
--- a/dlls/vcomp/main.c
+++ b/dlls/vcomp/main.c
@@ -301,6 +301,96 @@ void CDECL _vcomp_single_end(void)
TRACE("stub\n");
@@ -345,6 +345,96 @@ int CDECL _vcomp_sections_next(void)
return i;
}
+void CDECL _vcomp_for_static_simple_init(unsigned int first, unsigned int last, int step, BOOL forward,
@ -113,7 +113,7 @@ index bcaa4ea..fcbd747 100644
{
struct vcomp_thread_data *thread_data = param;
diff --git a/dlls/vcomp/vcomp.spec b/dlls/vcomp/vcomp.spec
index d446574..b14edca 100644
index dfbd184..51dc13c 100644
--- a/dlls/vcomp/vcomp.spec
+++ b/dlls/vcomp/vcomp.spec
@@ -59,10 +59,10 @@
@ -130,7 +130,7 @@ index d446574..b14edca 100644
@ varargs _vcomp_fork(long long ptr)
@ stub _vcomp_get_thread_num
diff --git a/dlls/vcomp100/vcomp100.spec b/dlls/vcomp100/vcomp100.spec
index 2c04e91..89e0972 100644
index 6eb6ae5..c2c644a 100644
--- a/dlls/vcomp100/vcomp100.spec
+++ b/dlls/vcomp100/vcomp100.spec
@@ -59,10 +59,10 @@
@ -147,7 +147,7 @@ index 2c04e91..89e0972 100644
@ varargs _vcomp_fork(long long ptr) vcomp._vcomp_fork
@ stub _vcomp_get_thread_num
diff --git a/dlls/vcomp90/vcomp90.spec b/dlls/vcomp90/vcomp90.spec
index 2c04e91..89e0972 100644
index 6eb6ae5..c2c644a 100644
--- a/dlls/vcomp90/vcomp90.spec
+++ b/dlls/vcomp90/vcomp90.spec
@@ -59,10 +59,10 @@

View File

@ -1,177 +0,0 @@
From d0d4b3991b691ee74e999f82dbf57a5a400fe7db Mon Sep 17 00:00:00 2001
From: Dan Kegel <dank@kegel.com>
Date: Tue, 14 Jul 2015 21:40:36 +0200
Subject: vcomp: Implement stub for _vcomp_fork.
Changes:
* The original patch added a new file, I moved the implementation to main.c.
* A huge comment block was removed, tests are more reliable than comments anyway. ;)
---
dlls/vcomp/main.c | 95 +++++++++++++++++++++++++++++++++++++++++++++
dlls/vcomp/vcomp.spec | 2 +-
dlls/vcomp100/vcomp100.spec | 2 +-
dlls/vcomp90/vcomp90.spec | 2 +-
4 files changed, 98 insertions(+), 3 deletions(-)
diff --git a/dlls/vcomp/main.c b/dlls/vcomp/main.c
index 8ec3616..03c085b 100644
--- a/dlls/vcomp/main.c
+++ b/dlls/vcomp/main.c
@@ -3,6 +3,7 @@
* vcomp implementation
*
* Copyright 2011 Austin English
+ * Copyright 2012 Dan Kegel
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -40,6 +41,89 @@ struct vcomp_thread_data
int fork_threads;
};
+void CDECL _vcomp_fork_call_wrapper(void *wrapper, int nargs, __ms_va_list args);
+
+#if defined(__i386__)
+
+__ASM_GLOBAL_FUNC( _vcomp_fork_call_wrapper,
+ "pushl %ebp\n\t"
+ __ASM_CFI(".cfi_adjust_cfa_offset 4\n\t")
+ __ASM_CFI(".cfi_rel_offset %ebp,0\n\t")
+ "movl %esp,%ebp\n\t"
+ __ASM_CFI(".cfi_def_cfa_register %ebp\n\t")
+ "pushl %esi\n\t"
+ __ASM_CFI(".cfi_rel_offset %esi,-4\n\t")
+ "pushl %edi\n\t"
+ __ASM_CFI(".cfi_rel_offset %edi,-8\n\t")
+ "movl 12(%ebp),%edx\n\t"
+ "movl %esp,%edi\n\t"
+ "shll $2,%edx\n\t"
+ "jz 1f\n\t"
+ "subl %edx,%edi\n\t"
+ "andl $~15,%edi\n\t"
+ "movl %edi,%esp\n\t"
+ "movl 12(%ebp),%ecx\n\t"
+ "movl 16(%ebp),%esi\n\t"
+ "cld\n\t"
+ "rep; movsl\n"
+ "1:\tcall *8(%ebp)\n\t"
+ "leal -8(%ebp),%esp\n\t"
+ "popl %edi\n\t"
+ __ASM_CFI(".cfi_same_value %edi\n\t")
+ "popl %esi\n\t"
+ __ASM_CFI(".cfi_same_value %esi\n\t")
+ "popl %ebp\n\t"
+ __ASM_CFI(".cfi_def_cfa %esp,4\n\t")
+ __ASM_CFI(".cfi_same_value %ebp\n\t")
+ "ret" )
+
+#elif defined(__x86_64__)
+
+__ASM_GLOBAL_FUNC( _vcomp_fork_call_wrapper,
+ "pushq %rbp\n\t"
+ __ASM_CFI(".cfi_adjust_cfa_offset 8\n\t")
+ __ASM_CFI(".cfi_rel_offset %rbp,0\n\t")
+ "movq %rsp,%rbp\n\t"
+ __ASM_CFI(".cfi_def_cfa_register %rbp\n\t")
+ "pushq %rsi\n\t"
+ __ASM_CFI(".cfi_rel_offset %rsi,-8\n\t")
+ "pushq %rdi\n\t"
+ __ASM_CFI(".cfi_rel_offset %rdi,-16\n\t")
+ "movq %rcx,%rax\n\t"
+ "movq $4,%rcx\n\t"
+ "cmp %rcx,%rdx\n\t"
+ "cmovgq %rdx,%rcx\n\t"
+ "leaq 0(,%rcx,8),%rdx\n\t"
+ "subq %rdx,%rsp\n\t"
+ "andq $~15,%rsp\n\t"
+ "movq %rsp,%rdi\n\t"
+ "movq %r8,%rsi\n\t"
+ "rep; movsq\n\t"
+ "movq 0(%rsp),%rcx\n\t"
+ "movq 8(%rsp),%rdx\n\t"
+ "movq 16(%rsp),%r8\n\t"
+ "movq 24(%rsp),%r9\n\t"
+ "callq *%rax\n\t"
+ "leaq -16(%rbp),%rsp\n\t"
+ "popq %rdi\n\t"
+ __ASM_CFI(".cfi_same_value %rdi\n\t")
+ "popq %rsi\n\t"
+ __ASM_CFI(".cfi_same_value %rsi\n\t")
+ __ASM_CFI(".cfi_def_cfa_register %rsp\n\t")
+ "popq %rbp\n\t"
+ __ASM_CFI(".cfi_adjust_cfa_offset -8\n\t")
+ __ASM_CFI(".cfi_same_value %rbp\n\t")
+ "ret")
+
+#else
+
+void CDECL _vcomp_fork_call_wrapper(void *wrapper, int nargs, __ms_va_list args)
+{
+ ERR("Not implemented for this architecture\n");
+}
+
+#endif
+
static inline struct vcomp_thread_data *vcomp_get_thread_data(void)
{
return (struct vcomp_thread_data *)TlsGetValue(vcomp_context_tls);
@@ -160,6 +244,17 @@ void CDECL _vcomp_single_end(void)
TRACE("stub\n");
}
+void WINAPIV _vcomp_fork(BOOL ifval, int nargs, void *wrapper, ...)
+{
+ __ms_va_list valist;
+
+ TRACE("(%d, %d, %p, ...)\n", ifval, nargs, wrapper);
+
+ __ms_va_start(valist, wrapper);
+ _vcomp_fork_call_wrapper(wrapper, nargs, valist);
+ __ms_va_end(valist);
+}
+
BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved)
{
TRACE("(%p, %d, %p)\n", instance, reason, reserved);
diff --git a/dlls/vcomp/vcomp.spec b/dlls/vcomp/vcomp.spec
index 306dd15..d446574 100644
--- a/dlls/vcomp/vcomp.spec
+++ b/dlls/vcomp/vcomp.spec
@@ -64,7 +64,7 @@
@ stub _vcomp_for_static_init_i8
@ stub _vcomp_for_static_simple_init
@ stub _vcomp_for_static_simple_init_i8
-@ stub _vcomp_fork
+@ varargs _vcomp_fork(long long ptr)
@ stub _vcomp_get_thread_num
@ stub _vcomp_leave_critsect
@ stub _vcomp_master_barrier
diff --git a/dlls/vcomp100/vcomp100.spec b/dlls/vcomp100/vcomp100.spec
index 39cf91c..2c04e91 100644
--- a/dlls/vcomp100/vcomp100.spec
+++ b/dlls/vcomp100/vcomp100.spec
@@ -64,7 +64,7 @@
@ stub _vcomp_for_static_init_i8
@ stub _vcomp_for_static_simple_init
@ stub _vcomp_for_static_simple_init_i8
-@ stub _vcomp_fork
+@ varargs _vcomp_fork(long long ptr) vcomp._vcomp_fork
@ stub _vcomp_get_thread_num
@ stub _vcomp_leave_critsect
@ stub _vcomp_master_barrier
diff --git a/dlls/vcomp90/vcomp90.spec b/dlls/vcomp90/vcomp90.spec
index 39cf91c..2c04e91 100644
--- a/dlls/vcomp90/vcomp90.spec
+++ b/dlls/vcomp90/vcomp90.spec
@@ -64,7 +64,7 @@
@ stub _vcomp_for_static_init_i8
@ stub _vcomp_for_static_simple_init
@ stub _vcomp_for_static_simple_init_i8
-@ stub _vcomp_fork
+@ varargs _vcomp_fork(long long ptr) vcomp._vcomp_fork
@ stub _vcomp_get_thread_num
@ stub _vcomp_leave_critsect
@ stub _vcomp_master_barrier
--
2.4.5

View File

@ -1,259 +0,0 @@
From 6f76d9a3a8a11bc4f6d3e6ddba1fcb9a856d0b2f Mon Sep 17 00:00:00 2001
From: Sebastian Lackner <sebastian@fds-team.de>
Date: Tue, 14 Jul 2015 21:41:10 +0200
Subject: vcomp: Add multithreaded implementation for _vcomp_fork.
---
dlls/vcomp/main.c | 180 +++++++++++++++++++++++++++++++++++++++++++++++++++---
1 file changed, 172 insertions(+), 8 deletions(-)
diff --git a/dlls/vcomp/main.c b/dlls/vcomp/main.c
index 03c085b..20aeb4f 100644
--- a/dlls/vcomp/main.c
+++ b/dlls/vcomp/main.c
@@ -4,6 +4,7 @@
*
* Copyright 2011 Austin English
* Copyright 2012 Dan Kegel
+ * Copyright 2015 Sebastian Lackner
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -23,22 +24,52 @@
#include "config.h"
#include <stdarg.h>
+#include <assert.h>
#include "windef.h"
#include "winbase.h"
#include "wine/debug.h"
+#include "wine/list.h"
WINE_DEFAULT_DEBUG_CHANNEL(vcomp);
+static struct list vcomp_idle_threads = LIST_INIT(vcomp_idle_threads);
static DWORD vcomp_context_tls = TLS_OUT_OF_INDEXES;
+static HMODULE vcomp_module;
static int vcomp_max_threads;
static int vcomp_num_threads;
static BOOL vcomp_nested_fork = FALSE;
+static RTL_CRITICAL_SECTION vcomp_section;
+static RTL_CRITICAL_SECTION_DEBUG critsect_debug =
+{
+ 0, 0, &vcomp_section,
+ { &critsect_debug.ProcessLocksList, &critsect_debug.ProcessLocksList },
+ 0, 0, { (DWORD_PTR)(__FILE__ ": vcomp_section") }
+};
+static RTL_CRITICAL_SECTION vcomp_section = { &critsect_debug, -1, 0, 0, 0, 0 };
+
struct vcomp_thread_data
{
+ struct vcomp_team_data *team;
int thread_num;
int fork_threads;
+
+ /* only used for concurrent tasks */
+ struct list entry;
+ CONDITION_VARIABLE cond;
+};
+
+struct vcomp_team_data
+{
+ CONDITION_VARIABLE cond;
+ int num_threads;
+ int finished_threads;
+
+ /* callback arguments */
+ int nargs;
+ void *wrapper;
+ __ms_va_list valist;
};
void CDECL _vcomp_fork_call_wrapper(void *wrapper, int nargs, __ms_va_list args);
@@ -145,8 +176,9 @@ static struct vcomp_thread_data *vcomp_init_thread_data(void)
ExitProcess(1);
}
- thread_data->thread_num = 0;
- thread_data->fork_threads = 0;
+ thread_data->team = NULL;
+ thread_data->thread_num = 0;
+ thread_data->fork_threads = 0;
vcomp_set_thread_data(thread_data);
return thread_data;
@@ -187,8 +219,9 @@ int CDECL omp_get_num_procs(void)
int CDECL omp_get_num_threads(void)
{
- TRACE("stub\n");
- return 1;
+ struct vcomp_team_data *team_data = vcomp_init_thread_data()->team;
+ TRACE("()\n");
+ return team_data ? team_data->num_threads : 1;
}
int CDECL omp_get_thread_num(void)
@@ -244,15 +277,145 @@ void CDECL _vcomp_single_end(void)
TRACE("stub\n");
}
+static DWORD WINAPI _vcomp_fork_worker(void *param)
+{
+ struct vcomp_thread_data *thread_data = param;
+ vcomp_set_thread_data(thread_data);
+
+ TRACE("starting worker thread for %p\n", thread_data);
+
+ EnterCriticalSection(&vcomp_section);
+ for (;;)
+ {
+ struct vcomp_team_data *team = thread_data->team;
+ if (team != NULL)
+ {
+ LeaveCriticalSection(&vcomp_section);
+ _vcomp_fork_call_wrapper(team->wrapper, team->nargs, team->valist);
+ EnterCriticalSection(&vcomp_section);
+
+ thread_data->team = NULL;
+ list_remove(&thread_data->entry);
+ list_add_tail(&vcomp_idle_threads, &thread_data->entry);
+ if (++team->finished_threads >= team->num_threads)
+ WakeAllConditionVariable(&team->cond);
+ }
+
+ if (!SleepConditionVariableCS(&thread_data->cond, &vcomp_section, 5000) &&
+ GetLastError() == ERROR_TIMEOUT && !thread_data->team)
+ {
+ break;
+ }
+ }
+ list_remove(&thread_data->entry);
+ LeaveCriticalSection(&vcomp_section);
+
+ TRACE("terminating worker thread for %p\n", thread_data);
+
+ HeapFree(GetProcessHeap(), 0, thread_data);
+ vcomp_set_thread_data(NULL);
+ FreeLibraryAndExitThread(vcomp_module, 0);
+ return 0;
+}
+
void WINAPIV _vcomp_fork(BOOL ifval, int nargs, void *wrapper, ...)
{
- __ms_va_list valist;
+ struct vcomp_thread_data *prev_thread_data = vcomp_init_thread_data();
+ struct vcomp_thread_data thread_data;
+ struct vcomp_team_data team_data;
+ int num_threads;
TRACE("(%d, %d, %p, ...)\n", ifval, nargs, wrapper);
- __ms_va_start(valist, wrapper);
- _vcomp_fork_call_wrapper(wrapper, nargs, valist);
- __ms_va_end(valist);
+ if (!ifval)
+ num_threads = 1;
+ else if (prev_thread_data->team && !vcomp_nested_fork)
+ num_threads = 1;
+ else if (prev_thread_data->fork_threads)
+ num_threads = prev_thread_data->fork_threads;
+ else
+ num_threads = vcomp_num_threads;
+
+ InitializeConditionVariable(&team_data.cond);
+ team_data.num_threads = 1;
+ team_data.finished_threads = 0;
+ team_data.nargs = nargs;
+ team_data.wrapper = wrapper;
+ __ms_va_start(team_data.valist, wrapper);
+
+ thread_data.team = &team_data;
+ thread_data.thread_num = 0;
+ thread_data.fork_threads = 0;
+ list_init(&thread_data.entry);
+ InitializeConditionVariable(&thread_data.cond);
+
+ if (num_threads > 1)
+ {
+ struct list *ptr;
+ EnterCriticalSection(&vcomp_section);
+
+ /* reuse existing threads (if any) */
+ while (team_data.num_threads < num_threads && (ptr = list_head(&vcomp_idle_threads)))
+ {
+ struct vcomp_thread_data *data = LIST_ENTRY(ptr, struct vcomp_thread_data, entry);
+ data->team = &team_data;
+ data->thread_num = team_data.num_threads++;
+ data->fork_threads = 0;
+ list_remove(&data->entry);
+ list_add_tail(&thread_data.entry, &data->entry);
+ WakeAllConditionVariable(&data->cond);
+ }
+
+ /* spawn additional threads */
+ while (team_data.num_threads < num_threads)
+ {
+ struct vcomp_thread_data *data;
+ HMODULE module;
+ HANDLE thread;
+
+ data = HeapAlloc(GetProcessHeap(), 0, sizeof(*data));
+ if (!data) break;
+
+ data->team = &team_data;
+ data->thread_num = team_data.num_threads;
+ data->fork_threads = 0;
+ InitializeConditionVariable(&data->cond);
+
+ thread = CreateThread(NULL, 0, _vcomp_fork_worker, data, 0, NULL);
+ if (!thread)
+ {
+ HeapFree(GetProcessHeap(), 0, data);
+ break;
+ }
+
+ GetModuleHandleExW(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS,
+ (const WCHAR *)vcomp_module, &module);
+ team_data.num_threads++;
+ list_add_tail(&thread_data.entry, &data->entry);
+ CloseHandle(thread);
+ }
+
+ LeaveCriticalSection(&vcomp_section);
+ }
+
+ vcomp_set_thread_data(&thread_data);
+ _vcomp_fork_call_wrapper(team_data.wrapper, team_data.nargs, team_data.valist);
+ vcomp_set_thread_data(prev_thread_data);
+ prev_thread_data->fork_threads = 0;
+
+ if (team_data.num_threads > 1)
+ {
+ EnterCriticalSection(&vcomp_section);
+
+ team_data.finished_threads++;
+ while (team_data.finished_threads < team_data.num_threads)
+ SleepConditionVariableCS(&team_data.cond, &vcomp_section, INFINITE);
+
+ LeaveCriticalSection(&vcomp_section);
+ assert(list_empty(&thread_data.entry));
+ }
+
+ __ms_va_end(team_data.valist);
}
BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved)
@@ -275,6 +438,7 @@ BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved)
}
GetSystemInfo(&sysinfo);
+ vcomp_module = instance;
vcomp_max_threads = sysinfo.dwNumberOfProcessors;
vcomp_num_threads = sysinfo.dwNumberOfProcessors;
break;
--
2.4.5

View File

@ -1,4 +1,4 @@
From 656f0051550426759e8f6ab287391bbe6a168418 Mon Sep 17 00:00:00 2001
From abd9917d138e9e7c4f4fa9c13c15c44072d604f8 Mon Sep 17 00:00:00 2001
From: Sebastian Lackner <sebastian@fds-team.de>
Date: Sat, 11 Jul 2015 05:12:39 +0200
Subject: vcomp/tests: Add tests for _vcomp_for_static_simple_init.
@ -8,7 +8,7 @@ Subject: vcomp/tests: Add tests for _vcomp_for_static_simple_init.
1 file changed, 220 insertions(+)
diff --git a/dlls/vcomp/tests/vcomp.c b/dlls/vcomp/tests/vcomp.c
index a9b975d..34c1ebc 100644
index c433991..bba1fe3 100644
--- a/dlls/vcomp/tests/vcomp.c
+++ b/dlls/vcomp/tests/vcomp.c
@@ -32,6 +32,9 @@ static BOOL (WINAPI *pDeactivateActCtx)(DWORD, ULONG_PTR);
@ -19,18 +19,18 @@ index a9b975d..34c1ebc 100644
+static void (CDECL *p_vcomp_for_static_simple_init)(unsigned int first, unsigned int last, int step,
+ BOOL forward, unsigned int *begin, unsigned int *end);
static void (WINAPIV *p_vcomp_fork)(BOOL ifval, int nargs, void *wrapper, ...);
static void (CDECL *p_vcomp_set_num_threads)(int num_threads);
static int (CDECL *pomp_get_max_threads)(void);
@@ -168,6 +171,8 @@ static BOOL init_vcomp(void)
static void (CDECL *p_vcomp_sections_init)(int n);
static int (CDECL *p_vcomp_sections_next)(void);
@@ -170,6 +173,8 @@ static BOOL init_vcomp(void)
}
VCOMP_GET_PROC(_vcomp_barrier);
+ VCOMP_GET_PROC(_vcomp_for_static_end);
+ VCOMP_GET_PROC(_vcomp_for_static_simple_init);
VCOMP_GET_PROC(_vcomp_fork);
VCOMP_GET_PROC(_vcomp_set_num_threads);
VCOMP_GET_PROC(omp_get_max_threads);
@@ -342,6 +347,220 @@ static void test_vcomp_fork(void)
VCOMP_GET_PROC(_vcomp_sections_init);
VCOMP_GET_PROC(_vcomp_sections_next);
@@ -392,6 +397,220 @@ static void test_vcomp_sections_init(void)
pomp_set_num_threads(max_threads);
}
@ -251,10 +251,10 @@ index a9b975d..34c1ebc 100644
START_TEST(vcomp)
{
if (!init_vcomp())
@@ -350,6 +569,7 @@ START_TEST(vcomp)
test_omp_get_num_threads(FALSE);
@@ -401,6 +620,7 @@ START_TEST(vcomp)
test_omp_get_num_threads(TRUE);
test_vcomp_fork();
test_vcomp_sections_init();
+ test_vcomp_for_static_simple_init();
release_vcomp();

View File

@ -1,65 +0,0 @@
From 5990968a0ae43fd6f4a4001107ef5d4fcc273458 Mon Sep 17 00:00:00 2001
From: Sebastian Lackner <sebastian@fds-team.de>
Date: Tue, 14 Jul 2015 21:41:27 +0200
Subject: vcomp: Implement _vcomp_barrier.
---
dlls/vcomp/main.c | 28 +++++++++++++++++++++++++++-
1 file changed, 27 insertions(+), 1 deletion(-)
diff --git a/dlls/vcomp/main.c b/dlls/vcomp/main.c
index 20aeb4f..bcaa4ea 100644
--- a/dlls/vcomp/main.c
+++ b/dlls/vcomp/main.c
@@ -70,6 +70,10 @@ struct vcomp_team_data
int nargs;
void *wrapper;
__ms_va_list valist;
+
+ /* barrier */
+ unsigned int barrier;
+ int barrier_count;
};
void CDECL _vcomp_fork_call_wrapper(void *wrapper, int nargs, __ms_va_list args);
@@ -256,7 +260,27 @@ void CDECL omp_set_num_threads(int num_threads)
void CDECL _vcomp_barrier(void)
{
- TRACE("stub\n");
+ struct vcomp_team_data *team_data = vcomp_init_thread_data()->team;
+
+ TRACE("()\n");
+
+ if (!team_data)
+ return;
+
+ EnterCriticalSection(&vcomp_section);
+ if (++team_data->barrier_count >= team_data->num_threads)
+ {
+ team_data->barrier++;
+ team_data->barrier_count = 0;
+ WakeAllConditionVariable(&team_data->cond);
+ }
+ else
+ {
+ unsigned int barrier = team_data->barrier;
+ while (team_data->barrier == barrier)
+ SleepConditionVariableCS(&team_data->cond, &vcomp_section, INFINITE);
+ }
+ LeaveCriticalSection(&vcomp_section);
}
void CDECL _vcomp_set_num_threads(int num_threads)
@@ -342,6 +366,8 @@ void WINAPIV _vcomp_fork(BOOL ifval, int nargs, void *wrapper, ...)
team_data.nargs = nargs;
team_data.wrapper = wrapper;
__ms_va_start(team_data.valist, wrapper);
+ team_data.barrier = 0;
+ team_data.barrier_count = 0;
thread_data.team = &team_data;
thread_data.thread_num = 0;
--
2.4.5

View File

@ -1,4 +1,4 @@
From ed0734ad10de657efb30ec7c851d20d20ba79a0a Mon Sep 17 00:00:00 2001
From bbced4bb965ecd2f773783ffb19f76b6e908f109 Mon Sep 17 00:00:00 2001
From: Sebastian Lackner <sebastian@fds-team.de>
Date: Sat, 11 Jul 2015 19:19:00 +0200
Subject: vcomp: Implement _vcomp_for_static_init.
@ -11,10 +11,10 @@ Subject: vcomp: Implement _vcomp_for_static_init.
4 files changed, 65 insertions(+), 3 deletions(-)
diff --git a/dlls/vcomp/main.c b/dlls/vcomp/main.c
index fcbd747..b22dd37 100644
index 7000e1b..f09fdda 100644
--- a/dlls/vcomp/main.c
+++ b/dlls/vcomp/main.c
@@ -386,6 +386,68 @@ void CDECL _vcomp_for_static_simple_init(unsigned int first, unsigned int last,
@@ -430,6 +430,68 @@ void CDECL _vcomp_for_static_simple_init(unsigned int first, unsigned int last,
}
}
@ -84,7 +84,7 @@ index fcbd747..b22dd37 100644
{
TRACE("()\n");
diff --git a/dlls/vcomp/vcomp.spec b/dlls/vcomp/vcomp.spec
index b14edca..8bc66e8 100644
index 51dc13c..718f80e 100644
--- a/dlls/vcomp/vcomp.spec
+++ b/dlls/vcomp/vcomp.spec
@@ -60,7 +60,7 @@
@ -97,7 +97,7 @@ index b14edca..8bc66e8 100644
@ cdecl _vcomp_for_static_simple_init(long long long long ptr ptr)
@ stub _vcomp_for_static_simple_init_i8
diff --git a/dlls/vcomp100/vcomp100.spec b/dlls/vcomp100/vcomp100.spec
index 89e0972..f008e2e 100644
index c2c644a..c0b3d98 100644
--- a/dlls/vcomp100/vcomp100.spec
+++ b/dlls/vcomp100/vcomp100.spec
@@ -60,7 +60,7 @@
@ -110,7 +110,7 @@ index 89e0972..f008e2e 100644
@ 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
diff --git a/dlls/vcomp90/vcomp90.spec b/dlls/vcomp90/vcomp90.spec
index 89e0972..f008e2e 100644
index c2c644a..c0b3d98 100644
--- a/dlls/vcomp90/vcomp90.spec
+++ b/dlls/vcomp90/vcomp90.spec
@@ -60,7 +60,7 @@

View File

@ -1,338 +0,0 @@
From 01b14a9059e5a0ade1818046b03546adc0002bde Mon Sep 17 00:00:00 2001
From: Sebastian Lackner <sebastian@fds-team.de>
Date: Tue, 14 Jul 2015 21:42:11 +0200
Subject: vcomp/tests: Add initial tests.
The only way to get the tests pass on all testbot machines was to dynamically
create a manifest file. Without manifest file, the vcomp library cannot be found
on all machines > Win2000, with manifest file as resource the Windows loader is
not able to load the executable for testbots without vcrun2005.
---
configure.ac | 1 +
dlls/vcomp/tests/Makefile.in | 4 +
dlls/vcomp/tests/vcomp.c | 290 +++++++++++++++++++++++++++++++++++++++++++
3 files changed, 295 insertions(+)
create mode 100644 dlls/vcomp/tests/Makefile.in
create mode 100644 dlls/vcomp/tests/vcomp.c
diff --git a/configure.ac b/configure.ac
index 3eaec29..f15a17a 100644
--- a/configure.ac
+++ b/configure.ac
@@ -3322,6 +3322,7 @@ WINE_CONFIG_TEST(dlls/uxtheme/tests)
WINE_CONFIG_DLL(vbscript,,[clean])
WINE_CONFIG_TEST(dlls/vbscript/tests,[clean])
WINE_CONFIG_DLL(vcomp)
+WINE_CONFIG_TEST(dlls/vcomp/tests)
WINE_CONFIG_DLL(vcomp100)
WINE_CONFIG_DLL(vcomp90)
WINE_CONFIG_DLL(vdhcp.vxd,enable_win16)
diff --git a/dlls/vcomp/tests/Makefile.in b/dlls/vcomp/tests/Makefile.in
new file mode 100644
index 0000000..d1b7b12
--- /dev/null
+++ b/dlls/vcomp/tests/Makefile.in
@@ -0,0 +1,4 @@
+TESTDLL = vcomp.dll
+
+C_SRCS = \
+ vcomp.c
diff --git a/dlls/vcomp/tests/vcomp.c b/dlls/vcomp/tests/vcomp.c
new file mode 100644
index 0000000..b084791
--- /dev/null
+++ b/dlls/vcomp/tests/vcomp.c
@@ -0,0 +1,290 @@
+/*
+ * Unit test suite for vcomp
+ *
+ * Copyright 2015 Sebastian Lackner
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include "wine/test.h"
+
+static char vcomp_manifest_file[MAX_PATH];
+static HANDLE vcomp_actctx_hctx;
+static ULONG_PTR vcomp_actctx_cookie;
+static HMODULE vcomp_handle;
+
+static HANDLE (WINAPI *pCreateActCtxA)(ACTCTXA*);
+static BOOL (WINAPI *pActivateActCtx)(HANDLE, ULONG_PTR*);
+static BOOL (WINAPI *pDeactivateActCtx)(DWORD, ULONG_PTR);
+static VOID (WINAPI *pReleaseActCtx)(HANDLE);
+
+static void (CDECL *p_vcomp_barrier)(void);
+static void (WINAPIV *p_vcomp_fork)(BOOL ifval, int nargs, void *wrapper, ...);
+static void (CDECL *p_vcomp_set_num_threads)(int num_threads);
+static int (CDECL *pomp_get_max_threads)(void);
+static int (CDECL *pomp_get_nested)(void);
+static int (CDECL *pomp_get_num_threads)(void);
+static int (CDECL *pomp_get_thread_num)(void);
+static void (CDECL *pomp_set_nested)(int nested);
+static void (CDECL *pomp_set_num_threads)(int num_threads);
+
+#ifdef __i386__
+#define ARCH "x86"
+#elif defined(__x86_64__)
+#define ARCH "amd64"
+#else
+#define ARCH "none"
+#endif
+
+static const char vcomp_manifest[] =
+ "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n"
+ "<assembly xmlns=\"urn:schemas-microsoft-com:asm.v1\" manifestVersion=\"1.0\">\n"
+ " <assemblyIdentity\n"
+ " type=\"win32\"\n"
+ " name=\"Wine.vcomp.Test\"\n"
+ " version=\"1.0.0.0\"\n"
+ " processorArchitecture=\"" ARCH "\"\n"
+ " />\n"
+ "<description>Wine vcomp test suite</description>\n"
+ "<dependency>\n"
+ " <dependentAssembly>\n"
+ " <assemblyIdentity\n"
+ " type=\"win32\"\n"
+ " name=\"Microsoft.VC80.OpenMP\"\n"
+ " version=\"8.0.50608.0\"\n"
+ " processorArchitecture=\"" ARCH "\"\n"
+ " publicKeyToken=\"1fc8b3b9a1e18e3b\"\n"
+ " />\n"
+ " </dependentAssembly>\n"
+ "</dependency>\n"
+ "</assembly>\n";
+
+#undef ARCH
+
+static void create_vcomp_manifest(void)
+{
+ char temp_path[MAX_PATH];
+ HMODULE kernel32;
+ DWORD written;
+ ACTCTXA ctx;
+ HANDLE file;
+
+ kernel32 = GetModuleHandleA("kernel32.dll");
+ pCreateActCtxA = (void *)GetProcAddress(kernel32, "CreateActCtxA");
+ pActivateActCtx = (void *)GetProcAddress(kernel32, "ActivateActCtx");
+ pDeactivateActCtx = (void *)GetProcAddress(kernel32, "DeactivateActCtx");
+ pReleaseActCtx = (void *)GetProcAddress(kernel32, "ReleaseActCtx");
+ if (!pCreateActCtxA) return;
+
+ if (!GetTempPathA(sizeof(temp_path), temp_path) ||
+ !GetTempFileNameA(temp_path, "vcomp", 0, vcomp_manifest_file))
+ {
+ ok(0, "failed to create manifest file\n");
+ return;
+ }
+
+ file = CreateFileA(vcomp_manifest_file, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
+ if (file == INVALID_HANDLE_VALUE)
+ {
+ ok(0, "failed to open manifest file\n");
+ return;
+ }
+
+ if (!WriteFile(file, vcomp_manifest, sizeof(vcomp_manifest) - 1, &written, NULL))
+ written = 0;
+ CloseHandle(file);
+
+ if (written != sizeof(vcomp_manifest) - 1)
+ {
+ ok(0, "failed to write manifest file\n");
+ DeleteFileA(vcomp_manifest_file);
+ return;
+ }
+
+ memset(&ctx, 0, sizeof(ctx));
+ ctx.cbSize = sizeof(ctx);
+ ctx.lpSource = vcomp_manifest_file;
+ vcomp_actctx_hctx = pCreateActCtxA(&ctx);
+ if (!vcomp_actctx_hctx)
+ {
+ ok(0, "failed to create activation context\n");
+ DeleteFileA(vcomp_manifest_file);
+ return;
+ }
+
+ if (!pActivateActCtx(vcomp_actctx_hctx, &vcomp_actctx_cookie))
+ {
+ win_skip("failed to activate context\n");
+ pReleaseActCtx(vcomp_actctx_hctx);
+ DeleteFileA(vcomp_manifest_file);
+ vcomp_actctx_hctx = NULL;
+ }
+}
+
+static void release_vcomp(void)
+{
+ if (vcomp_handle)
+ FreeLibrary(vcomp_handle);
+
+ if (vcomp_actctx_hctx)
+ {
+ pDeactivateActCtx(0, vcomp_actctx_cookie);
+ pReleaseActCtx(vcomp_actctx_hctx);
+ DeleteFileA(vcomp_manifest_file);
+ }
+}
+
+#define VCOMP_GET_PROC(func) \
+ do \
+ { \
+ p ## func = (void *)GetProcAddress(vcomp_handle, #func); \
+ if (!p ## func) trace("Failed to get address for %s\n", #func); \
+ } \
+ while (0)
+
+static BOOL init_vcomp(void)
+{
+ create_vcomp_manifest();
+
+ vcomp_handle = LoadLibraryA("vcomp.dll");
+ if (!vcomp_handle)
+ {
+ win_skip("vcomp.dll not installed\n");
+ release_vcomp();
+ return FALSE;
+ }
+
+ VCOMP_GET_PROC(_vcomp_barrier);
+ VCOMP_GET_PROC(_vcomp_fork);
+ VCOMP_GET_PROC(_vcomp_set_num_threads);
+ VCOMP_GET_PROC(omp_get_max_threads);
+ VCOMP_GET_PROC(omp_get_nested);
+ VCOMP_GET_PROC(omp_get_num_threads);
+ VCOMP_GET_PROC(omp_get_thread_num);
+ VCOMP_GET_PROC(omp_set_nested);
+ VCOMP_GET_PROC(omp_set_num_threads);
+
+ return TRUE;
+}
+
+#undef VCOMP_GET_PROC
+
+static void CDECL num_threads_cb2(LONG *count)
+{
+ InterlockedIncrement(count);
+}
+
+static void CDECL num_threads_cb(BOOL nested, int nested_threads, LONG *count)
+{
+ int num_threads, thread_num;
+ LONG thread_count;
+
+ InterlockedIncrement(count);
+ p_vcomp_barrier();
+
+ num_threads = pomp_get_num_threads();
+ ok(num_threads == *count, "expected num_threads == %d, got %d\n", *count, num_threads);
+ thread_num = pomp_get_thread_num();
+ ok(thread_num >= 0 && thread_num < num_threads,
+ "expected thread_num in range [0, %d], got %d\n", num_threads - 1, thread_num);
+
+ thread_count = 0;
+ p_vcomp_fork(TRUE, 1, num_threads_cb2, &thread_count);
+ if (nested)
+ ok(thread_count == nested_threads, "expected %d thread, got %d\n", nested_threads, thread_count);
+ else
+ ok(thread_count == 1, "expected 1 thread, got %d\n", thread_count);
+
+ p_vcomp_set_num_threads(4);
+ thread_count = 0;
+ p_vcomp_fork(TRUE, 1, num_threads_cb2, &thread_count);
+ if (nested)
+ ok(thread_count == 4 , "expected 4 thread, got %d\n", thread_count);
+ else
+ ok(thread_count == 1 , "expected 1 thread, got %d\n", thread_count);
+}
+
+static void test_omp_get_num_threads(BOOL nested)
+{
+ int is_nested, max_threads, num_threads, thread_num;
+ LONG thread_count;
+
+ pomp_set_nested(nested);
+ is_nested = pomp_get_nested();
+ ok(is_nested == nested, "expected %d, got %d\n", nested, is_nested);
+
+ max_threads = pomp_get_max_threads();
+ ok(max_threads >= 1, "expected max_threads >= 1, got %d\n", max_threads);
+ thread_num = pomp_get_thread_num();
+ ok(thread_num == 0, "expected thread_num == 0, got %d\n", thread_num);
+
+ num_threads = pomp_get_num_threads();
+ ok(num_threads == 1, "expected num_threads == 1, got %d\n", num_threads);
+ thread_count = 0;
+ p_vcomp_fork(TRUE, 3, num_threads_cb, nested, max_threads, &thread_count);
+ ok(thread_count == max_threads, "expected %d threads, got %d\n", max_threads, thread_count);
+
+ pomp_set_num_threads(2);
+ num_threads = pomp_get_num_threads();
+ ok(num_threads == 1, "expected num_threads == 1, got %d\n", num_threads);
+ thread_count = 0;
+ p_vcomp_fork(TRUE, 3, num_threads_cb, nested, 2, &thread_count);
+ ok(thread_count == 2, "expected 2 threads, got %d\n", thread_count);
+
+ pomp_set_num_threads(4);
+ num_threads = pomp_get_num_threads();
+ ok(num_threads == 1, "expected num_threads == 1, got %d\n", num_threads);
+ thread_count = 0;
+ p_vcomp_fork(TRUE, 3, num_threads_cb, nested, 4, &thread_count);
+ ok(thread_count == 4, "expected 4 threads, got %d\n", thread_count);
+
+ p_vcomp_set_num_threads(8);
+ num_threads = pomp_get_num_threads();
+ ok(num_threads == 1, "expected num_threads == 1, got %d\n", num_threads);
+ thread_count = 0;
+ p_vcomp_fork(TRUE, 3, num_threads_cb, nested, 4, &thread_count);
+ ok(thread_count == 8, "expected 8 threads, got %d\n", thread_count);
+ thread_count = 0;
+ p_vcomp_fork(TRUE, 3, num_threads_cb, nested, 4, &thread_count);
+ ok(thread_count == 4, "expected 4 threads, got %d\n", thread_count);
+
+ p_vcomp_set_num_threads(0);
+ num_threads = pomp_get_num_threads();
+ ok(num_threads == 1, "expected num_threads == 1, got %d\n", num_threads);
+ thread_count = 0;
+ p_vcomp_fork(TRUE, 3, num_threads_cb, nested, 4, &thread_count);
+ ok(thread_count == 4, "expected 4 threads, got %d\n", thread_count);
+
+ pomp_set_num_threads(0);
+ num_threads = pomp_get_num_threads();
+ ok(num_threads == 1, "expected num_threads == 1, got %d\n", num_threads);
+ thread_count = 0;
+ p_vcomp_fork(TRUE, 3, num_threads_cb, nested, 4, &thread_count);
+ ok(thread_count == 4, "expected 4 threads, got %d\n", thread_count);
+
+ pomp_set_num_threads(max_threads);
+ pomp_set_nested(FALSE);
+}
+
+START_TEST(vcomp)
+{
+ if (!init_vcomp())
+ return;
+
+ test_omp_get_num_threads(FALSE);
+ test_omp_get_num_threads(TRUE);
+
+ release_vcomp();
+}
--
2.4.5

View File

@ -1,4 +1,4 @@
From 39cd9028667159d38193fca46691b7cdbc0fe82b Mon Sep 17 00:00:00 2001
From 9d2c0d36fecd34e7b111fa342aa73315bc26342a Mon Sep 17 00:00:00 2001
From: Sebastian Lackner <sebastian@fds-team.de>
Date: Sat, 11 Jul 2015 06:08:08 +0200
Subject: vcomp/tests: Add tests for _vcomp_for_static_init.
@ -8,7 +8,7 @@ Subject: vcomp/tests: Add tests for _vcomp_for_static_init.
1 file changed, 199 insertions(+)
diff --git a/dlls/vcomp/tests/vcomp.c b/dlls/vcomp/tests/vcomp.c
index 34c1ebc..0103af1 100644
index bba1fe3..8de4510b 100644
--- a/dlls/vcomp/tests/vcomp.c
+++ b/dlls/vcomp/tests/vcomp.c
@@ -33,6 +33,8 @@ static VOID (WINAPI *pReleaseActCtx)(HANDLE);
@ -20,15 +20,15 @@ index 34c1ebc..0103af1 100644
static void (CDECL *p_vcomp_for_static_simple_init)(unsigned int first, unsigned int last, int step,
BOOL forward, unsigned int *begin, unsigned int *end);
static void (WINAPIV *p_vcomp_fork)(BOOL ifval, int nargs, void *wrapper, ...);
@@ -172,6 +174,7 @@ static BOOL init_vcomp(void)
@@ -174,6 +176,7 @@ static BOOL init_vcomp(void)
VCOMP_GET_PROC(_vcomp_barrier);
VCOMP_GET_PROC(_vcomp_for_static_end);
+ VCOMP_GET_PROC(_vcomp_for_static_init);
VCOMP_GET_PROC(_vcomp_for_static_simple_init);
VCOMP_GET_PROC(_vcomp_fork);
VCOMP_GET_PROC(_vcomp_set_num_threads);
@@ -561,6 +564,201 @@ static void test_vcomp_for_static_simple_init(void)
VCOMP_GET_PROC(_vcomp_sections_init);
@@ -611,6 +614,201 @@ static void test_vcomp_for_static_simple_init(void)
}
}
@ -230,9 +230,9 @@ index 34c1ebc..0103af1 100644
START_TEST(vcomp)
{
if (!init_vcomp())
@@ -570,6 +768,7 @@ START_TEST(vcomp)
test_omp_get_num_threads(TRUE);
@@ -621,6 +819,7 @@ START_TEST(vcomp)
test_vcomp_fork();
test_vcomp_sections_init();
test_vcomp_for_static_simple_init();
+ test_vcomp_for_static_init();

View File

@ -1,4 +1,4 @@
From d9ec7f94c0ecefeccf49f1d09bf458eb90472faf Mon Sep 17 00:00:00 2001
From c9cf03f4ce4830885ee991ea8e8a5807532be6e5 Mon Sep 17 00:00:00 2001
From: Sebastian Lackner <sebastian@fds-team.de>
Date: Sat, 11 Jul 2015 19:41:29 +0200
Subject: vcomp: Implement omp_in_parallel.
@ -11,10 +11,10 @@ Subject: vcomp: Implement omp_in_parallel.
4 files changed, 9 insertions(+), 3 deletions(-)
diff --git a/dlls/vcomp/main.c b/dlls/vcomp/main.c
index b22dd37..a9a49ce 100644
index f09fdda..af6fe61 100644
--- a/dlls/vcomp/main.c
+++ b/dlls/vcomp/main.c
@@ -453,6 +453,12 @@ void CDECL _vcomp_for_static_end(void)
@@ -497,6 +497,12 @@ void CDECL _vcomp_for_static_end(void)
TRACE("()\n");
}
@ -28,7 +28,7 @@ index b22dd37..a9a49ce 100644
{
struct vcomp_thread_data *thread_data = param;
diff --git a/dlls/vcomp/vcomp.spec b/dlls/vcomp/vcomp.spec
index 8bc66e8..156233f 100644
index 718f80e..7083ce4 100644
--- a/dlls/vcomp/vcomp.spec
+++ b/dlls/vcomp/vcomp.spec
@@ -98,7 +98,7 @@
@ -41,7 +41,7 @@ index 8bc66e8..156233f 100644
@ stub omp_init_nest_lock
@ cdecl omp_set_dynamic(long)
diff --git a/dlls/vcomp100/vcomp100.spec b/dlls/vcomp100/vcomp100.spec
index f008e2e..dd276d0 100644
index c0b3d98..56c7ae3 100644
--- a/dlls/vcomp100/vcomp100.spec
+++ b/dlls/vcomp100/vcomp100.spec
@@ -98,7 +98,7 @@
@ -54,7 +54,7 @@ index f008e2e..dd276d0 100644
@ stub omp_init_nest_lock
@ cdecl omp_set_dynamic(long) vcomp.omp_set_dynamic
diff --git a/dlls/vcomp90/vcomp90.spec b/dlls/vcomp90/vcomp90.spec
index f008e2e..dd276d0 100644
index c0b3d98..56c7ae3 100644
--- a/dlls/vcomp90/vcomp90.spec
+++ b/dlls/vcomp90/vcomp90.spec
@@ -98,7 +98,7 @@

View File

@ -1,107 +0,0 @@
From e9d9801b549a73db5666c51c14200aeca63725b4 Mon Sep 17 00:00:00 2001
From: Dan Kegel <dank@kegel.com>
Date: Tue, 14 Jul 2015 21:42:31 +0200
Subject: vcomp/tests: Add additional tests for _vcomp_fork.
Changes:
* The number of threads is now set to 4 before running the tests.
* Some functions were renamed.
* All fork tests are now in a single test_*() function.
* Various ok(...) messages were improved.
---
dlls/vcomp/tests/vcomp.c | 65 ++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 65 insertions(+)
diff --git a/dlls/vcomp/tests/vcomp.c b/dlls/vcomp/tests/vcomp.c
index b084791..a9b975d 100644
--- a/dlls/vcomp/tests/vcomp.c
+++ b/dlls/vcomp/tests/vcomp.c
@@ -1,6 +1,7 @@
/*
* Unit test suite for vcomp
*
+ * Copyright 2012 Dan Kegel
* Copyright 2015 Sebastian Lackner
*
* This library is free software; you can redistribute it and/or
@@ -278,6 +279,69 @@ static void test_omp_get_num_threads(BOOL nested)
pomp_set_nested(FALSE);
}
+static void CDECL fork_ptr_cb(LONG *a, LONG *b, LONG *c, LONG *d, LONG *e)
+{
+ InterlockedIncrement(a);
+ InterlockedIncrement(b);
+ InterlockedIncrement(c);
+ InterlockedIncrement(d);
+ InterlockedIncrement(e);
+}
+
+static void CDECL fork_uintptr_cb(UINT_PTR a, UINT_PTR b, UINT_PTR c, UINT_PTR d, UINT_PTR e)
+{
+ ok(a == 1, "expected a == 1, got %p\n", (void *)a);
+ ok(b == MAXUINT_PTR - 2, "expected b == MAXUINT_PTR - 2, got %p\n", (void *)b);
+ ok(c == 3, "expected c == 3, got %p\n", (void *)c);
+ ok(d == MAXUINT_PTR - 4, "expected d == MAXUINT_PTR - 4, got %p\n", (void *)d);
+ ok(e == 5, "expected e == 5, got %p\n", (void *)e);
+}
+
+static void CDECL fork_float_cb(float a, float b, float c, float d, float e)
+{
+ ok(1.4999 < a && a < 1.5001, "expected a == 1.5, got %f\n", a);
+ ok(2.4999 < b && b < 2.5001, "expected b == 2.5, got %f\n", b);
+ ok(3.4999 < c && c < 3.5001, "expected c == 3.5, got %f\n", c);
+ ok(4.4999 < d && d < 4.5001, "expected d == 4.5, got %f\n", d);
+ ok(5.4999 < e && e < 5.5001, "expected e == 5.5, got %f\n", e);
+}
+
+static void test_vcomp_fork(void)
+{
+ LONG a, b, c, d, e;
+ int max_threads = pomp_get_max_threads();
+ pomp_set_num_threads(4);
+
+ a = 0; b = 1; c = 2; d = 3; e = 4;
+ p_vcomp_fork(FALSE, 5, fork_ptr_cb, &a, &b, &c, &d, &e);
+ ok(a == 1, "expected a == 1, got %d\n", a);
+ ok(b == 2, "expected b == 2, got %d\n", b);
+ ok(c == 3, "expected c == 3, got %d\n", c);
+ ok(d == 4, "expected d == 4, got %d\n", d);
+ ok(e == 5, "expected e == 5, got %d\n", e);
+
+ a = 0; b = 1; c = 2; d = 3; e = 4;
+ p_vcomp_fork(TRUE, 5, fork_ptr_cb, &a, &b, &c, &d, &e);
+ ok(a == 4, "expected a == 4, got %d\n", a);
+ ok(b == 5, "expected b == 5, got %d\n", b);
+ ok(c == 6, "expected c == 6, got %d\n", c);
+ ok(d == 7, "expected d == 7, got %d\n", d);
+ ok(e == 8, "expected e == 8, got %d\n", e);
+
+ p_vcomp_fork(TRUE, 5, fork_uintptr_cb, (UINT_PTR)1, (UINT_PTR)(MAXUINT_PTR - 2),
+ (UINT_PTR)3, (UINT_PTR)(MAXUINT_PTR - 4), (UINT_PTR)5);
+
+ if (sizeof(int) < sizeof(void *))
+ skip("skipping float test on x86_64\n");
+ else
+ {
+ void (CDECL *func)(BOOL, int, void *, float, float, float, float, float) = (void *)p_vcomp_fork;
+ func(TRUE, 5, fork_float_cb, 1.5f, 2.5f, 3.5f, 4.5f, 5.5f);
+ }
+
+ pomp_set_num_threads(max_threads);
+}
+
START_TEST(vcomp)
{
if (!init_vcomp())
@@ -285,6 +349,7 @@ START_TEST(vcomp)
test_omp_get_num_threads(FALSE);
test_omp_get_num_threads(TRUE);
+ test_vcomp_fork();
release_vcomp();
}
--
2.4.5

View File

@ -1,4 +1,4 @@
From 145ddf41060e93e9f320d5d2e4347dd2c7b8a83f Mon Sep 17 00:00:00 2001
From 2884d2c0e05a7bf26fe340774fd3d6a29a1de416 Mon Sep 17 00:00:00 2001
From: Sebastian Lackner <sebastian@fds-team.de>
Date: Sat, 11 Jul 2015 23:28:31 +0200
Subject: vcomp: Implement _vcomp_for_dynamic_init and _vcomp_for_dynamic_next
@ -13,7 +13,7 @@ Subject: vcomp: Implement _vcomp_for_dynamic_init and _vcomp_for_dynamic_next
5 files changed, 152 insertions(+), 6 deletions(-)
diff --git a/dlls/vcomp/main.c b/dlls/vcomp/main.c
index 31814d6..174ce06 100644
index af6fe61..9771841 100644
--- a/dlls/vcomp/main.c
+++ b/dlls/vcomp/main.c
@@ -61,6 +61,9 @@ struct vcomp_thread_data
@ -28,8 +28,8 @@ index 31814d6..174ce06 100644
struct vcomp_team_data
@@ -82,6 +85,15 @@ struct vcomp_team_data
unsigned int section;
unsigned int num_sections;
unsigned int section_index;
int num_sections;
int section_index;
+
+ /* dynamic */
+ DWORD dynamic;
@ -41,9 +41,9 @@ index 31814d6..174ce06 100644
+ DWORD dynamic_min_chunksize;
};
void CDECL _vcomp_fork_call_wrapper(void *wrapper, int nargs, __ms_va_list args);
@@ -498,6 +510,83 @@ int CDECL _vcomp_sections_next(void)
return i;
#if defined(__i386__)
@@ -497,6 +509,83 @@ void CDECL _vcomp_for_static_end(void)
TRACE("()\n");
}
+void CDECL _vcomp_for_dynamic_init(int flags, int first, int last, int step, int chunksize)
@ -126,7 +126,7 @@ index 31814d6..174ce06 100644
int CDECL omp_in_parallel(void)
{
TRACE("()\n");
@@ -572,11 +661,13 @@ void WINAPIV _vcomp_fork(BOOL ifval, int nargs, void *wrapper, ...)
@@ -571,11 +660,13 @@ void WINAPIV _vcomp_fork(BOOL ifval, int nargs, void *wrapper, ...)
team_data.barrier = 0;
team_data.barrier_count = 0;
team_data.section = 0;
@ -140,7 +140,7 @@ index 31814d6..174ce06 100644
list_init(&thread_data.entry);
InitializeConditionVariable(&thread_data.cond);
@@ -593,6 +684,7 @@ void WINAPIV _vcomp_fork(BOOL ifval, int nargs, void *wrapper, ...)
@@ -592,6 +683,7 @@ void WINAPIV _vcomp_fork(BOOL ifval, int nargs, void *wrapper, ...)
data->thread_num = team_data.num_threads++;
data->fork_threads = 0;
data->section = 1;
@ -148,7 +148,7 @@ index 31814d6..174ce06 100644
list_remove(&data->entry);
list_add_tail(&thread_data.entry, &data->entry);
WakeAllConditionVariable(&data->cond);
@@ -612,6 +704,7 @@ void WINAPIV _vcomp_fork(BOOL ifval, int nargs, void *wrapper, ...)
@@ -611,6 +703,7 @@ void WINAPIV _vcomp_fork(BOOL ifval, int nargs, void *wrapper, ...)
data->thread_num = team_data.num_threads;
data->fork_threads = 0;
data->section = 1;
@ -157,7 +157,7 @@ index 31814d6..174ce06 100644
thread = CreateThread(NULL, 0, _vcomp_fork_worker, data, 0, NULL);
diff --git a/dlls/vcomp/tests/vcomp.c b/dlls/vcomp/tests/vcomp.c
index c962fe8..af04cc9 100644
index 8de4510b..3992bda 100644
--- a/dlls/vcomp/tests/vcomp.c
+++ b/dlls/vcomp/tests/vcomp.c
@@ -32,6 +32,8 @@ static BOOL (WINAPI *pDeactivateActCtx)(DWORD, ULONG_PTR);
@ -178,7 +178,7 @@ index c962fe8..af04cc9 100644
VCOMP_GET_PROC(_vcomp_for_static_end);
VCOMP_GET_PROC(_vcomp_for_static_init);
VCOMP_GET_PROC(_vcomp_for_static_simple_init);
@@ -807,6 +811,54 @@ static void test_vcomp_sections_init(void)
@@ -809,6 +813,54 @@ static void test_vcomp_for_static_init(void)
}
}
@ -233,10 +233,10 @@ index c962fe8..af04cc9 100644
START_TEST(vcomp)
{
if (!init_vcomp())
@@ -818,6 +870,7 @@ START_TEST(vcomp)
@@ -820,6 +872,7 @@ START_TEST(vcomp)
test_vcomp_sections_init();
test_vcomp_for_static_simple_init();
test_vcomp_for_static_init();
test_vcomp_sections_init();
+ test_vcomp_for_dynamic_init();
release_vcomp();

View File

@ -1,242 +0,0 @@
From 92b615e0038571e52fb6cc22164ba80c07dcf2f5 Mon Sep 17 00:00:00 2001
From: Sebastian Lackner <sebastian@fds-team.de>
Date: Sat, 11 Jul 2015 21:29:41 +0200
Subject: vcomp: Implement _vcomp_sections_init and _vcomp_sections_next and
add tests.
---
dlls/vcomp/main.c | 49 +++++++++++++++++++++++++++++++++++++++++++++
dlls/vcomp/tests/vcomp.c | 49 +++++++++++++++++++++++++++++++++++++++++++++
dlls/vcomp/vcomp.spec | 4 ++--
dlls/vcomp100/vcomp100.spec | 4 ++--
dlls/vcomp90/vcomp90.spec | 4 ++--
5 files changed, 104 insertions(+), 6 deletions(-)
diff --git a/dlls/vcomp/main.c b/dlls/vcomp/main.c
index a9a49ce..31814d6 100644
--- a/dlls/vcomp/main.c
+++ b/dlls/vcomp/main.c
@@ -58,6 +58,9 @@ struct vcomp_thread_data
/* only used for concurrent tasks */
struct list entry;
CONDITION_VARIABLE cond;
+
+ /* section */
+ unsigned int section;
};
struct vcomp_team_data
@@ -74,6 +77,11 @@ struct vcomp_team_data
/* barrier */
unsigned int barrier;
int barrier_count;
+
+ /* section */
+ unsigned int section;
+ unsigned int num_sections;
+ unsigned int section_index;
};
void CDECL _vcomp_fork_call_wrapper(void *wrapper, int nargs, __ms_va_list args);
@@ -453,6 +461,43 @@ void CDECL _vcomp_for_static_end(void)
TRACE("()\n");
}
+void CDECL _vcomp_sections_init(int n)
+{
+ struct vcomp_thread_data *thread_data = vcomp_get_thread_data();
+ struct vcomp_team_data *team_data = thread_data->team;
+
+ TRACE("(%d)\n", n);
+
+ EnterCriticalSection(&vcomp_section);
+ thread_data->section++;
+ if ((int)(thread_data->section - team_data->section) > 0)
+ {
+ /* first thread in a new section */
+ team_data->section = thread_data->section;
+ team_data->num_sections = n;
+ team_data->section_index = 0;
+ }
+ LeaveCriticalSection(&vcomp_section);
+}
+
+int CDECL _vcomp_sections_next(void)
+{
+ struct vcomp_thread_data *thread_data = vcomp_get_thread_data();
+ struct vcomp_team_data *team_data = thread_data->team;
+ int i = -1;
+
+ TRACE("()\n");
+
+ EnterCriticalSection(&vcomp_section);
+ if (thread_data->section == team_data->section &&
+ team_data->section_index < team_data->num_sections)
+ {
+ i = team_data->section_index++;
+ }
+ LeaveCriticalSection(&vcomp_section);
+ return i;
+}
+
int CDECL omp_in_parallel(void)
{
TRACE("()\n");
@@ -526,10 +571,12 @@ void WINAPIV _vcomp_fork(BOOL ifval, int nargs, void *wrapper, ...)
__ms_va_start(team_data.valist, wrapper);
team_data.barrier = 0;
team_data.barrier_count = 0;
+ team_data.section = 0;
thread_data.team = &team_data;
thread_data.thread_num = 0;
thread_data.fork_threads = 0;
+ thread_data.section = 1;
list_init(&thread_data.entry);
InitializeConditionVariable(&thread_data.cond);
@@ -545,6 +592,7 @@ void WINAPIV _vcomp_fork(BOOL ifval, int nargs, void *wrapper, ...)
data->team = &team_data;
data->thread_num = team_data.num_threads++;
data->fork_threads = 0;
+ data->section = 1;
list_remove(&data->entry);
list_add_tail(&thread_data.entry, &data->entry);
WakeAllConditionVariable(&data->cond);
@@ -563,6 +611,7 @@ void WINAPIV _vcomp_fork(BOOL ifval, int nargs, void *wrapper, ...)
data->team = &team_data;
data->thread_num = team_data.num_threads;
data->fork_threads = 0;
+ data->section = 1;
InitializeConditionVariable(&data->cond);
thread = CreateThread(NULL, 0, _vcomp_fork_worker, data, 0, NULL);
diff --git a/dlls/vcomp/tests/vcomp.c b/dlls/vcomp/tests/vcomp.c
index 0103af1..c962fe8 100644
--- a/dlls/vcomp/tests/vcomp.c
+++ b/dlls/vcomp/tests/vcomp.c
@@ -38,6 +38,8 @@ static void (CDECL *p_vcomp_for_static_init)(int first, int last, int step, i
static void (CDECL *p_vcomp_for_static_simple_init)(unsigned int first, unsigned int last, int step,
BOOL forward, unsigned int *begin, unsigned int *end);
static void (WINAPIV *p_vcomp_fork)(BOOL ifval, int nargs, void *wrapper, ...);
+static void (CDECL *p_vcomp_sections_init)(int n);
+static int (CDECL *p_vcomp_sections_next)(void);
static void (CDECL *p_vcomp_set_num_threads)(int num_threads);
static int (CDECL *pomp_get_max_threads)(void);
static int (CDECL *pomp_get_nested)(void);
@@ -177,6 +179,8 @@ static BOOL init_vcomp(void)
VCOMP_GET_PROC(_vcomp_for_static_init);
VCOMP_GET_PROC(_vcomp_for_static_simple_init);
VCOMP_GET_PROC(_vcomp_fork);
+ VCOMP_GET_PROC(_vcomp_sections_init);
+ VCOMP_GET_PROC(_vcomp_sections_next);
VCOMP_GET_PROC(_vcomp_set_num_threads);
VCOMP_GET_PROC(omp_get_max_threads);
VCOMP_GET_PROC(omp_get_nested);
@@ -759,6 +763,50 @@ static void test_vcomp_for_static_init(void)
}
}
+static void CDECL _test_vcomp_sections_init(LONG *a, LONG *b, LONG *c)
+{
+ int i;
+
+ p_vcomp_sections_init(20);
+ while ((i = p_vcomp_sections_next()) != -1)
+ {
+ InterlockedIncrement(a);
+ Sleep(50);
+ }
+
+ p_vcomp_sections_init(30);
+ while ((i = p_vcomp_sections_next()) != -1)
+ {
+ InterlockedIncrement(b);
+ Sleep(50);
+ }
+
+ p_vcomp_sections_init(40);
+ while ((i = p_vcomp_sections_next()) != -1)
+ {
+ InterlockedIncrement(c);
+ Sleep(50);
+ }
+}
+
+static void test_vcomp_sections_init(void)
+{
+ LONG a, b, c;
+ int i;
+
+ for (i = 1; i <= 4; i++)
+ {
+ trace("Running tests with %d threads\n", i);
+ pomp_set_num_threads(i);
+
+ a = b = c = 0;
+ p_vcomp_fork(TRUE, 3, _test_vcomp_sections_init, &a, &b, &c);
+ ok(a == 20, "expected a = 20, got %d\n", a);
+ ok(b == 30, "expected b = 30, got %d\n", b);
+ ok(c == 40, "expected c = 40, got %d\n", c);
+ }
+}
+
START_TEST(vcomp)
{
if (!init_vcomp())
@@ -769,6 +817,7 @@ START_TEST(vcomp)
test_vcomp_fork();
test_vcomp_for_static_simple_init();
test_vcomp_for_static_init();
+ test_vcomp_sections_init();
release_vcomp();
}
diff --git a/dlls/vcomp/vcomp.spec b/dlls/vcomp/vcomp.spec
index 156233f..7083ce4 100644
--- a/dlls/vcomp/vcomp.spec
+++ b/dlls/vcomp/vcomp.spec
@@ -83,8 +83,8 @@
@ stub _vcomp_reduction_u2
@ stub _vcomp_reduction_u4
@ stub _vcomp_reduction_u8
-@ stub _vcomp_sections_init
-@ stub _vcomp_sections_next
+@ cdecl _vcomp_sections_init(long)
+@ cdecl _vcomp_sections_next()
@ cdecl _vcomp_set_num_threads(long)
@ cdecl _vcomp_single_begin(long)
@ cdecl _vcomp_single_end()
diff --git a/dlls/vcomp100/vcomp100.spec b/dlls/vcomp100/vcomp100.spec
index dd276d0..56c7ae3 100644
--- a/dlls/vcomp100/vcomp100.spec
+++ b/dlls/vcomp100/vcomp100.spec
@@ -83,8 +83,8 @@
@ stub _vcomp_reduction_u2
@ stub _vcomp_reduction_u4
@ stub _vcomp_reduction_u8
-@ stub _vcomp_sections_init
-@ stub _vcomp_sections_next
+@ cdecl _vcomp_sections_init(long) vcomp._vcomp_sections_init
+@ cdecl _vcomp_sections_next() vcomp._vcomp_sections_next
@ cdecl _vcomp_set_num_threads(long) vcomp._vcomp_set_num_threads
@ cdecl _vcomp_single_begin(long) vcomp._vcomp_single_begin
@ cdecl _vcomp_single_end() vcomp._vcomp_single_end
diff --git a/dlls/vcomp90/vcomp90.spec b/dlls/vcomp90/vcomp90.spec
index dd276d0..56c7ae3 100644
--- a/dlls/vcomp90/vcomp90.spec
+++ b/dlls/vcomp90/vcomp90.spec
@@ -83,8 +83,8 @@
@ stub _vcomp_reduction_u2
@ stub _vcomp_reduction_u4
@ stub _vcomp_reduction_u8
-@ stub _vcomp_sections_init
-@ stub _vcomp_sections_next
+@ cdecl _vcomp_sections_init(long) vcomp._vcomp_sections_init
+@ cdecl _vcomp_sections_next() vcomp._vcomp_sections_next
@ cdecl _vcomp_set_num_threads(long) vcomp._vcomp_set_num_threads
@ cdecl _vcomp_single_begin(long) vcomp._vcomp_single_begin
@ cdecl _vcomp_single_end() vcomp._vcomp_single_end
--
2.4.5

View File

@ -1,7 +1,7 @@
From 2efe4f101c0dc1b87b176d6652576f8e1880a72a Mon Sep 17 00:00:00 2001
From 7b26357b2125f80df05269f2bb38592dd2e8be6f Mon Sep 17 00:00:00 2001
From: Austin English <austinenglish@gmail.com>
Date: Thu, 7 May 2015 06:15:58 +0200
Subject: winsta: Add stub for WinStationEnumerateW.
Subject: winsta: Add stub for WinStationEnumerateW. (v2)
---
dlls/winsta/main.c | 7 +++++++
@ -9,22 +9,22 @@ Subject: winsta: Add stub for WinStationEnumerateW.
2 files changed, 8 insertions(+), 1 deletion(-)
diff --git a/dlls/winsta/main.c b/dlls/winsta/main.c
index 46a4ce7..82e5d36 100644
index a95782f..59efef2 100644
--- a/dlls/winsta/main.c
+++ b/dlls/winsta/main.c
@@ -90,3 +90,10 @@ BOOL WINAPI WinStationVirtualOpen( PVOID a, PVOID b, PVOID c )
@@ -91,3 +91,10 @@ BOOL WINAPI WinStationVirtualOpen( PVOID a, PVOID b, PVOID c )
SetLastError( ERROR_CALL_NOT_IMPLEMENTED );
return FALSE;
}
+
+BOOLEAN WINAPI WinStationEnumerateW( HANDLE server, void *sessionids, PULONG count )
+BOOLEAN WINAPI WinStationEnumerateW( HANDLE server, PSESSIONIDW *sessionids, ULONG *count )
+{
+ FIXME( "%p %p %p\n", server, sessionids, count );
+ SetLastError( ERROR_CALL_NOT_IMPLEMENTED );
+ return FALSE;
+}
diff --git a/dlls/winsta/winsta.spec b/dlls/winsta/winsta.spec
index 5854d83..6c4affc 100644
index 30aa6b5..a9def1a 100644
--- a/dlls/winsta/winsta.spec
+++ b/dlls/winsta/winsta.spec
@@ -29,7 +29,7 @@
@ -37,5 +37,5 @@ index 5854d83..6c4affc 100644
@ stub WinStationEnumerate_IndexedW
@ stub WinStationFreeGAPMemory
--
2.3.7
2.4.5