mirror of
https://gitlab.winehq.org/wine/wine-staging.git
synced 2024-09-13 09:17:20 -07:00
Rebase against 22f28d2923811b85024f63ce43e41966a864ecd0.
This commit is contained in:
parent
d26abf2d93
commit
d205f22f1e
@ -1,4 +1,4 @@
|
||||
From 16bb8ba07739f3c189920cdbf56f87aa520456c0 Mon Sep 17 00:00:00 2001
|
||||
From f4024fac3fba56c007fa873a66271eef4f6c31ff Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Michael=20M=C3=BCller?= <michael@fds-team.de>
|
||||
Date: Wed, 1 Apr 2015 04:34:20 +0200
|
||||
Subject: ntdll: Load CLI/.NET images in the same way as Windows XP and above.
|
||||
@ -9,7 +9,7 @@ Subject: ntdll: Load CLI/.NET images in the same way as Windows XP and above.
|
||||
2 files changed, 133 insertions(+), 10 deletions(-)
|
||||
|
||||
diff --git a/dlls/kernel32/process.c b/dlls/kernel32/process.c
|
||||
index 2c8074b..5810080 100644
|
||||
index 1cd6e47..4d985d4 100644
|
||||
--- a/dlls/kernel32/process.c
|
||||
+++ b/dlls/kernel32/process.c
|
||||
@@ -1079,16 +1079,11 @@ static inline DWORD call_process_entry( PEB *peb, LPTHREAD_START_ROUTINE entry )
|
||||
@ -33,11 +33,11 @@ index 2c8074b..5810080 100644
|
||||
ERR( "%s doesn't have an entry point, it cannot be executed\n",
|
||||
debugstr_w(peb->ProcessParameters->ImagePathName.Buffer) );
|
||||
diff --git a/dlls/ntdll/loader.c b/dlls/ntdll/loader.c
|
||||
index 9810f07..18f20fe 100644
|
||||
index bef0ab1..2dd8ad0 100644
|
||||
--- a/dlls/ntdll/loader.c
|
||||
+++ b/dlls/ntdll/loader.c
|
||||
@@ -97,6 +97,10 @@ static UINT tls_module_count; /* number of modules with TLS directory */
|
||||
static const IMAGE_TLS_DIRECTORY **tls_dirs; /* array of TLS directories */
|
||||
static IMAGE_TLS_DIRECTORY *tls_dirs; /* array of TLS directories */
|
||||
LIST_ENTRY tls_links = { &tls_links, &tls_links };
|
||||
|
||||
+static HRESULT (WINAPI *p_CorValidateImage)(PVOID* ImageBase, LPCWSTR FileName);
|
||||
@ -126,7 +126,7 @@ index 9810f07..18f20fe 100644
|
||||
* get_modref
|
||||
*
|
||||
* Looks for the referenced HMODULE in the current process
|
||||
@@ -863,6 +939,10 @@ static NTSTATUS fixup_imports( WINE_MODREF *wm, LPCWSTR load_path )
|
||||
@@ -868,6 +944,10 @@ static NTSTATUS fixup_imports( WINE_MODREF *wm, LPCWSTR load_path )
|
||||
if (!(wm->ldr.Flags & LDR_DONT_RESOLVE_REFS)) return STATUS_SUCCESS; /* already done */
|
||||
wm->ldr.Flags &= ~LDR_DONT_RESOLVE_REFS;
|
||||
|
||||
@ -137,7 +137,7 @@ index 9810f07..18f20fe 100644
|
||||
wm->ldr.TlsIndex = alloc_tls_slot( &wm->ldr );
|
||||
|
||||
if (!(imports = RtlImageDirectoryEntryToData( wm->ldr.BaseAddress, TRUE,
|
||||
@@ -1058,8 +1138,43 @@ static NTSTATUS MODULE_InitDLL( WINE_MODREF *wm, UINT reason, LPVOID lpReserved
|
||||
@@ -1063,8 +1143,43 @@ static NTSTATUS MODULE_InitDLL( WINE_MODREF *wm, UINT reason, LPVOID lpReserved
|
||||
BOOL retv = FALSE;
|
||||
|
||||
/* Skip calls for modules loaded with special load flags */
|
||||
@ -182,7 +182,7 @@ index 9810f07..18f20fe 100644
|
||||
if (wm->ldr.TlsIndex != -1) call_tls_callbacks( wm->ldr.BaseAddress, reason );
|
||||
if (!entry || !(wm->ldr.Flags & LDR_IMAGE_IS_DLL)) return STATUS_SUCCESS;
|
||||
|
||||
@@ -2865,7 +2980,20 @@ static void load_global_options(void)
|
||||
@@ -2870,7 +2985,20 @@ static void load_global_options(void)
|
||||
*/
|
||||
static void start_process( void *kernel_start )
|
||||
{
|
||||
@ -205,5 +205,5 @@ index 9810f07..18f20fe 100644
|
||||
|
||||
/******************************************************************
|
||||
--
|
||||
2.3.3
|
||||
2.4.5
|
||||
|
||||
|
@ -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 a8f45dff604058d419bd6c2e070f65a13a6ddfdb"
|
||||
echo " commit 22f28d2923811b85024f63ce43e41966a864ecd0"
|
||||
echo ""
|
||||
}
|
||||
|
||||
@ -203,7 +203,6 @@ patch_enable_all ()
|
||||
enable_server_RootDirectory_File="$1"
|
||||
enable_server_Shared_Memory="$1"
|
||||
enable_server_Stored_ACLs="$1"
|
||||
enable_server_Unexpected_Wakeup="$1"
|
||||
enable_setupapi_SetupDiSelectBestCompatDrv="$1"
|
||||
enable_setupapi_SetupDiSetDeviceInstallParamsW="$1"
|
||||
enable_setupapi_SetupPromptForDisk="$1"
|
||||
@ -678,9 +677,6 @@ patch_enable ()
|
||||
server-Stored_ACLs)
|
||||
enable_server_Stored_ACLs="$2"
|
||||
;;
|
||||
server-Unexpected_Wakeup)
|
||||
enable_server_Unexpected_Wakeup="$2"
|
||||
;;
|
||||
setupapi-SetupDiSelectBestCompatDrv)
|
||||
enable_setupapi_SetupDiSelectBestCompatDrv="$2"
|
||||
;;
|
||||
@ -1407,9 +1403,6 @@ if test "$enable_category_stable" -eq 1; then
|
||||
if test "$enable_server_Delete_On_Close" -gt 1; then
|
||||
abort "Patchset server-Delete_On_Close disabled, but category-stable depends on that."
|
||||
fi
|
||||
if test "$enable_server_Unexpected_Wakeup" -gt 1; then
|
||||
abort "Patchset server-Unexpected_Wakeup disabled, but category-stable depends on that."
|
||||
fi
|
||||
if test "$enable_setupapi_SetupDiSetDeviceInstallParamsW" -gt 1; then
|
||||
abort "Patchset setupapi-SetupDiSetDeviceInstallParamsW disabled, but category-stable depends on that."
|
||||
fi
|
||||
@ -1538,7 +1531,6 @@ if test "$enable_category_stable" -eq 1; then
|
||||
enable_server_ClipCursor=1
|
||||
enable_server_CreateProcess_ACLs=1
|
||||
enable_server_Delete_On_Close=1
|
||||
enable_server_Unexpected_Wakeup=1
|
||||
enable_setupapi_SetupDiSetDeviceInstallParamsW=1
|
||||
enable_shell32_RunDLL_CallEntry16=1
|
||||
enable_shell32_SHFileOperation=1
|
||||
@ -4115,20 +4107,6 @@ if test "$enable_server_Shared_Memory" -eq 1; then
|
||||
) >> "$patchlist"
|
||||
fi
|
||||
|
||||
# Patchset server-Unexpected_Wakeup
|
||||
# |
|
||||
# | Modified files:
|
||||
# | * dlls/kernel32/tests/sync.c, server/thread.c
|
||||
# |
|
||||
if test "$enable_server_Unexpected_Wakeup" -eq 1; then
|
||||
patch_apply server-Unexpected_Wakeup/0001-server-Avoid-sending-unexpected-wakeup-with-uninitia.patch
|
||||
patch_apply server-Unexpected_Wakeup/0002-kernel32-tests-Repeat-test-for-SignalObjectAndWait-m.patch
|
||||
(
|
||||
echo '+ { "Sebastian Lackner", "server: Avoid sending unexpected wakeup with uninitialized cookie value.", 1 },';
|
||||
echo '+ { "Sebastian Lackner", "kernel32/tests: Repeat test for SignalObjectAndWait multiple times to test wineserver wakeup cookie management.", 1 },';
|
||||
) >> "$patchlist"
|
||||
fi
|
||||
|
||||
# Patchset setupapi-SetupDiSelectBestCompatDrv
|
||||
# |
|
||||
# | This patchset fixes the following Wine bugs:
|
||||
@ -4513,31 +4491,32 @@ 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/tests/vcomp.manifest, dlls/vcomp/tests/vcomp.rc, dlls/vcomp/vcomp.spec, dlls/vcomp100/vcomp100.spec,
|
||||
# | dlls/vcomp90/vcomp90.spec
|
||||
# | * 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
|
||||
# |
|
||||
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-basic-worker-thread-infrastructure.patch
|
||||
patch_apply vcomp-Functions/0003-vcomp-tests-Add-initial-tests-for-_vcomp_fork.patch
|
||||
patch_apply vcomp-Functions/0004-vcomp-Implement-_vcomp_for_static_simple_init-and-_v.patch
|
||||
patch_apply vcomp-Functions/0005-vcomp-tests-Add-tests-for-_vcomp_for_static_simple_i.patch
|
||||
patch_apply vcomp-Functions/0006-vcomp-Implement-_vcomp_for_static_init.patch
|
||||
patch_apply vcomp-Functions/0007-vcomp-tests-Add-tests-for-_vcomp_for_static_init.patch
|
||||
patch_apply vcomp-Functions/0008-vcomp-Implement-_vcomp_barrier.patch
|
||||
patch_apply vcomp-Functions/0009-vcomp-Implement-omp_in_parallel.patch
|
||||
patch_apply vcomp-Functions/0010-vcomp-Implement-_vcomp_sections_init-and-_vcomp_sect.patch
|
||||
patch_apply vcomp-Functions/0011-vcomp-Implement-_vcomp_for_dynamic_init-and-_vcomp_f.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
|
||||
(
|
||||
echo '+ { "Dan Kegel", "vcomp: Implement stub for _vcomp_fork.", 1 },';
|
||||
echo '+ { "Sebastian Lackner", "vcomp: Add basic worker thread infrastructure.", 1 },';
|
||||
echo '+ { "Dan Kegel", "vcomp/tests: Add initial tests 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 _vcomp_barrier.", 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 },';
|
||||
|
@ -1,67 +0,0 @@
|
||||
From 9df06c6e4b4cf258b7f321dfd5e20467bef2b36f Mon Sep 17 00:00:00 2001
|
||||
From: Sebastian Lackner <sebastian@fds-team.de>
|
||||
Date: Sat, 22 Nov 2014 17:42:22 +0100
|
||||
Subject: server: Avoid sending unexpected wakeup with uninitialized cookie
|
||||
value.
|
||||
|
||||
While executing the kernel32/sync tests I noticed a couple of unexpected wakeup cookies, which looked like uninitialized wineserver memory.
|
||||
Here an excerpt from the log (added additional debug values):
|
||||
---
|
||||
server/thread.c | 13 +++++++++++--
|
||||
1 file changed, 11 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/server/thread.c b/server/thread.c
|
||||
index ba3f1d5..bdd9ef7 100644
|
||||
--- a/server/thread.c
|
||||
+++ b/server/thread.c
|
||||
@@ -601,6 +601,7 @@ static int wait_on( const select_op_t *select_op, unsigned int count, struct obj
|
||||
wait->count = count;
|
||||
wait->flags = flags;
|
||||
wait->select = select_op->op;
|
||||
+ wait->cookie = 0;
|
||||
wait->user = NULL;
|
||||
wait->timeout = timeout;
|
||||
wait->abandoned = 0;
|
||||
@@ -719,7 +720,7 @@ int wake_thread( struct thread *thread )
|
||||
cookie = thread->wait->cookie;
|
||||
if (debug_level) fprintf( stderr, "%04x: *wakeup* signaled=%d\n", thread->id, signaled );
|
||||
end_wait( thread );
|
||||
- if (send_thread_wakeup( thread, cookie, signaled ) == -1) /* error */
|
||||
+ if (cookie && send_thread_wakeup( thread, cookie, signaled ) == -1) /* error */
|
||||
{
|
||||
if (!count) count = -1;
|
||||
break;
|
||||
@@ -749,7 +750,7 @@ int wake_thread_queue_entry( struct wait_queue_entry *entry )
|
||||
if (debug_level) fprintf( stderr, "%04x: *wakeup* signaled=%d\n", thread->id, signaled );
|
||||
end_wait( thread );
|
||||
|
||||
- if (send_thread_wakeup( thread, cookie, signaled ) != -1)
|
||||
+ if (!cookie || send_thread_wakeup( thread, cookie, signaled ) != -1)
|
||||
wake_thread( thread ); /* check other waits too */
|
||||
|
||||
return 1;
|
||||
@@ -768,6 +769,8 @@ static void thread_timeout( void *ptr )
|
||||
|
||||
if (debug_level) fprintf( stderr, "%04x: *wakeup* signaled=TIMEOUT\n", thread->id );
|
||||
end_wait( thread );
|
||||
+
|
||||
+ assert( cookie );
|
||||
if (send_thread_wakeup( thread, cookie, STATUS_TIMEOUT ) == -1) return;
|
||||
/* check if other objects have become signaled in the meantime */
|
||||
wake_thread( thread );
|
||||
@@ -1429,6 +1432,12 @@ DECL_HANDLER(select)
|
||||
set_error( STATUS_INVALID_PARAMETER );
|
||||
return;
|
||||
}
|
||||
+ if (!req->cookie)
|
||||
+ {
|
||||
+ set_error( STATUS_INVALID_PARAMETER );
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
op_size = min( get_req_data_size() - sizeof(*result), sizeof(select_op) );
|
||||
memset( &select_op, 0, sizeof(select_op) );
|
||||
memcpy( &select_op, result + 1, op_size );
|
||||
--
|
||||
2.1.3
|
||||
|
@ -1,42 +0,0 @@
|
||||
From e8a0619c85e774abd866e3882038dee563007c77 Mon Sep 17 00:00:00 2001
|
||||
From: Sebastian Lackner <sebastian@fds-team.de>
|
||||
Date: Tue, 16 Dec 2014 06:23:15 +0100
|
||||
Subject: kernel32/tests: Repeat test for SignalObjectAndWait multiple times to
|
||||
test wineserver wakeup cookie management.
|
||||
|
||||
---
|
||||
dlls/kernel32/tests/sync.c | 11 ++++++++---
|
||||
1 file changed, 8 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/dlls/kernel32/tests/sync.c b/dlls/kernel32/tests/sync.c
|
||||
index cbe0acb..668b92d 100644
|
||||
--- a/dlls/kernel32/tests/sync.c
|
||||
+++ b/dlls/kernel32/tests/sync.c
|
||||
@@ -64,6 +64,7 @@ static void test_signalandwait(void)
|
||||
HMODULE kernel32;
|
||||
DWORD r;
|
||||
HANDLE event[2], semaphore[2], file;
|
||||
+ int i;
|
||||
|
||||
kernel32 = GetModuleHandleA("kernel32.dll");
|
||||
pSignalObjectAndWait = (void*) GetProcAddress(kernel32, "SignalObjectAndWait");
|
||||
@@ -96,9 +97,13 @@ static void test_signalandwait(void)
|
||||
r = pSignalObjectAndWait(event[0], event[1], 0, FALSE);
|
||||
ok( r == WAIT_OBJECT_0, "should succeed\n");
|
||||
|
||||
- /* event[0] is now signalled */
|
||||
- r = pSignalObjectAndWait(event[0], event[0], 0, FALSE);
|
||||
- ok( r == WAIT_OBJECT_0, "should succeed\n");
|
||||
+ /* event[0] is now signalled - we repeat this test multiple times
|
||||
+ * to ensure that the wineserver handles this situation properly. */
|
||||
+ for (i = 0; i < 10000; i++)
|
||||
+ {
|
||||
+ r = pSignalObjectAndWait(event[0], event[0], 0, FALSE);
|
||||
+ ok( r == WAIT_OBJECT_0, "should succeed\n");
|
||||
+ }
|
||||
|
||||
/* event[0] is not signalled */
|
||||
r = WaitForSingleObject(event[0], 0);
|
||||
--
|
||||
2.1.3
|
||||
|
@ -1 +0,0 @@
|
||||
Category: stable
|
@ -1,17 +1,20 @@
|
||||
From 6404654fd885acbf0e563d9b5070d321986b5b8d Mon Sep 17 00:00:00 2001
|
||||
From d0d4b3991b691ee74e999f82dbf57a5a400fe7db Mon Sep 17 00:00:00 2001
|
||||
From: Dan Kegel <dank@kegel.com>
|
||||
Date: Sat, 11 Jul 2015 06:50:26 +0200
|
||||
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 | 93 +++++++++++++++++++++++++++++++++++++++++++++
|
||||
dlls/vcomp/main.c | 95 +++++++++++++++++++++++++++++++++++++++++++++
|
||||
dlls/vcomp/vcomp.spec | 2 +-
|
||||
dlls/vcomp100/vcomp100.spec | 2 +-
|
||||
dlls/vcomp90/vcomp90.spec | 2 +-
|
||||
4 files changed, 96 insertions(+), 3 deletions(-)
|
||||
4 files changed, 98 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/dlls/vcomp/main.c b/dlls/vcomp/main.c
|
||||
index ab2a372..26f6c67 100644
|
||||
index 8ec3616..03c085b 100644
|
||||
--- a/dlls/vcomp/main.c
|
||||
+++ b/dlls/vcomp/main.c
|
||||
@@ -3,6 +3,7 @@
|
||||
@ -22,24 +25,14 @@ index ab2a372..26f6c67 100644
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
@@ -107,6 +108,98 @@ void CDECL _vcomp_single_end(void)
|
||||
TRACE("stub\n");
|
||||
}
|
||||
@@ -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);
|
||||
+
|
||||
+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);
|
||||
+}
|
||||
+
|
||||
+#if defined(__i386__)
|
||||
+
|
||||
+__ASM_GLOBAL_FUNC( _vcomp_fork_call_wrapper,
|
||||
+ "pushl %ebp\n\t"
|
||||
+ __ASM_CFI(".cfi_adjust_cfa_offset 4\n\t")
|
||||
@ -109,6 +102,7 @@ index ab2a372..26f6c67 100644
|
||||
+ __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)
|
||||
@ -118,9 +112,27 @@ index ab2a372..26f6c67 100644
|
||||
+
|
||||
+#endif
|
||||
+
|
||||
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
|
||||
static inline struct vcomp_thread_data *vcomp_get_thread_data(void)
|
||||
{
|
||||
TRACE("(0x%p, %d, %p)\n", hinstDLL, fdwReason, lpvReserved);
|
||||
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
|
||||
|
@ -1,311 +0,0 @@
|
||||
From e3f58ae29d504bd1f2287566878b7d6674bd5484 Mon Sep 17 00:00:00 2001
|
||||
From: Sebastian Lackner <sebastian@fds-team.de>
|
||||
Date: Sat, 11 Jul 2015 18:53:41 +0200
|
||||
Subject: vcomp: Add basic worker thread infrastructure.
|
||||
|
||||
---
|
||||
dlls/vcomp/main.c | 221 +++++++++++++++++++++++++++++++++++++++++++++++++++---
|
||||
1 file changed, 211 insertions(+), 10 deletions(-)
|
||||
|
||||
diff --git a/dlls/vcomp/main.c b/dlls/vcomp/main.c
|
||||
index 26f6c67..9de9721 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,13 +24,68 @@
|
||||
#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 HMODULE vcomp_module;
|
||||
+static struct list vcomp_idle_threads = LIST_INIT(vcomp_idle_threads);
|
||||
+static DWORD vcomp_context_tls = TLS_OUT_OF_INDEXES;
|
||||
+static DWORD vcomp_max_threads = 32;
|
||||
+static DWORD vcomp_num_threads = 1;
|
||||
+
|
||||
+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_info
|
||||
+{
|
||||
+ struct list entry;
|
||||
+ CONDITION_VARIABLE cond;
|
||||
+
|
||||
+ /* current task */
|
||||
+ struct vcomp_team_info *team;
|
||||
+ DWORD thread_num;
|
||||
+};
|
||||
+
|
||||
+struct vcomp_team_info
|
||||
+{
|
||||
+ CONDITION_VARIABLE cond;
|
||||
+ DWORD num_threads;
|
||||
+ DWORD finished_threads;
|
||||
+
|
||||
+ /* callback arguments */
|
||||
+ unsigned int nargs;
|
||||
+ void *wrapper;
|
||||
+ __ms_va_list valist;
|
||||
+};
|
||||
+
|
||||
+static inline struct vcomp_thread_info *vcomp_get_thread_info(void)
|
||||
+{
|
||||
+ return (struct vcomp_thread_info *)TlsGetValue(vcomp_context_tls);
|
||||
+}
|
||||
+
|
||||
+static inline struct vcomp_team_info *vcomp_get_team_info(void)
|
||||
+{
|
||||
+ struct vcomp_thread_info *thread_info = vcomp_get_thread_info();
|
||||
+ return thread_info ? thread_info->team : NULL;
|
||||
+}
|
||||
+
|
||||
+static inline void vcomp_set_thread_info(struct vcomp_thread_info *thread_info)
|
||||
+{
|
||||
+ TlsSetValue(vcomp_context_tls, thread_info);
|
||||
+}
|
||||
+
|
||||
int CDECL omp_get_dynamic(void)
|
||||
{
|
||||
TRACE("stub\n");
|
||||
@@ -39,7 +95,7 @@ int CDECL omp_get_dynamic(void)
|
||||
int CDECL omp_get_max_threads(void)
|
||||
{
|
||||
TRACE("stub\n");
|
||||
- return 1;
|
||||
+ return vcomp_max_threads;
|
||||
}
|
||||
|
||||
int CDECL omp_get_nested(void)
|
||||
@@ -56,14 +112,22 @@ int CDECL omp_get_num_procs(void)
|
||||
|
||||
int CDECL omp_get_num_threads(void)
|
||||
{
|
||||
- TRACE("stub\n");
|
||||
- return 1;
|
||||
+ struct vcomp_team_info *team_info;
|
||||
+
|
||||
+ TRACE("()\n");
|
||||
+
|
||||
+ team_info = vcomp_get_team_info();
|
||||
+ return team_info ? team_info->num_threads : 1;
|
||||
}
|
||||
|
||||
int CDECL omp_get_thread_num(void)
|
||||
{
|
||||
- TRACE("stub\n");
|
||||
- return 0;
|
||||
+ struct vcomp_thread_info *thread_info;
|
||||
+
|
||||
+ TRACE("()\n");
|
||||
+
|
||||
+ thread_info = vcomp_get_thread_info();
|
||||
+ return thread_info ? thread_info->thread_num : 0;
|
||||
}
|
||||
|
||||
/* Time in seconds since "some time in the past" */
|
||||
@@ -85,6 +149,7 @@ void CDECL omp_set_nested(int nested)
|
||||
void CDECL omp_set_num_threads(int num_threads)
|
||||
{
|
||||
TRACE("(%d): stub\n", num_threads);
|
||||
+ vcomp_num_threads = max(1, min(num_threads, vcomp_max_threads));
|
||||
}
|
||||
|
||||
void CDECL _vcomp_barrier(void)
|
||||
@@ -94,7 +159,8 @@ void CDECL _vcomp_barrier(void)
|
||||
|
||||
void CDECL _vcomp_set_num_threads(int num_threads)
|
||||
{
|
||||
- TRACE("(%d): stub\n", num_threads);
|
||||
+ TRACE("(%d)\n", num_threads);
|
||||
+ vcomp_num_threads = max(1, min(num_threads, vcomp_max_threads));
|
||||
}
|
||||
|
||||
int CDECL _vcomp_single_begin(int flags)
|
||||
@@ -110,15 +176,139 @@ void CDECL _vcomp_single_end(void)
|
||||
|
||||
void CDECL _vcomp_fork_call_wrapper(void *wrapper, int nargs, __ms_va_list args);
|
||||
|
||||
+static DWORD WINAPI _vcomp_fork_worker(void *param)
|
||||
+{
|
||||
+ struct vcomp_thread_info *thread_info = param;
|
||||
+ vcomp_set_thread_info(thread_info);
|
||||
+
|
||||
+ TRACE("starting worker thread %p\n", thread_info);
|
||||
+
|
||||
+ EnterCriticalSection(&vcomp_section);
|
||||
+ for (;;)
|
||||
+ {
|
||||
+ struct vcomp_team_info *team = thread_info->team;
|
||||
+ if (team != NULL)
|
||||
+ {
|
||||
+ /* Leave critical section and execute callback. */
|
||||
+ LeaveCriticalSection(&vcomp_section);
|
||||
+ _vcomp_fork_call_wrapper(team->wrapper, team->nargs, team->valist);
|
||||
+ EnterCriticalSection(&vcomp_section);
|
||||
+
|
||||
+ /* Detach current thread from team. */
|
||||
+ thread_info->team = NULL;
|
||||
+ list_remove(&thread_info->entry);
|
||||
+ list_add_tail(&vcomp_idle_threads, &thread_info->entry);
|
||||
+ if (++team->finished_threads >= team->num_threads)
|
||||
+ WakeAllConditionVariable(&team->cond);
|
||||
+ }
|
||||
+
|
||||
+ if (!SleepConditionVariableCS(&thread_info->cond, &vcomp_section, 5000) &&
|
||||
+ GetLastError() == ERROR_TIMEOUT && !thread_info->team)
|
||||
+ {
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+ list_remove(&thread_info->entry);
|
||||
+ LeaveCriticalSection(&vcomp_section);
|
||||
+
|
||||
+ TRACE("terminating worker thread %p\n", thread_info);
|
||||
+ HeapFree(GetProcessHeap(), 0, thread_info);
|
||||
+ FreeLibraryAndExitThread(vcomp_module, 0);
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
void WINAPIV _vcomp_fork(BOOL ifval, int nargs, void *wrapper, ...)
|
||||
{
|
||||
- __ms_va_list valist;
|
||||
+ struct vcomp_thread_info thread_info, *prev_thread_info;
|
||||
+ struct vcomp_team_info team_info;
|
||||
+ DWORD num_threads = vcomp_num_threads; /* FIXME */
|
||||
+ BOOL parallel = ifval;
|
||||
|
||||
TRACE("(%d, %d, %p, ...)\n", ifval, nargs, wrapper);
|
||||
|
||||
- __ms_va_start(valist, wrapper);
|
||||
- _vcomp_fork_call_wrapper(wrapper, nargs, valist);
|
||||
- __ms_va_end(valist);
|
||||
+ /* Initialize members of team_info. */
|
||||
+ InitializeConditionVariable(&team_info.cond);
|
||||
+ team_info.num_threads = 1;
|
||||
+ team_info.finished_threads = 0;
|
||||
+ team_info.nargs = nargs;
|
||||
+ team_info.wrapper = wrapper;
|
||||
+ __ms_va_start(team_info.valist, wrapper);
|
||||
+
|
||||
+ /* Initialize members of thread_info. */
|
||||
+ list_init(&thread_info.entry);
|
||||
+ InitializeConditionVariable(&thread_info.cond);
|
||||
+ thread_info.team = &team_info;
|
||||
+ thread_info.thread_num = 0;
|
||||
+
|
||||
+ if (parallel)
|
||||
+ {
|
||||
+ struct list *ptr;
|
||||
+ EnterCriticalSection(&vcomp_section);
|
||||
+
|
||||
+ /* Try to reuse idle threads. */
|
||||
+ while (team_info.num_threads < num_threads &&
|
||||
+ (ptr = list_head( &vcomp_idle_threads )))
|
||||
+ {
|
||||
+ struct vcomp_thread_info *info = LIST_ENTRY(ptr, struct vcomp_thread_info, entry);
|
||||
+ list_remove(&info->entry);
|
||||
+ list_add_tail(&thread_info.entry, &info->entry);
|
||||
+ info->team = &team_info;
|
||||
+ info->thread_num = team_info.num_threads++;
|
||||
+ WakeAllConditionVariable(&info->cond);
|
||||
+ }
|
||||
+
|
||||
+ /* Spawn additional new threads. */
|
||||
+ while (team_info.num_threads < num_threads)
|
||||
+ {
|
||||
+ struct vcomp_thread_info *info;
|
||||
+ HMODULE module;
|
||||
+ HANDLE thread;
|
||||
+
|
||||
+ info = HeapAlloc(GetProcessHeap(), 0, sizeof(*info));
|
||||
+ if (!info) break;
|
||||
+
|
||||
+ InitializeConditionVariable(&info->cond);
|
||||
+ info->team = &team_info;
|
||||
+ info->thread_num = team_info.num_threads;
|
||||
+
|
||||
+ thread = CreateThread(NULL, 0, _vcomp_fork_worker, info, 0, NULL);
|
||||
+ if (!thread)
|
||||
+ {
|
||||
+ HeapFree(GetProcessHeap(), 0, info);
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ GetModuleHandleExW(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS,
|
||||
+ (const WCHAR *)vcomp_module, &module);
|
||||
+
|
||||
+ list_add_tail(&thread_info.entry, &info->entry);
|
||||
+ team_info.num_threads++;
|
||||
+ CloseHandle(thread);
|
||||
+ }
|
||||
+
|
||||
+ LeaveCriticalSection(&vcomp_section);
|
||||
+ }
|
||||
+
|
||||
+ /* Call the callback in the context of the new team. */
|
||||
+ prev_thread_info = vcomp_get_thread_info();
|
||||
+ vcomp_set_thread_info(&thread_info);
|
||||
+ _vcomp_fork_call_wrapper(team_info.wrapper, team_info.nargs, team_info.valist);
|
||||
+ vcomp_set_thread_info(prev_thread_info);
|
||||
+
|
||||
+ /* Implicit join, wait for other tasks. */
|
||||
+ if (parallel)
|
||||
+ {
|
||||
+ EnterCriticalSection(&vcomp_section);
|
||||
+
|
||||
+ team_info.finished_threads++;
|
||||
+ while (team_info.finished_threads < team_info.num_threads)
|
||||
+ SleepConditionVariableCS(&team_info.cond, &vcomp_section, INFINITE);
|
||||
+
|
||||
+ LeaveCriticalSection(&vcomp_section);
|
||||
+ assert(list_empty(&thread_info.entry));
|
||||
+ }
|
||||
+
|
||||
+ __ms_va_end(team_info.valist);
|
||||
}
|
||||
|
||||
#if defined(__i386__)
|
||||
@@ -208,8 +398,19 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
|
||||
{
|
||||
case DLL_WINE_PREATTACH:
|
||||
return FALSE; /* prefer native version */
|
||||
+
|
||||
case DLL_PROCESS_ATTACH:
|
||||
+ vcomp_module = hinstDLL;
|
||||
DisableThreadLibraryCalls(hinstDLL);
|
||||
+ if ((vcomp_context_tls = TlsAlloc()) == TLS_OUT_OF_INDEXES)
|
||||
+ {
|
||||
+ ERR("Failed to allocate TLS index\n");
|
||||
+ return FALSE;
|
||||
+ }
|
||||
+ break;
|
||||
+
|
||||
+ case DLL_PROCESS_DETACH:
|
||||
+ TlsFree(vcomp_context_tls);
|
||||
break;
|
||||
}
|
||||
|
||||
--
|
||||
2.4.5
|
||||
|
@ -0,0 +1,259 @@
|
||||
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
|
||||
|
@ -0,0 +1,65 @@
|
||||
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
|
||||
|
@ -1,230 +0,0 @@
|
||||
From 92cd559115925b61b980a784efacb0ccdd7029d0 Mon Sep 17 00:00:00 2001
|
||||
From: Dan Kegel <dank@kegel.com>
|
||||
Date: Sat, 11 Jul 2015 03:56:04 +0200
|
||||
Subject: vcomp/tests: Add initial tests for _vcomp_fork.
|
||||
|
||||
---
|
||||
configure.ac | 3 +-
|
||||
dlls/vcomp/tests/Makefile.in | 7 +++
|
||||
dlls/vcomp/tests/vcomp.c | 122 ++++++++++++++++++++++++++++++++++++++++
|
||||
dlls/vcomp/tests/vcomp.manifest | 21 +++++++
|
||||
dlls/vcomp/tests/vcomp.rc | 22 ++++++++
|
||||
5 files changed, 174 insertions(+), 1 deletion(-)
|
||||
create mode 100644 dlls/vcomp/tests/Makefile.in
|
||||
create mode 100644 dlls/vcomp/tests/vcomp.c
|
||||
create mode 100644 dlls/vcomp/tests/vcomp.manifest
|
||||
create mode 100644 dlls/vcomp/tests/vcomp.rc
|
||||
|
||||
diff --git a/configure.ac b/configure.ac
|
||||
index 3eaec29..a36fc4b 100644
|
||||
--- a/configure.ac
|
||||
+++ b/configure.ac
|
||||
@@ -3321,7 +3321,8 @@ WINE_CONFIG_DLL(uxtheme,,[implib])
|
||||
WINE_CONFIG_TEST(dlls/uxtheme/tests)
|
||||
WINE_CONFIG_DLL(vbscript,,[clean])
|
||||
WINE_CONFIG_TEST(dlls/vbscript/tests,[clean])
|
||||
-WINE_CONFIG_DLL(vcomp)
|
||||
+WINE_CONFIG_DLL(vcomp,,[implib])
|
||||
+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..08a5b7f
|
||||
--- /dev/null
|
||||
+++ b/dlls/vcomp/tests/Makefile.in
|
||||
@@ -0,0 +1,7 @@
|
||||
+TESTDLL = vcomp.dll
|
||||
+
|
||||
+C_SRCS = \
|
||||
+ vcomp.c
|
||||
+
|
||||
+RC_SRCS = \
|
||||
+ vcomp.rc
|
||||
diff --git a/dlls/vcomp/tests/vcomp.c b/dlls/vcomp/tests/vcomp.c
|
||||
new file mode 100644
|
||||
index 0000000..5c6a861
|
||||
--- /dev/null
|
||||
+++ b/dlls/vcomp/tests/vcomp.c
|
||||
@@ -0,0 +1,122 @@
|
||||
+/*
|
||||
+ * Unit test suite for vcomp fork/join implementation
|
||||
+ *
|
||||
+ * 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
|
||||
+ * 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 const int is_win64 = (sizeof(void *) > sizeof(int));
|
||||
+
|
||||
+static HMODULE hvcomp = 0;
|
||||
+static void (WINAPIV *p_vcomp_fork)(BOOL ifval, int nargs, void *wrapper, ...);
|
||||
+static int (CDECL *pomp_get_max_threads)(void);
|
||||
+
|
||||
+#define VCOMP_GET_PROC(func) \
|
||||
+ do \
|
||||
+ { \
|
||||
+ p ## func = (void *)GetProcAddress(hvcomp, #func); \
|
||||
+ if (!p ## func) trace("Failed to get address for %s\n", #func); \
|
||||
+ } \
|
||||
+ while (0)
|
||||
+
|
||||
+static BOOL init_vcomp(void)
|
||||
+{
|
||||
+ hvcomp = LoadLibraryA("vcomp.dll");
|
||||
+ if (!hvcomp)
|
||||
+ {
|
||||
+ win_skip("vcomp.dll not installed\n");
|
||||
+ return FALSE;
|
||||
+ }
|
||||
+
|
||||
+ VCOMP_GET_PROC(_vcomp_fork);
|
||||
+ VCOMP_GET_PROC(omp_get_max_threads);
|
||||
+
|
||||
+ return TRUE;
|
||||
+}
|
||||
+
|
||||
+#undef VCOMP_GET_PROC
|
||||
+
|
||||
+static void CDECL _test_vcomp_fork_ptr(LONG *a, LONG *b, LONG *c, LONG *d, LONG *e)
|
||||
+{
|
||||
+ InterlockedIncrement(a);
|
||||
+ InterlockedIncrement(b);
|
||||
+ InterlockedIncrement(c);
|
||||
+ InterlockedIncrement(d);
|
||||
+ InterlockedIncrement(e);
|
||||
+}
|
||||
+
|
||||
+static void CDECL _test_vcomp_fork_uintptr(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 _test_vcomp_fork_float(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 n = pomp_get_max_threads();
|
||||
+
|
||||
+ a = 0; b = 1; c = 2; d = 3; e = 4;
|
||||
+ p_vcomp_fork(FALSE, 5, _test_vcomp_fork_ptr, &a, &b, &c, &d, &e);
|
||||
+ ok(a == 1, "expected a = 1, got %u\n", a);
|
||||
+ ok(b == 2, "expected b = 2, got %u\n", b);
|
||||
+ ok(c == 3, "expected c = 3, got %u\n", c);
|
||||
+ ok(d == 4, "expected d = 4, got %u\n", d);
|
||||
+ ok(e == 5, "expected e = 5, got %u\n", e);
|
||||
+
|
||||
+ a = 0; b = 1; c = 2; d = 3; e = 4;
|
||||
+ p_vcomp_fork(TRUE, 5, _test_vcomp_fork_ptr, &a, &b, &c, &d, &e);
|
||||
+ ok(a > 0 && a <= (n + 0), "expected a > 0 && a <= (n + 0), got %u\n", a);
|
||||
+ ok(b > 1 && b <= (n + 1), "expected b > 1 && b <= (n + 1), got %u\n", b);
|
||||
+ ok(c > 2 && c <= (n + 2), "expected c > 2 && c <= (n + 2), got %u\n", c);
|
||||
+ ok(d > 3 && d <= (n + 3), "expected d > 3 && d <= (n + 3), got %u\n", d);
|
||||
+ ok(e > 4 && e <= (n + 4), "expected e > 4 && e <= (n + 4), got %u\n", e);
|
||||
+
|
||||
+ p_vcomp_fork(TRUE, 5, _test_vcomp_fork_uintptr, (UINT_PTR)1, (UINT_PTR)(MAXUINT_PTR - 2),
|
||||
+ (UINT_PTR)3, (UINT_PTR)(MAXUINT_PTR - 4), (UINT_PTR)5);
|
||||
+
|
||||
+ if (is_win64)
|
||||
+ 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, _test_vcomp_fork_float, 1.5f, 2.5f, 3.5f, 4.5f, 5.5f);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+START_TEST(vcomp)
|
||||
+{
|
||||
+ if (!init_vcomp())
|
||||
+ return;
|
||||
+
|
||||
+ test_vcomp_fork();
|
||||
+
|
||||
+ FreeLibrary(hvcomp);
|
||||
+}
|
||||
diff --git a/dlls/vcomp/tests/vcomp.manifest b/dlls/vcomp/tests/vcomp.manifest
|
||||
new file mode 100644
|
||||
index 0000000..6c8bd91
|
||||
--- /dev/null
|
||||
+++ b/dlls/vcomp/tests/vcomp.manifest
|
||||
@@ -0,0 +1,21 @@
|
||||
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||
+<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
|
||||
+ <assemblyIdentity
|
||||
+ type="win32"
|
||||
+ name="Wine.vcomp.Test"
|
||||
+ version="1.0.0.0"
|
||||
+ processorArchitecture="*"
|
||||
+ />
|
||||
+<description>Wine vcomp test suite</description>
|
||||
+<dependency>
|
||||
+ <dependentAssembly>
|
||||
+ <assemblyIdentity
|
||||
+ type="win32"
|
||||
+ name="Microsoft.VC80.OpenMP"
|
||||
+ version="8.0.50608.0"
|
||||
+ processorArchitecture="*"
|
||||
+ publicKeyToken="1fc8b3b9a1e18e3b"
|
||||
+ />
|
||||
+ </dependentAssembly>
|
||||
+</dependency>
|
||||
+</assembly>
|
||||
diff --git a/dlls/vcomp/tests/vcomp.rc b/dlls/vcomp/tests/vcomp.rc
|
||||
new file mode 100644
|
||||
index 0000000..c5f1d25
|
||||
--- /dev/null
|
||||
+++ b/dlls/vcomp/tests/vcomp.rc
|
||||
@@ -0,0 +1,22 @@
|
||||
+/*
|
||||
+ * Copyright (c) 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
|
||||
+ * 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 "winuser.h"
|
||||
+
|
||||
+/* @makedep: vcomp.manifest */
|
||||
+1 RT_MANIFEST vcomp.manifest
|
||||
--
|
||||
2.4.5
|
||||
|
338
patches/vcomp-Functions/0004-vcomp-tests-Add-initial-tests.patch
Normal file
338
patches/vcomp-Functions/0004-vcomp-tests-Add-initial-tests.patch
Normal file
@ -0,0 +1,338 @@
|
||||
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
|
||||
|
@ -0,0 +1,107 @@
|
||||
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
|
||||
|
@ -1,4 +1,4 @@
|
||||
From f455eb53b0d527874fb95bdc652d1a31cd8fa93a Mon Sep 17 00:00:00 2001
|
||||
From 7b64b41a512320a89e7758db43343ebe99c0f563 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,25 +12,25 @@ 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 9de9721..400f93a 100644
|
||||
index bcaa4ea..fcbd747 100644
|
||||
--- a/dlls/vcomp/main.c
|
||||
+++ b/dlls/vcomp/main.c
|
||||
@@ -174,6 +174,96 @@ void CDECL _vcomp_single_end(void)
|
||||
@@ -301,6 +301,96 @@ void CDECL _vcomp_single_end(void)
|
||||
TRACE("stub\n");
|
||||
}
|
||||
|
||||
+void CDECL _vcomp_for_static_simple_init(unsigned int first, unsigned int last, int step, BOOL forward,
|
||||
+ unsigned int *begin, unsigned int *end)
|
||||
+{
|
||||
+ struct vcomp_thread_info *thread_info = vcomp_get_thread_info();
|
||||
+ struct vcomp_team_info *team_info = thread_info->team;
|
||||
+ struct vcomp_thread_data *thread_data = vcomp_init_thread_data();
|
||||
+ struct vcomp_team_data *team_data = thread_data->team;
|
||||
+ unsigned int iterations, per_thread, remaining;
|
||||
+ DWORD num_threads, thread_num;
|
||||
+
|
||||
+ TRACE("(%d, %d, %d, %d, %p, %p)\n", first, last, step, forward, begin, end);
|
||||
+
|
||||
+ num_threads = team_info->num_threads;
|
||||
+ thread_num = thread_info->thread_num;
|
||||
+ num_threads = team_data->num_threads;
|
||||
+ thread_num = thread_data->thread_num;
|
||||
+
|
||||
+ if (num_threads == 1)
|
||||
+ {
|
||||
@ -109,9 +109,9 @@ index 9de9721..400f93a 100644
|
||||
+ TRACE("()\n");
|
||||
+}
|
||||
+
|
||||
void CDECL _vcomp_fork_call_wrapper(void *wrapper, int nargs, __ms_va_list args);
|
||||
|
||||
static DWORD WINAPI _vcomp_fork_worker(void *param)
|
||||
{
|
||||
struct vcomp_thread_data *thread_data = param;
|
||||
diff --git a/dlls/vcomp/vcomp.spec b/dlls/vcomp/vcomp.spec
|
||||
index d446574..b14edca 100644
|
||||
--- a/dlls/vcomp/vcomp.spec
|
@ -1,49 +1,37 @@
|
||||
From af8411c2c51708c2edbc620b3d775bf5a08144f9 Mon Sep 17 00:00:00 2001
|
||||
From 656f0051550426759e8f6ab287391bbe6a168418 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.
|
||||
|
||||
---
|
||||
dlls/vcomp/tests/vcomp.c | 228 +++++++++++++++++++++++++++++++++++++++++++++++
|
||||
1 file changed, 228 insertions(+)
|
||||
dlls/vcomp/tests/vcomp.c | 220 +++++++++++++++++++++++++++++++++++++++++++++++
|
||||
1 file changed, 220 insertions(+)
|
||||
|
||||
diff --git a/dlls/vcomp/tests/vcomp.c b/dlls/vcomp/tests/vcomp.c
|
||||
index 5c6a861..1971b6d 100644
|
||||
index a9b975d..34c1ebc 100644
|
||||
--- a/dlls/vcomp/tests/vcomp.c
|
||||
+++ b/dlls/vcomp/tests/vcomp.c
|
||||
@@ -23,8 +23,15 @@
|
||||
static const int is_win64 = (sizeof(void *) > sizeof(int));
|
||||
@@ -32,6 +32,9 @@ static BOOL (WINAPI *pDeactivateActCtx)(DWORD, ULONG_PTR);
|
||||
static VOID (WINAPI *pReleaseActCtx)(HANDLE);
|
||||
|
||||
static HMODULE hvcomp = 0;
|
||||
+static void (CDECL *p_vcomp_barrier)(void);
|
||||
static void (CDECL *p_vcomp_barrier)(void);
|
||||
+static void (CDECL *p_vcomp_for_static_end)(void);
|
||||
+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);
|
||||
+static int (CDECL *pomp_get_num_threads)(void);
|
||||
+static int (CDECL *pomp_get_thread_num)(void);
|
||||
+static void (CDECL *pomp_set_num_threads)(int num_threads);
|
||||
|
||||
#define VCOMP_GET_PROC(func) \
|
||||
do \
|
||||
@@ -43,8 +50,14 @@ static BOOL init_vcomp(void)
|
||||
return FALSE;
|
||||
@@ -168,6 +171,8 @@ static BOOL init_vcomp(void)
|
||||
}
|
||||
|
||||
+ VCOMP_GET_PROC(_vcomp_barrier);
|
||||
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);
|
||||
+ VCOMP_GET_PROC(omp_get_num_threads);
|
||||
+ VCOMP_GET_PROC(omp_get_thread_num);
|
||||
+ VCOMP_GET_PROC(omp_set_num_threads);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
@@ -111,12 +124,227 @@ static void test_vcomp_fork(void)
|
||||
}
|
||||
@@ -342,6 +347,220 @@ static void test_vcomp_fork(void)
|
||||
pomp_set_num_threads(max_threads);
|
||||
}
|
||||
|
||||
+static void CDECL _test_vcomp_for_static_simple_init(void)
|
||||
@ -263,12 +251,13 @@ index 5c6a861..1971b6d 100644
|
||||
START_TEST(vcomp)
|
||||
{
|
||||
if (!init_vcomp())
|
||||
return;
|
||||
|
||||
@@ -350,6 +569,7 @@ START_TEST(vcomp)
|
||||
test_omp_get_num_threads(FALSE);
|
||||
test_omp_get_num_threads(TRUE);
|
||||
test_vcomp_fork();
|
||||
+ test_vcomp_for_static_simple_init();
|
||||
|
||||
FreeLibrary(hvcomp);
|
||||
release_vcomp();
|
||||
}
|
||||
--
|
||||
2.4.5
|
@ -1,66 +0,0 @@
|
||||
From 8732b345bcab27edc68eda1ab35095d72a817899 Mon Sep 17 00:00:00 2001
|
||||
From: Sebastian Lackner <sebastian@fds-team.de>
|
||||
Date: Sat, 11 Jul 2015 19:38:24 +0200
|
||||
Subject: vcomp: Implement _vcomp_barrier.
|
||||
|
||||
---
|
||||
dlls/vcomp/main.c | 29 ++++++++++++++++++++++++++++-
|
||||
1 file changed, 28 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/dlls/vcomp/main.c b/dlls/vcomp/main.c
|
||||
index 2eeea3b..4f3471a 100644
|
||||
--- a/dlls/vcomp/main.c
|
||||
+++ b/dlls/vcomp/main.c
|
||||
@@ -68,6 +68,10 @@ struct vcomp_team_info
|
||||
unsigned int nargs;
|
||||
void *wrapper;
|
||||
__ms_va_list valist;
|
||||
+
|
||||
+ /* barrier */
|
||||
+ DWORD barrier;
|
||||
+ DWORD barrier_count;
|
||||
};
|
||||
|
||||
static inline struct vcomp_thread_info *vcomp_get_thread_info(void)
|
||||
@@ -154,7 +158,28 @@ void CDECL omp_set_num_threads(int num_threads)
|
||||
|
||||
void CDECL _vcomp_barrier(void)
|
||||
{
|
||||
- TRACE("stub\n");
|
||||
+ struct vcomp_team_info *team_info;
|
||||
+
|
||||
+ TRACE("()\n");
|
||||
+
|
||||
+ team_info = vcomp_get_team_info();
|
||||
+ EnterCriticalSection(&vcomp_section);
|
||||
+
|
||||
+ team_info->barrier_count++;
|
||||
+ if (team_info->barrier_count >= team_info->num_threads)
|
||||
+ {
|
||||
+ team_info->barrier++;
|
||||
+ team_info->barrier_count = 0;
|
||||
+ WakeAllConditionVariable(&team_info->cond);
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ DWORD barrier = team_info->barrier;
|
||||
+ while (team_info->barrier == barrier)
|
||||
+ SleepConditionVariableCS(&team_info->cond, &vcomp_section, INFINITE);
|
||||
+ }
|
||||
+
|
||||
+ LeaveCriticalSection(&vcomp_section);
|
||||
}
|
||||
|
||||
void CDECL _vcomp_set_num_threads(int num_threads)
|
||||
@@ -385,6 +410,8 @@ void WINAPIV _vcomp_fork(BOOL ifval, int nargs, void *wrapper, ...)
|
||||
team_info.nargs = nargs;
|
||||
team_info.wrapper = wrapper;
|
||||
__ms_va_start(team_info.valist, wrapper);
|
||||
+ team_info.barrier = 0;
|
||||
+ team_info.barrier_count = 0;
|
||||
|
||||
/* Initialize members of thread_info. */
|
||||
list_init(&thread_info.entry);
|
||||
--
|
||||
2.4.5
|
||||
|
@ -1,4 +1,4 @@
|
||||
From 721c89ed7aec4a9ae8f0a5f7b0efeee838c08985 Mon Sep 17 00:00:00 2001
|
||||
From ed0734ad10de657efb30ec7c851d20d20ba79a0a 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,26 +11,26 @@ 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 400f93a..2eeea3b 100644
|
||||
index fcbd747..b22dd37 100644
|
||||
--- a/dlls/vcomp/main.c
|
||||
+++ b/dlls/vcomp/main.c
|
||||
@@ -259,6 +259,68 @@ void CDECL _vcomp_for_static_simple_init(unsigned int first, unsigned int last,
|
||||
@@ -386,6 +386,68 @@ void CDECL _vcomp_for_static_simple_init(unsigned int first, unsigned int last,
|
||||
}
|
||||
}
|
||||
|
||||
+void CDECL _vcomp_for_static_init(int first, int last, int step, int chunksize, unsigned int *loops,
|
||||
+ int *begin, int *end, int *next, int *lastchunk)
|
||||
+{
|
||||
+ struct vcomp_thread_info *thread_info = vcomp_get_thread_info();
|
||||
+ struct vcomp_team_info *team_info = thread_info->team;
|
||||
+ struct vcomp_thread_data *thread_data = vcomp_get_thread_data();
|
||||
+ struct vcomp_team_data *team_data = thread_data->team;
|
||||
+ unsigned int iterations, num_chunks, per_thread, remaining;
|
||||
+ DWORD num_threads, thread_num;
|
||||
+
|
||||
+ TRACE("(%d, %d, %d, %d, %p, %p, %p, %p, %p)\n",
|
||||
+ first, last, step, chunksize, loops, begin, end, next, lastchunk);
|
||||
+
|
||||
+ num_threads = team_info->num_threads;
|
||||
+ thread_num = thread_info->thread_num;
|
||||
+ num_threads = team_data->num_threads;
|
||||
+ thread_num = thread_data->thread_num;
|
||||
+
|
||||
+ if (chunksize < 1)
|
||||
+ chunksize = 1;
|
@ -1,4 +1,4 @@
|
||||
From 9cea1ba140eb5d8ecd70eab4a68e309cd80fd454 Mon Sep 17 00:00:00 2001
|
||||
From 39cd9028667159d38193fca46691b7cdbc0fe82b 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,11 +8,11 @@ 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 1971b6d..96806fd 100644
|
||||
index 34c1ebc..0103af1 100644
|
||||
--- a/dlls/vcomp/tests/vcomp.c
|
||||
+++ b/dlls/vcomp/tests/vcomp.c
|
||||
@@ -25,6 +25,8 @@ static const int is_win64 = (sizeof(void *) > sizeof(int));
|
||||
static HMODULE hvcomp = 0;
|
||||
@@ -33,6 +33,8 @@ static VOID (WINAPI *pReleaseActCtx)(HANDLE);
|
||||
|
||||
static void (CDECL *p_vcomp_barrier)(void);
|
||||
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,
|
||||
@ -20,15 +20,15 @@ index 1971b6d..96806fd 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, ...);
|
||||
@@ -52,6 +54,7 @@ static BOOL init_vcomp(void)
|
||||
@@ -172,6 +174,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(omp_get_max_threads);
|
||||
@@ -338,6 +341,201 @@ static void test_vcomp_for_static_simple_init(void)
|
||||
VCOMP_GET_PROC(_vcomp_set_num_threads);
|
||||
@@ -561,6 +564,201 @@ static void test_vcomp_for_static_simple_init(void)
|
||||
}
|
||||
}
|
||||
|
||||
@ -230,13 +230,13 @@ index 1971b6d..96806fd 100644
|
||||
START_TEST(vcomp)
|
||||
{
|
||||
if (!init_vcomp())
|
||||
@@ -345,6 +543,7 @@ START_TEST(vcomp)
|
||||
|
||||
@@ -570,6 +768,7 @@ START_TEST(vcomp)
|
||||
test_omp_get_num_threads(TRUE);
|
||||
test_vcomp_fork();
|
||||
test_vcomp_for_static_simple_init();
|
||||
+ test_vcomp_for_static_init();
|
||||
|
||||
FreeLibrary(hvcomp);
|
||||
release_vcomp();
|
||||
}
|
||||
--
|
||||
2.4.5
|
@ -1,4 +1,4 @@
|
||||
From aad24232add010020898eaa1a0934cb353c123f2 Mon Sep 17 00:00:00 2001
|
||||
From d9ec7f94c0ecefeccf49f1d09bf458eb90472faf 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,22 +11,22 @@ 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 4f3471a..fccad93 100644
|
||||
index b22dd37..a9a49ce 100644
|
||||
--- a/dlls/vcomp/main.c
|
||||
+++ b/dlls/vcomp/main.c
|
||||
@@ -351,6 +351,12 @@ void CDECL _vcomp_for_static_end(void)
|
||||
@@ -453,6 +453,12 @@ void CDECL _vcomp_for_static_end(void)
|
||||
TRACE("()\n");
|
||||
}
|
||||
|
||||
+int CDECL omp_in_parallel(void)
|
||||
+{
|
||||
+ TRACE("()\n");
|
||||
+ return vcomp_get_team_info() != NULL;
|
||||
+ return vcomp_init_thread_data()->team != NULL;
|
||||
+}
|
||||
+
|
||||
void CDECL _vcomp_fork_call_wrapper(void *wrapper, int nargs, __ms_va_list args);
|
||||
|
||||
static DWORD WINAPI _vcomp_fork_worker(void *param)
|
||||
{
|
||||
struct vcomp_thread_data *thread_data = param;
|
||||
diff --git a/dlls/vcomp/vcomp.spec b/dlls/vcomp/vcomp.spec
|
||||
index 8bc66e8..156233f 100644
|
||||
--- a/dlls/vcomp/vcomp.spec
|
@ -1,4 +1,4 @@
|
||||
From 77d6daebca21cfb4209a8281abac2b9db0d7a1b4 Mon Sep 17 00:00:00 2001
|
||||
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
|
||||
@ -13,129 +13,127 @@ Subject: vcomp: Implement _vcomp_sections_init and _vcomp_sections_next and
|
||||
5 files changed, 104 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/dlls/vcomp/main.c b/dlls/vcomp/main.c
|
||||
index fccad93..db47ff6 100644
|
||||
index a9a49ce..31814d6 100644
|
||||
--- a/dlls/vcomp/main.c
|
||||
+++ b/dlls/vcomp/main.c
|
||||
@@ -56,6 +56,9 @@ struct vcomp_thread_info
|
||||
/* current task */
|
||||
struct vcomp_team_info *team;
|
||||
DWORD thread_num;
|
||||
@@ -58,6 +58,9 @@ struct vcomp_thread_data
|
||||
/* only used for concurrent tasks */
|
||||
struct list entry;
|
||||
CONDITION_VARIABLE cond;
|
||||
+
|
||||
+ /* section */
|
||||
+ DWORD section;
|
||||
+ unsigned int section;
|
||||
};
|
||||
|
||||
struct vcomp_team_info
|
||||
@@ -72,6 +75,11 @@ struct vcomp_team_info
|
||||
struct vcomp_team_data
|
||||
@@ -74,6 +77,11 @@ struct vcomp_team_data
|
||||
/* barrier */
|
||||
DWORD barrier;
|
||||
DWORD barrier_count;
|
||||
unsigned int barrier;
|
||||
int barrier_count;
|
||||
+
|
||||
+ /* section */
|
||||
+ DWORD section;
|
||||
+ DWORD num_sections;
|
||||
+ DWORD section_index;
|
||||
+ unsigned int section;
|
||||
+ unsigned int num_sections;
|
||||
+ unsigned int section_index;
|
||||
};
|
||||
|
||||
static inline struct vcomp_thread_info *vcomp_get_thread_info(void)
|
||||
@@ -357,6 +365,43 @@ int CDECL omp_in_parallel(void)
|
||||
return vcomp_get_team_info() != NULL;
|
||||
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_info *thread_info = vcomp_get_thread_info();
|
||||
+ struct vcomp_team_info *team_info = thread_info->team;
|
||||
+ 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_info->section++;
|
||||
+ if ((int)(thread_info->section - team_info->section) > 0)
|
||||
+ thread_data->section++;
|
||||
+ if ((int)(thread_data->section - team_data->section) > 0)
|
||||
+ {
|
||||
+ /* first thread in a new section */
|
||||
+ team_info->section = thread_info->section;
|
||||
+ team_info->num_sections = n;
|
||||
+ team_info->section_index = 0;
|
||||
+ 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_info *thread_info = vcomp_get_thread_info();
|
||||
+ struct vcomp_team_info *team_info = thread_info->team;
|
||||
+ 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_info->section == team_info->section &&
|
||||
+ team_info->section_index < team_info->num_sections)
|
||||
+ if (thread_data->section == team_data->section &&
|
||||
+ team_data->section_index < team_data->num_sections)
|
||||
+ {
|
||||
+ i = team_info->section_index++;
|
||||
+ i = team_data->section_index++;
|
||||
+ }
|
||||
+ LeaveCriticalSection(&vcomp_section);
|
||||
+ return i;
|
||||
+}
|
||||
+
|
||||
void CDECL _vcomp_fork_call_wrapper(void *wrapper, int nargs, __ms_va_list args);
|
||||
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;
|
||||
|
||||
static DWORD WINAPI _vcomp_fork_worker(void *param)
|
||||
@@ -418,12 +463,14 @@ void WINAPIV _vcomp_fork(BOOL ifval, int nargs, void *wrapper, ...)
|
||||
__ms_va_start(team_info.valist, wrapper);
|
||||
team_info.barrier = 0;
|
||||
team_info.barrier_count = 0;
|
||||
+ team_info.section = -1;
|
||||
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);
|
||||
|
||||
/* Initialize members of thread_info. */
|
||||
list_init(&thread_info.entry);
|
||||
InitializeConditionVariable(&thread_info.cond);
|
||||
thread_info.team = &team_info;
|
||||
thread_info.thread_num = 0;
|
||||
+ thread_info.section = 0;
|
||||
@@ -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);
|
||||
|
||||
if (parallel)
|
||||
{
|
||||
@@ -439,6 +486,7 @@ void WINAPIV _vcomp_fork(BOOL ifval, int nargs, void *wrapper, ...)
|
||||
list_add_tail(&thread_info.entry, &info->entry);
|
||||
info->team = &team_info;
|
||||
info->thread_num = team_info.num_threads++;
|
||||
+ info->section = 0;
|
||||
WakeAllConditionVariable(&info->cond);
|
||||
}
|
||||
|
||||
@@ -455,6 +503,7 @@ void WINAPIV _vcomp_fork(BOOL ifval, int nargs, void *wrapper, ...)
|
||||
InitializeConditionVariable(&info->cond);
|
||||
info->team = &team_info;
|
||||
info->thread_num = team_info.num_threads;
|
||||
+ info->section = 0;
|
||||
|
||||
thread = CreateThread(NULL, 0, _vcomp_fork_worker, info, 0, NULL);
|
||||
if (!thread)
|
||||
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 96806fd..902a836 100644
|
||||
index 0103af1..c962fe8 100644
|
||||
--- a/dlls/vcomp/tests/vcomp.c
|
||||
+++ b/dlls/vcomp/tests/vcomp.c
|
||||
@@ -30,6 +30,8 @@ static void (CDECL *p_vcomp_for_static_init)(int first, int last, int step, i
|
||||
@@ -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_num_threads)(void);
|
||||
static int (CDECL *pomp_get_thread_num)(void);
|
||||
@@ -57,6 +59,8 @@ static BOOL init_vcomp(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_num_threads);
|
||||
VCOMP_GET_PROC(omp_get_thread_num);
|
||||
@@ -536,6 +540,50 @@ static void test_vcomp_for_static_init(void)
|
||||
VCOMP_GET_PROC(omp_get_nested);
|
||||
@@ -759,6 +763,50 @@ static void test_vcomp_for_static_init(void)
|
||||
}
|
||||
}
|
||||
|
||||
@ -186,13 +184,13 @@ index 96806fd..902a836 100644
|
||||
START_TEST(vcomp)
|
||||
{
|
||||
if (!init_vcomp())
|
||||
@@ -544,6 +592,7 @@ START_TEST(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();
|
||||
|
||||
FreeLibrary(hvcomp);
|
||||
release_vcomp();
|
||||
}
|
||||
diff --git a/dlls/vcomp/vcomp.spec b/dlls/vcomp/vcomp.spec
|
||||
index 156233f..7083ce4 100644
|
@ -1,4 +1,4 @@
|
||||
From f29610acbf9ce393b772520f6041acce9d1aefd8 Mon Sep 17 00:00:00 2001
|
||||
From 145ddf41060e93e9f320d5d2e4347dd2c7b8a83f 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,23 +13,23 @@ 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 db47ff6..3a1e9ee 100644
|
||||
index 31814d6..174ce06 100644
|
||||
--- a/dlls/vcomp/main.c
|
||||
+++ b/dlls/vcomp/main.c
|
||||
@@ -59,6 +59,9 @@ struct vcomp_thread_info
|
||||
@@ -61,6 +61,9 @@ struct vcomp_thread_data
|
||||
|
||||
/* section */
|
||||
DWORD section;
|
||||
unsigned int section;
|
||||
+
|
||||
+ /* dynamic */
|
||||
+ DWORD dynamic;
|
||||
+ unsigned int dynamic;
|
||||
};
|
||||
|
||||
struct vcomp_team_info
|
||||
@@ -80,6 +83,15 @@ struct vcomp_team_info
|
||||
DWORD section;
|
||||
DWORD num_sections;
|
||||
DWORD section_index;
|
||||
struct vcomp_team_data
|
||||
@@ -82,6 +85,15 @@ struct vcomp_team_data
|
||||
unsigned int section;
|
||||
unsigned int num_sections;
|
||||
unsigned int section_index;
|
||||
+
|
||||
+ /* dynamic */
|
||||
+ DWORD dynamic;
|
||||
@ -41,23 +41,23 @@ index db47ff6..3a1e9ee 100644
|
||||
+ DWORD dynamic_min_chunksize;
|
||||
};
|
||||
|
||||
static inline struct vcomp_thread_info *vcomp_get_thread_info(void)
|
||||
@@ -402,6 +414,83 @@ int CDECL _vcomp_sections_next(void)
|
||||
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;
|
||||
}
|
||||
|
||||
+void CDECL _vcomp_for_dynamic_init(int flags, int first, int last, int step, int chunksize)
|
||||
+{
|
||||
+ struct vcomp_thread_info *thread_info = vcomp_get_thread_info();
|
||||
+ struct vcomp_team_info *team_info = thread_info->team;
|
||||
+ struct vcomp_thread_data *thread_data = vcomp_get_thread_data();
|
||||
+ struct vcomp_team_data *team_data = thread_data->team;
|
||||
+ unsigned int iterations;
|
||||
+ BOOL forward = (flags & 0x40) != 0;
|
||||
+
|
||||
+ TRACE("(%d, %d, %d, %d, %d)\n", flags, first, last, step, chunksize);
|
||||
+
|
||||
+ EnterCriticalSection(&vcomp_section);
|
||||
+ thread_info->dynamic++;
|
||||
+ if ((int)(thread_info->dynamic - team_info->dynamic) > 0)
|
||||
+ thread_data->dynamic++;
|
||||
+ if ((int)(thread_data->dynamic - team_data->dynamic) > 0)
|
||||
+ {
|
||||
+ /* first thread in a new for_dynamic */
|
||||
+
|
||||
@ -76,102 +76,100 @@ index db47ff6..3a1e9ee 100644
|
||||
+ iterations = 1 + (first64 - last) / step;
|
||||
+ }
|
||||
+
|
||||
+ team_info->dynamic = thread_info->dynamic;
|
||||
+ team_info->dynamic_forward = forward;
|
||||
+ team_info->dynamic_first = first;
|
||||
+ team_info->dynamic_iterations = iterations;
|
||||
+ team_info->dynamic_step = step;
|
||||
+ team_info->dynamic_chunksize = max(1, iterations / team_info->num_threads);
|
||||
+ team_info->dynamic_min_chunksize = max(1, chunksize);
|
||||
+ team_data->dynamic = thread_data->dynamic;
|
||||
+ team_data->dynamic_forward = forward;
|
||||
+ team_data->dynamic_first = first;
|
||||
+ team_data->dynamic_iterations = iterations;
|
||||
+ team_data->dynamic_step = step;
|
||||
+ team_data->dynamic_chunksize = max(1, iterations / team_data->num_threads);
|
||||
+ team_data->dynamic_min_chunksize = max(1, chunksize);
|
||||
+ }
|
||||
+ LeaveCriticalSection(&vcomp_section);
|
||||
+}
|
||||
+
|
||||
+int CDECL _vcomp_for_dynamic_next(int *begin, int *end)
|
||||
+{
|
||||
+ struct vcomp_thread_info *thread_info = vcomp_get_thread_info();
|
||||
+ struct vcomp_team_info *team_info = thread_info->team;
|
||||
+ struct vcomp_thread_data *thread_data = vcomp_get_thread_data();
|
||||
+ struct vcomp_team_data *team_data = thread_data->team;
|
||||
+ unsigned int iterations = 0;
|
||||
+
|
||||
+ TRACE("(%p, %p)\n", begin, end);
|
||||
+
|
||||
+ EnterCriticalSection(&vcomp_section);
|
||||
+ if (thread_info->dynamic == team_info->dynamic &&
|
||||
+ team_info->dynamic_iterations != 0)
|
||||
+ if (thread_data->dynamic == team_data->dynamic &&
|
||||
+ team_data->dynamic_iterations != 0)
|
||||
+ {
|
||||
+ iterations = min(team_info->dynamic_iterations, team_info->dynamic_chunksize);
|
||||
+ team_info->dynamic_iterations -= iterations;
|
||||
+ iterations = min(team_data->dynamic_iterations, team_data->dynamic_chunksize);
|
||||
+ team_data->dynamic_iterations -= iterations;
|
||||
+
|
||||
+ if (team_info->dynamic_forward)
|
||||
+ if (team_data->dynamic_forward)
|
||||
+ {
|
||||
+ *begin = team_info->dynamic_first;
|
||||
+ *end = team_info->dynamic_first + (iterations - 1) * team_info->dynamic_step;
|
||||
+ team_info->dynamic_first += iterations * team_info->dynamic_step;
|
||||
+ *begin = team_data->dynamic_first;
|
||||
+ *end = team_data->dynamic_first + (iterations - 1) * team_data->dynamic_step;
|
||||
+ team_data->dynamic_first += iterations * team_data->dynamic_step;
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ *begin = team_info->dynamic_first;
|
||||
+ *end = team_info->dynamic_first - (iterations - 1) * team_info->dynamic_step;
|
||||
+ team_info->dynamic_first -= iterations * team_info->dynamic_step;
|
||||
+ *begin = team_data->dynamic_first;
|
||||
+ *end = team_data->dynamic_first - (iterations - 1) * team_data->dynamic_step;
|
||||
+ team_data->dynamic_first -= iterations * team_data->dynamic_step;
|
||||
+ }
|
||||
+
|
||||
+ team_info->dynamic_chunksize =
|
||||
+ max((team_info->dynamic_chunksize * 3 + 2)/4, team_info->dynamic_min_chunksize);
|
||||
+ team_data->dynamic_chunksize =
|
||||
+ max((team_data->dynamic_chunksize * 3 + 2)/4, team_data->dynamic_min_chunksize);
|
||||
+ }
|
||||
+ LeaveCriticalSection(&vcomp_section);
|
||||
+
|
||||
+ return (iterations != 0);
|
||||
+}
|
||||
+
|
||||
void CDECL _vcomp_fork_call_wrapper(void *wrapper, int nargs, __ms_va_list args);
|
||||
int CDECL omp_in_parallel(void)
|
||||
{
|
||||
TRACE("()\n");
|
||||
@@ -572,11 +661,13 @@ void WINAPIV _vcomp_fork(BOOL ifval, int nargs, void *wrapper, ...)
|
||||
team_data.barrier = 0;
|
||||
team_data.barrier_count = 0;
|
||||
team_data.section = 0;
|
||||
+ team_data.dynamic = 0;
|
||||
|
||||
static DWORD WINAPI _vcomp_fork_worker(void *param)
|
||||
@@ -464,6 +553,7 @@ void WINAPIV _vcomp_fork(BOOL ifval, int nargs, void *wrapper, ...)
|
||||
team_info.barrier = 0;
|
||||
team_info.barrier_count = 0;
|
||||
team_info.section = -1;
|
||||
+ team_info.dynamic = -1;
|
||||
thread_data.team = &team_data;
|
||||
thread_data.thread_num = 0;
|
||||
thread_data.fork_threads = 0;
|
||||
thread_data.section = 1;
|
||||
+ thread_data.dynamic = 1;
|
||||
list_init(&thread_data.entry);
|
||||
InitializeConditionVariable(&thread_data.cond);
|
||||
|
||||
/* Initialize members of thread_info. */
|
||||
list_init(&thread_info.entry);
|
||||
@@ -471,6 +561,7 @@ void WINAPIV _vcomp_fork(BOOL ifval, int nargs, void *wrapper, ...)
|
||||
thread_info.team = &team_info;
|
||||
thread_info.thread_num = 0;
|
||||
thread_info.section = 0;
|
||||
+ thread_info.dynamic = 0;
|
||||
@@ -593,6 +684,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;
|
||||
+ data->dynamic = 1;
|
||||
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, ...)
|
||||
data->thread_num = team_data.num_threads;
|
||||
data->fork_threads = 0;
|
||||
data->section = 1;
|
||||
+ data->dynamic = 1;
|
||||
InitializeConditionVariable(&data->cond);
|
||||
|
||||
if (parallel)
|
||||
{
|
||||
@@ -487,6 +578,7 @@ void WINAPIV _vcomp_fork(BOOL ifval, int nargs, void *wrapper, ...)
|
||||
info->team = &team_info;
|
||||
info->thread_num = team_info.num_threads++;
|
||||
info->section = 0;
|
||||
+ info->dynamic = 0;
|
||||
WakeAllConditionVariable(&info->cond);
|
||||
}
|
||||
|
||||
@@ -504,6 +596,7 @@ void WINAPIV _vcomp_fork(BOOL ifval, int nargs, void *wrapper, ...)
|
||||
info->team = &team_info;
|
||||
info->thread_num = team_info.num_threads;
|
||||
info->section = 0;
|
||||
+ info->dynamic = 0;
|
||||
|
||||
thread = CreateThread(NULL, 0, _vcomp_fork_worker, info, 0, NULL);
|
||||
if (!thread)
|
||||
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 902a836..4273680 100644
|
||||
index c962fe8..af04cc9 100644
|
||||
--- a/dlls/vcomp/tests/vcomp.c
|
||||
+++ b/dlls/vcomp/tests/vcomp.c
|
||||
@@ -24,6 +24,8 @@ static const int is_win64 = (sizeof(void *) > sizeof(int));
|
||||
@@ -32,6 +32,8 @@ static BOOL (WINAPI *pDeactivateActCtx)(DWORD, ULONG_PTR);
|
||||
static VOID (WINAPI *pReleaseActCtx)(HANDLE);
|
||||
|
||||
static HMODULE hvcomp = 0;
|
||||
static void (CDECL *p_vcomp_barrier)(void);
|
||||
+static void (CDECL *p_vcomp_for_dynamic_init)(int flags, int first, int last, int step, int chunksize);
|
||||
+static int (CDECL *p_vcomp_for_dynamic_next)(int *begin, int *end);
|
||||
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);
|
||||
@@ -55,6 +57,8 @@ static BOOL init_vcomp(void)
|
||||
@@ -175,6 +177,8 @@ static BOOL init_vcomp(void)
|
||||
}
|
||||
|
||||
VCOMP_GET_PROC(_vcomp_barrier);
|
||||
@ -180,7 +178,7 @@ index 902a836..4273680 100644
|
||||
VCOMP_GET_PROC(_vcomp_for_static_end);
|
||||
VCOMP_GET_PROC(_vcomp_for_static_init);
|
||||
VCOMP_GET_PROC(_vcomp_for_static_simple_init);
|
||||
@@ -584,6 +588,54 @@ static void test_vcomp_sections_init(void)
|
||||
@@ -807,6 +811,54 @@ static void test_vcomp_sections_init(void)
|
||||
}
|
||||
}
|
||||
|
||||
@ -235,13 +233,13 @@ index 902a836..4273680 100644
|
||||
START_TEST(vcomp)
|
||||
{
|
||||
if (!init_vcomp())
|
||||
@@ -593,6 +645,7 @@ START_TEST(vcomp)
|
||||
@@ -818,6 +870,7 @@ START_TEST(vcomp)
|
||||
test_vcomp_for_static_simple_init();
|
||||
test_vcomp_for_static_init();
|
||||
test_vcomp_sections_init();
|
||||
+ test_vcomp_for_dynamic_init();
|
||||
|
||||
FreeLibrary(hvcomp);
|
||||
release_vcomp();
|
||||
}
|
||||
diff --git a/dlls/vcomp/vcomp.spec b/dlls/vcomp/vcomp.spec
|
||||
index 7083ce4..1b02a65 100644
|
Loading…
Reference in New Issue
Block a user