From f212a137a6ae1eec774587a731c294448b75d532 Mon Sep 17 00:00:00 2001 From: Sebastian Lackner Date: Tue, 18 Aug 2015 06:56:17 +0200 Subject: [PATCH] vcomp: Implement OpenMP nested locking functions. The test marked with todo_wine suggests that native OpenMP might use a separate counter for the nesting level. However, to implement the owner checks required for regular locks we need to access the critical section private members anyway. --- dlls/vcomp/main.c | 18 ++++++++++++++++++ dlls/vcomp/tests/vcomp.c | 38 +++++++++++++++++++++++++++++++++++++ dlls/vcomp/vcomp.spec | 6 +++--- dlls/vcomp100/vcomp100.spec | 6 +++--- dlls/vcomp110/vcomp110.spec | 6 +++--- dlls/vcomp90/vcomp90.spec | 6 +++--- 6 files changed, 68 insertions(+), 12 deletions(-) diff --git a/dlls/vcomp/main.c b/dlls/vcomp/main.c index 81e3bc8b5a2..487d55ce51f 100644 --- a/dlls/vcomp/main.c +++ b/dlls/vcomp/main.c @@ -1057,6 +1057,24 @@ void CDECL omp_destroy_lock(omp_lock_t *lock) destroy_critsect(*lock); } +void CDECL omp_set_nest_lock(omp_nest_lock_t *lock) +{ + TRACE("(%p)\n", lock); + EnterCriticalSection(*lock); +} + +void CDECL omp_unset_nest_lock(omp_nest_lock_t *lock) +{ + TRACE("(%p)\n", lock); + LeaveCriticalSection(*lock); +} + +int CDECL omp_test_nest_lock(omp_nest_lock_t *lock) +{ + TRACE("(%p)\n", lock); + return TryEnterCriticalSection(*lock) ? (*lock)->RecursionCount : 0; +} + void CDECL _vcomp_enter_critsect(CRITICAL_SECTION **critsect) { TRACE("(%p)\n", critsect); diff --git a/dlls/vcomp/tests/vcomp.c b/dlls/vcomp/tests/vcomp.c index dd734fd6702..b06455406e4 100644 --- a/dlls/vcomp/tests/vcomp.c +++ b/dlls/vcomp/tests/vcomp.c @@ -82,8 +82,11 @@ static int (CDECL *pomp_get_thread_num)(void); static int (CDECL *pomp_in_parallel)(void); static void (CDECL *pomp_init_lock)(omp_lock_t *lock); static void (CDECL *pomp_init_nest_lock)(omp_nest_lock_t *lock); +static void (CDECL *pomp_set_nest_lock)(omp_nest_lock_t *lock); static void (CDECL *pomp_set_nested)(int nested); static void (CDECL *pomp_set_num_threads)(int num_threads); +static int (CDECL *pomp_test_nest_lock)(omp_nest_lock_t *lock); +static void (CDECL *pomp_unset_nest_lock)(omp_nest_lock_t *lock); #define VCOMP_DYNAMIC_FLAGS_STATIC 0x01 #define VCOMP_DYNAMIC_FLAGS_CHUNKED 0x02 @@ -265,8 +268,11 @@ static BOOL init_vcomp(void) VCOMP_GET_PROC(omp_in_parallel); VCOMP_GET_PROC(omp_init_lock); VCOMP_GET_PROC(omp_init_nest_lock); + VCOMP_GET_PROC(omp_set_nest_lock); VCOMP_GET_PROC(omp_set_nested); VCOMP_GET_PROC(omp_set_num_threads); + VCOMP_GET_PROC(omp_test_nest_lock); + VCOMP_GET_PROC(omp_unset_nest_lock); return TRUE; } @@ -1298,10 +1304,42 @@ static void test_vcomp_flush(void) static void test_omp_init_nest_lock(void) { + omp_nest_lock_t lock; + int ret; + ok(pomp_init_nest_lock == pomp_init_lock, "expected omp_init_nest_lock == %p, got %p\n", pomp_init_lock, pomp_init_nest_lock); ok(pomp_destroy_nest_lock == pomp_destroy_lock, "expected omp_destroy_nest_lock == %p, got %p\n", pomp_destroy_lock, pomp_destroy_nest_lock); + + pomp_init_nest_lock(&lock); + + /* test omp_set_nest_lock */ + pomp_set_nest_lock(&lock); + pomp_set_nest_lock(&lock); + pomp_unset_nest_lock(&lock); + pomp_unset_nest_lock(&lock); + + /* test omp_test_nest_lock */ + ret = pomp_test_nest_lock(&lock); + ok(ret == 1, "expected ret == 1, got %d\n", ret); + ret = pomp_test_nest_lock(&lock); + ok(ret == 2, "expected ret == 2, got %d\n", ret); + ret = pomp_test_nest_lock(&lock); + ok(ret == 3, "expected ret == 3, got %d\n", ret); + pomp_unset_nest_lock(&lock); + pomp_unset_nest_lock(&lock); + pomp_unset_nest_lock(&lock); + + /* test with EnterCriticalSection */ + EnterCriticalSection(lock); + ret = pomp_test_nest_lock(&lock); + todo_wine + ok(ret == 1, "expected ret == 1, got %d\n", ret); + pomp_unset_nest_lock(&lock); + LeaveCriticalSection(lock); + + pomp_destroy_nest_lock(&lock); } static void test_atomic_integer32(void) diff --git a/dlls/vcomp/vcomp.spec b/dlls/vcomp/vcomp.spec index 418d1763294..4c89879fc89 100644 --- a/dlls/vcomp/vcomp.spec +++ b/dlls/vcomp/vcomp.spec @@ -103,10 +103,10 @@ @ cdecl omp_init_nest_lock(ptr) omp_init_lock @ cdecl omp_set_dynamic(long) @ stub omp_set_lock -@ stub omp_set_nest_lock +@ cdecl omp_set_nest_lock(ptr) @ cdecl omp_set_nested(long) @ cdecl omp_set_num_threads(long) @ stub omp_test_lock -@ stub omp_test_nest_lock +@ cdecl omp_test_nest_lock(ptr) @ stub omp_unset_lock -@ stub omp_unset_nest_lock +@ cdecl omp_unset_nest_lock(ptr) diff --git a/dlls/vcomp100/vcomp100.spec b/dlls/vcomp100/vcomp100.spec index 8a26b151e36..9021b10efe2 100644 --- a/dlls/vcomp100/vcomp100.spec +++ b/dlls/vcomp100/vcomp100.spec @@ -103,10 +103,10 @@ @ cdecl omp_init_nest_lock(ptr) vcomp.omp_init_nest_lock @ cdecl omp_set_dynamic(long) vcomp.omp_set_dynamic @ stub omp_set_lock -@ stub omp_set_nest_lock +@ cdecl omp_set_nest_lock(ptr) vcomp.omp_set_nest_lock @ cdecl omp_set_nested(long) vcomp.omp_set_nested @ cdecl omp_set_num_threads(long) vcomp.omp_set_num_threads @ stub omp_test_lock -@ stub omp_test_nest_lock +@ cdecl omp_test_nest_lock(ptr) vcomp.omp_test_nest_lock @ stub omp_unset_lock -@ stub omp_unset_nest_lock +@ cdecl omp_unset_nest_lock(ptr) vcomp.omp_unset_nest_lock diff --git a/dlls/vcomp110/vcomp110.spec b/dlls/vcomp110/vcomp110.spec index 64a401629c6..4f7503f7ccf 100644 --- a/dlls/vcomp110/vcomp110.spec +++ b/dlls/vcomp110/vcomp110.spec @@ -104,10 +104,10 @@ @ cdecl omp_init_nest_lock(ptr) vcomp.omp_init_nest_lock @ cdecl omp_set_dynamic(long) vcomp.omp_set_dynamic @ stub omp_set_lock -@ stub omp_set_nest_lock +@ cdecl omp_set_nest_lock(ptr) vcomp.omp_set_nest_lock @ cdecl omp_set_nested(long) vcomp.omp_set_nested @ cdecl omp_set_num_threads(long) vcomp.omp_set_num_threads @ stub omp_test_lock -@ stub omp_test_nest_lock +@ cdecl omp_test_nest_lock(ptr) vcomp.omp_test_nest_lock @ stub omp_unset_lock -@ stub omp_unset_nest_lock +@ cdecl omp_unset_nest_lock(ptr) vcomp.omp_unset_nest_lock diff --git a/dlls/vcomp90/vcomp90.spec b/dlls/vcomp90/vcomp90.spec index 8a26b151e36..9021b10efe2 100644 --- a/dlls/vcomp90/vcomp90.spec +++ b/dlls/vcomp90/vcomp90.spec @@ -103,10 +103,10 @@ @ cdecl omp_init_nest_lock(ptr) vcomp.omp_init_nest_lock @ cdecl omp_set_dynamic(long) vcomp.omp_set_dynamic @ stub omp_set_lock -@ stub omp_set_nest_lock +@ cdecl omp_set_nest_lock(ptr) vcomp.omp_set_nest_lock @ cdecl omp_set_nested(long) vcomp.omp_set_nested @ cdecl omp_set_num_threads(long) vcomp.omp_set_num_threads @ stub omp_test_lock -@ stub omp_test_nest_lock +@ cdecl omp_test_nest_lock(ptr) vcomp.omp_test_nest_lock @ stub omp_unset_lock -@ stub omp_unset_nest_lock +@ cdecl omp_unset_nest_lock(ptr) vcomp.omp_unset_nest_lock