msvcp120: Add _Concurrent_queue_base_v4 tests.
Signed-off-by: Piotr Caban <piotr@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
411e3c51c0
commit
33ba5e296b
|
@ -24,6 +24,38 @@
|
|||
#include "wine/test.h"
|
||||
#include "winbase.h"
|
||||
|
||||
#define DEFINE_EXPECT(func) \
|
||||
static BOOL expect_ ## func = FALSE, called_ ## func = FALSE
|
||||
|
||||
#define SET_EXPECT(func) \
|
||||
do { \
|
||||
expect_ ## func = TRUE; \
|
||||
errno = 0xdeadbeef; \
|
||||
}while(0)
|
||||
|
||||
#define CHECK_EXPECT2(func) \
|
||||
do { \
|
||||
ok(expect_ ##func, "unexpected call " #func "\n"); \
|
||||
called_ ## func = TRUE; \
|
||||
}while(0)
|
||||
|
||||
#define CHECK_EXPECT(func) \
|
||||
do { \
|
||||
CHECK_EXPECT2(func); \
|
||||
expect_ ## func = FALSE; \
|
||||
}while(0)
|
||||
|
||||
#define CHECK_CALLED(func) \
|
||||
do { \
|
||||
ok(called_ ## func, "expected " #func "\n"); \
|
||||
expect_ ## func = called_ ## func = FALSE; \
|
||||
}while(0)
|
||||
|
||||
DEFINE_EXPECT(queue_char__Allocate_page);
|
||||
DEFINE_EXPECT(queue_char__Deallocate_page);
|
||||
DEFINE_EXPECT(queue_char__Copy_item);
|
||||
DEFINE_EXPECT(queue_char__Assign_and_destroy_item);
|
||||
|
||||
#undef __thiscall
|
||||
#ifdef __i386__
|
||||
#define __thiscall __stdcall
|
||||
|
@ -278,6 +310,29 @@ static BOOLEAN (WINAPI *pCreateSymbolicLinkA)(LPCSTR,LPCSTR,DWORD);
|
|||
|
||||
static size_t (__cdecl *p_vector_base_v4__Segment_index_of)(size_t);
|
||||
|
||||
typedef struct
|
||||
{
|
||||
const vtable_ptr *vtable;
|
||||
void *data;
|
||||
size_t alloc_count;
|
||||
size_t item_size;
|
||||
} queue_base_v4;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
struct _Page *_Next;
|
||||
size_t _Mask;
|
||||
char data[1];
|
||||
} _Page;
|
||||
|
||||
static queue_base_v4* (__thiscall *p_queue_base_v4_ctor)(queue_base_v4*, size_t);
|
||||
static void (__thiscall *p_queue_base_v4_dtor)(queue_base_v4*);
|
||||
static MSVCP_bool (__thiscall *p_queue_base_v4__Internal_empty)(queue_base_v4*);
|
||||
static size_t (__thiscall *p_queue_base_v4__Internal_size)(queue_base_v4*);
|
||||
static void (__thiscall *p_queue_base_v4__Internal_push)(queue_base_v4*, const void*);
|
||||
static MSVCP_bool (__thiscall *p_queue_base_v4__Internal_pop_if_present)(queue_base_v4*, void*);
|
||||
static void (__thiscall *p_queue_base_v4__Internal_finish_clear)(queue_base_v4*);
|
||||
|
||||
static HMODULE msvcp;
|
||||
#define SETNOFAIL(x,y) x = (void*)GetProcAddress(msvcp,y)
|
||||
#define SET(x,y) do { SETNOFAIL(x,y); ok(x != NULL, "Export '%s' not found\n", y); } while(0)
|
||||
|
@ -395,6 +450,20 @@ static BOOL init(void)
|
|||
"?_Mtx_unlock@threads@stdext@@YAXPEAX@Z");
|
||||
SET(p_vector_base_v4__Segment_index_of,
|
||||
"?_Segment_index_of@_Concurrent_vector_base_v4@details@Concurrency@@KA_K_K@Z");
|
||||
SET(p_queue_base_v4_ctor,
|
||||
"??0_Concurrent_queue_base_v4@details@Concurrency@@IEAA@_K@Z");
|
||||
SET(p_queue_base_v4_dtor,
|
||||
"??1_Concurrent_queue_base_v4@details@Concurrency@@MEAA@XZ");
|
||||
SET(p_queue_base_v4__Internal_empty,
|
||||
"?_Internal_empty@_Concurrent_queue_base_v4@details@Concurrency@@IEBA_NXZ");
|
||||
SET(p_queue_base_v4__Internal_size,
|
||||
"?_Internal_size@_Concurrent_queue_base_v4@details@Concurrency@@IEBA_KXZ");
|
||||
SET(p_queue_base_v4__Internal_push,
|
||||
"?_Internal_push@_Concurrent_queue_base_v4@details@Concurrency@@IEAAXPEBX@Z");
|
||||
SET(p_queue_base_v4__Internal_pop_if_present,
|
||||
"?_Internal_pop_if_present@_Concurrent_queue_base_v4@details@Concurrency@@IEAA_NPEAX@Z");
|
||||
SET(p_queue_base_v4__Internal_finish_clear,
|
||||
"?_Internal_finish_clear@_Concurrent_queue_base_v4@details@Concurrency@@IEAAXXZ");
|
||||
} else {
|
||||
SET(p_tr2_sys__File_size,
|
||||
"?_File_size@sys@tr2@std@@YA_KPBD@Z");
|
||||
|
@ -482,6 +551,20 @@ static BOOL init(void)
|
|||
"?_Launch@_Pad@std@@QAEXPAU_Thrd_imp_t@@@Z");
|
||||
SET(p__Pad__Release,
|
||||
"?_Release@_Pad@std@@QAEXXZ");
|
||||
SET(p_queue_base_v4_ctor,
|
||||
"??0_Concurrent_queue_base_v4@details@Concurrency@@IAE@I@Z");
|
||||
SET(p_queue_base_v4_dtor,
|
||||
"??1_Concurrent_queue_base_v4@details@Concurrency@@MAE@XZ");
|
||||
SET(p_queue_base_v4__Internal_empty,
|
||||
"?_Internal_empty@_Concurrent_queue_base_v4@details@Concurrency@@IBE_NXZ");
|
||||
SET(p_queue_base_v4__Internal_size,
|
||||
"?_Internal_size@_Concurrent_queue_base_v4@details@Concurrency@@IBEIXZ");
|
||||
SET(p_queue_base_v4__Internal_push,
|
||||
"?_Internal_push@_Concurrent_queue_base_v4@details@Concurrency@@IAEXPBX@Z");
|
||||
SET(p_queue_base_v4__Internal_pop_if_present,
|
||||
"?_Internal_pop_if_present@_Concurrent_queue_base_v4@details@Concurrency@@IAE_NPAX@Z");
|
||||
SET(p_queue_base_v4__Internal_finish_clear,
|
||||
"?_Internal_finish_clear@_Concurrent_queue_base_v4@details@Concurrency@@IAEXXZ");
|
||||
#else
|
||||
SET(p__Thrd_current,
|
||||
"_Thrd_current");
|
||||
|
@ -497,6 +580,20 @@ static BOOL init(void)
|
|||
"?_Launch@_Pad@std@@QAAXPAU_Thrd_imp_t@@@Z");
|
||||
SET(p__Pad__Release,
|
||||
"?_Release@_Pad@std@@QAAXXZ");
|
||||
SET(p_queue_base_v4_ctor,
|
||||
"??0_Concurrent_queue_base_v4@details@Concurrency@@IAA@I@Z");
|
||||
SET(p_queue_base_v4_dtor,
|
||||
"??1_Concurrent_queue_base_v4@details@Concurrency@@MAA@XZ");
|
||||
SET(p_queue_base_v4__Internal_empty,
|
||||
"?_Internal_empty@_Concurrent_queue_base_v4@details@Concurrency@@IBA_NXZ");
|
||||
SET(p_queue_base_v4__Internal_size,
|
||||
"?_Internal_size@_Concurrent_queue_base_v4@details@Concurrency@@IBAIXZ");
|
||||
SET(p_queue_base_v4__Internal_push,
|
||||
"?_Internal_push@_Concurrent_queue_base_v4@details@Concurrency@@IAAXPBX@Z");
|
||||
SET(p_queue_base_v4__Internal_pop_if_present,
|
||||
"?_Internal_pop_if_present@_Concurrent_queue_base_v4@details@Concurrency@@IAA_NPAX@Z");
|
||||
SET(p_queue_base_v4__Internal_finish_clear,
|
||||
"?_Internal_finish_clear@_Concurrent_queue_base_v4@details@Concurrency@@IAAXXZ");
|
||||
#endif
|
||||
}
|
||||
SET(p__Thrd_equal,
|
||||
|
@ -2148,6 +2245,169 @@ static void test_vector_base_v4__Segment_index_of(void)
|
|||
}
|
||||
}
|
||||
|
||||
static void __thiscall queue_char__Move_item(
|
||||
#ifndef __i386__
|
||||
queue_base_v4 *this,
|
||||
#endif
|
||||
_Page *dst, size_t idx, void *src)
|
||||
{
|
||||
ok(0, "unexpected call\n");
|
||||
memcpy(dst->data + idx, src, sizeof(char));
|
||||
}
|
||||
|
||||
static void __thiscall queue_char__Copy_item(
|
||||
#ifndef __i386__
|
||||
queue_base_v4 *this,
|
||||
#endif
|
||||
_Page *dst, size_t idx, const void *src)
|
||||
{
|
||||
CHECK_EXPECT(queue_char__Copy_item);
|
||||
memcpy(dst->data + idx, src, sizeof(char));
|
||||
}
|
||||
|
||||
static void __thiscall queue_char__Assign_and_destroy_item(
|
||||
#ifndef __i386__
|
||||
queue_base_v4 *this,
|
||||
#endif
|
||||
void *dst, _Page *src, size_t idx)
|
||||
{
|
||||
CHECK_EXPECT(queue_char__Assign_and_destroy_item);
|
||||
memcpy(dst, src->data + idx, sizeof(char));
|
||||
}
|
||||
|
||||
#ifndef __i386__
|
||||
static _Page* __thiscall queue_char__Allocate_page(queue_base_v4 *this)
|
||||
#else
|
||||
static _Page* __thiscall queue_char__Allocate_page(void)
|
||||
#endif
|
||||
{
|
||||
CHECK_EXPECT(queue_char__Allocate_page);
|
||||
return malloc(sizeof(_Page) + sizeof(char[256]));
|
||||
}
|
||||
|
||||
static void __thiscall queue_char__Deallocate_page(
|
||||
#ifndef __i386__
|
||||
queue_base_v4 *this,
|
||||
#endif
|
||||
_Page *page)
|
||||
{
|
||||
CHECK_EXPECT2(queue_char__Deallocate_page);
|
||||
free(page);
|
||||
}
|
||||
|
||||
static const void* queue_char_vtbl[] =
|
||||
{
|
||||
queue_char__Move_item,
|
||||
queue_char__Copy_item,
|
||||
queue_char__Assign_and_destroy_item,
|
||||
NULL, /* dtor */
|
||||
queue_char__Allocate_page,
|
||||
queue_char__Deallocate_page
|
||||
};
|
||||
|
||||
static void test_queue_base_v4(void)
|
||||
{
|
||||
queue_base_v4 queue;
|
||||
MSVCP_bool b;
|
||||
size_t size;
|
||||
int i;
|
||||
char c;
|
||||
|
||||
call_func2(p_queue_base_v4_ctor, &queue, 0);
|
||||
ok(queue.data != NULL, "queue.data = NULL\n");
|
||||
ok(queue.alloc_count == 32, "queue.alloc_count = %ld\n", (long)queue.alloc_count);
|
||||
ok(queue.item_size == 0, "queue.item_size = %ld\n", (long)queue.item_size);
|
||||
call_func1(p_queue_base_v4_dtor, &queue);
|
||||
|
||||
call_func2(p_queue_base_v4_ctor, &queue, 8);
|
||||
ok(queue.data != NULL, "queue.data = NULL\n");
|
||||
ok(queue.alloc_count == 32, "queue.alloc_count = %ld\n", (long)queue.alloc_count);
|
||||
ok(queue.item_size == 8, "queue.item_size = %ld\n", (long)queue.item_size);
|
||||
call_func1(p_queue_base_v4_dtor, &queue);
|
||||
|
||||
call_func2(p_queue_base_v4_ctor, &queue, 16);
|
||||
ok(queue.data != NULL, "queue.data = NULL\n");
|
||||
ok(queue.alloc_count == 16, "queue.alloc_count = %ld\n", (long)queue.alloc_count);
|
||||
ok(queue.item_size == 16, "queue.item_size = %ld\n", (long)queue.item_size);
|
||||
b = (DWORD_PTR)call_func1(p_queue_base_v4__Internal_empty, &queue);
|
||||
ok(b, "queue is not empty\n");
|
||||
size = (size_t)call_func1(p_queue_base_v4__Internal_size, &queue);
|
||||
ok(!size, "size = %ld\n", (long)size);
|
||||
call_func1(p_queue_base_v4_dtor, &queue);
|
||||
|
||||
call_func2(p_queue_base_v4_ctor, &queue, 1);
|
||||
queue.vtable = (void*)&queue_char_vtbl;
|
||||
|
||||
for(i=0; i<8; i++) {
|
||||
SET_EXPECT(queue_char__Allocate_page);
|
||||
SET_EXPECT(queue_char__Copy_item);
|
||||
c = 'a'+i;
|
||||
call_func2(p_queue_base_v4__Internal_push, &queue, &c);
|
||||
CHECK_CALLED(queue_char__Allocate_page);
|
||||
CHECK_CALLED(queue_char__Copy_item);
|
||||
|
||||
b = (MSVCP_bool)(DWORD_PTR)call_func1(p_queue_base_v4__Internal_empty, &queue);
|
||||
ok(!b, "queue is empty\n");
|
||||
size = (size_t)call_func1(p_queue_base_v4__Internal_size, &queue);
|
||||
ok(size == i+1, "size = %ld, expected %ld\n", (long)size, (long)i);
|
||||
}
|
||||
|
||||
SET_EXPECT(queue_char__Copy_item);
|
||||
c = 'a'+i;
|
||||
call_func2(p_queue_base_v4__Internal_push, &queue, &c);
|
||||
CHECK_CALLED(queue_char__Copy_item);
|
||||
|
||||
for(i=0; i<9; i++) {
|
||||
SET_EXPECT(queue_char__Assign_and_destroy_item);
|
||||
b = (DWORD_PTR)call_func2(p_queue_base_v4__Internal_pop_if_present, &queue, &c);
|
||||
CHECK_CALLED(queue_char__Assign_and_destroy_item);
|
||||
ok(b, "pop returned false\n");
|
||||
ok(c == 'a'+i, "got '%c', expected '%c'\n", c, 'a'+i);
|
||||
}
|
||||
b = (DWORD_PTR)call_func2(p_queue_base_v4__Internal_pop_if_present, &queue, &c);
|
||||
ok(!b, "pop returned true\n");
|
||||
|
||||
for(i=0; i<247; i++) {
|
||||
SET_EXPECT(queue_char__Copy_item);
|
||||
c = 'a'+i;
|
||||
call_func2(p_queue_base_v4__Internal_push, &queue, &c);
|
||||
CHECK_CALLED(queue_char__Copy_item);
|
||||
|
||||
size = (size_t)call_func1(p_queue_base_v4__Internal_size, &queue);
|
||||
ok(size == i+1, "size = %ld, expected %ld\n", (long)size, (long)i);
|
||||
}
|
||||
|
||||
SET_EXPECT(queue_char__Allocate_page);
|
||||
SET_EXPECT(queue_char__Copy_item);
|
||||
c = 'a'+i;
|
||||
call_func2(p_queue_base_v4__Internal_push, &queue, &c);
|
||||
CHECK_CALLED(queue_char__Allocate_page);
|
||||
CHECK_CALLED(queue_char__Copy_item);
|
||||
|
||||
for(i=0; i<239; i++) {
|
||||
SET_EXPECT(queue_char__Assign_and_destroy_item);
|
||||
b = (DWORD_PTR)call_func2(p_queue_base_v4__Internal_pop_if_present, &queue, &c);
|
||||
CHECK_CALLED(queue_char__Assign_and_destroy_item);
|
||||
ok(b, "pop returned false\n");
|
||||
ok(c == (char)('a'+i), "got '%c', expected '%c'\n", c, 'a'+i);
|
||||
}
|
||||
|
||||
SET_EXPECT(queue_char__Assign_and_destroy_item);
|
||||
SET_EXPECT(queue_char__Deallocate_page);
|
||||
b = (DWORD_PTR)call_func2(p_queue_base_v4__Internal_pop_if_present, &queue, &c);
|
||||
CHECK_CALLED(queue_char__Assign_and_destroy_item);
|
||||
CHECK_CALLED(queue_char__Deallocate_page);
|
||||
ok(b, "pop returned false\n");
|
||||
ok(c == (char)('a'+i), "got '%c', expected '%c'\n", c, 'a'+i);
|
||||
|
||||
/* destructor does't clear the memory, _Internal_finish_clear needs to be called */
|
||||
SET_EXPECT(queue_char__Deallocate_page);
|
||||
call_func1(p_queue_base_v4__Internal_finish_clear, &queue);
|
||||
CHECK_CALLED(queue_char__Deallocate_page);
|
||||
|
||||
call_func1(p_queue_base_v4_dtor, &queue);
|
||||
}
|
||||
|
||||
START_TEST(msvcp120)
|
||||
{
|
||||
if(!init()) return;
|
||||
|
@ -2182,6 +2442,7 @@ START_TEST(msvcp120)
|
|||
test_threads__Mtx();
|
||||
|
||||
test_vector_base_v4__Segment_index_of();
|
||||
test_queue_base_v4();
|
||||
|
||||
test_vbtable_size_exports();
|
||||
|
||||
|
|
Loading…
Reference in New Issue