mfplat: Read queue subscriber within the critical section.
[wine/zf.git] / dlls / msvcp120 / tests / msvcp120.c
blob35e90cfa29c93faeac04ec687e3c450014c51c17
1 /*
2 * Copyright 2014 Yifu Wang for ESRI
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19 #include <locale.h>
20 #include <stdio.h>
21 #include <math.h>
22 #include <limits.h>
24 #include "wine/test.h"
25 #include "winbase.h"
27 DWORD expect_idx;
28 static int vector_alloc_count;
29 static int vector_elem_count;
30 typedef struct blocks_to_free{
31 size_t first_block;
32 void *blocks[sizeof(void*)*8];
33 int size_check;
34 }compact_block;
36 #define DEFINE_EXPECT(func) \
37 BOOL expect_ ## func, called_ ## func
39 struct expect_struct {
40 DEFINE_EXPECT(queue_char__Allocate_page);
41 DEFINE_EXPECT(queue_char__Deallocate_page);
42 DEFINE_EXPECT(queue_char__Move_item);
43 DEFINE_EXPECT(queue_char__Copy_item);
44 DEFINE_EXPECT(queue_char__Assign_and_destroy_item);
45 DEFINE_EXPECT(concurrent_vector_int_alloc);
46 DEFINE_EXPECT(concurrent_vector_int_destroy);
47 DEFINE_EXPECT(concurrent_vector_int_copy);
48 DEFINE_EXPECT(concurrent_vector_int_assign);
51 #define SET_EXPECT(func) \
52 do { \
53 struct expect_struct *p = TlsGetValue(expect_idx); \
54 ok(p != NULL, "expect_struct not initialized\n"); \
55 p->expect_ ## func = TRUE; \
56 }while(0)
58 #define CHECK_EXPECT2(func) \
59 do { \
60 struct expect_struct *p = TlsGetValue(expect_idx); \
61 ok(p != NULL, "expect_struct not initialized\n"); \
62 ok(p->expect_ ##func, "unexpected call " #func "\n"); \
63 p->called_ ## func = TRUE; \
64 }while(0)
66 #define CHECK_EXPECT(func) \
67 do { \
68 struct expect_struct *p = TlsGetValue(expect_idx); \
69 ok(p != NULL, "expect_struct not initialized\n"); \
70 CHECK_EXPECT2(func); \
71 p->expect_ ## func = FALSE; \
72 }while(0)
74 #define CHECK_CALLED(func) \
75 do { \
76 struct expect_struct *p = TlsGetValue(expect_idx); \
77 ok(p != NULL, "expect_struct not initialized\n"); \
78 ok(p->called_ ## func, "expected " #func "\n"); \
79 p->expect_ ## func = p->called_ ## func = FALSE; \
80 }while(0)
82 static void alloc_expect_struct(void)
84 struct expect_struct *p = malloc(sizeof(*p));
85 memset(p, 0, sizeof(*p));
86 ok(TlsSetValue(expect_idx, p), "TlsSetValue failed\n");
89 static void free_expect_struct(void)
91 struct expect_struct *p = TlsGetValue(expect_idx);
92 ok(TlsSetValue(expect_idx, NULL), "TlsSetValue failed\n");
93 free(p);
96 #undef __thiscall
97 #ifdef __i386__
98 #define __thiscall __stdcall
99 #else
100 #define __thiscall __cdecl
101 #endif
103 /* Emulate a __thiscall */
104 #ifdef __i386__
106 #include "pshpack1.h"
107 struct thiscall_thunk
109 BYTE pop_eax; /* popl %eax (ret addr) */
110 BYTE pop_edx; /* popl %edx (func) */
111 BYTE pop_ecx; /* popl %ecx (this) */
112 BYTE push_eax; /* pushl %eax */
113 WORD jmp_edx; /* jmp *%edx */
115 #include "poppack.h"
117 static void * (WINAPI *call_thiscall_func1)( void *func, void *this );
118 static void * (WINAPI *call_thiscall_func2)( void *func, void *this, void *a );
119 static void * (WINAPI *call_thiscall_func3)( void *func, void *this, void *a, void *b );
120 static void * (WINAPI *call_thiscall_func4)( void *func, void *this, void *a, void *b, void *c );
121 static void * (WINAPI *call_thiscall_func5)( void *func, void *this, void *a, void *b, void *c, void *d );
122 static void * (WINAPI *call_thiscall_func6)( void *func, void *this, void *a, void *b, void *c, void *d, void *e );
123 static void * (WINAPI *call_thiscall_func7)( void *func, void *this, void *a, void *b, void *c, void *d, void *e, void *f );
125 static void init_thiscall_thunk(void)
127 struct thiscall_thunk *thunk = VirtualAlloc( NULL, sizeof(*thunk),
128 MEM_COMMIT, PAGE_EXECUTE_READWRITE );
129 thunk->pop_eax = 0x58; /* popl %eax */
130 thunk->pop_edx = 0x5a; /* popl %edx */
131 thunk->pop_ecx = 0x59; /* popl %ecx */
132 thunk->push_eax = 0x50; /* pushl %eax */
133 thunk->jmp_edx = 0xe2ff; /* jmp *%edx */
134 call_thiscall_func1 = (void *)thunk;
135 call_thiscall_func2 = (void *)thunk;
136 call_thiscall_func3 = (void *)thunk;
137 call_thiscall_func4 = (void *)thunk;
138 call_thiscall_func5 = (void *)thunk;
139 call_thiscall_func6 = (void *)thunk;
140 call_thiscall_func7 = (void *)thunk;
143 #define call_func1(func,_this) call_thiscall_func1(func,_this)
144 #define call_func2(func,_this,a) call_thiscall_func2(func,_this,(void*)(a))
145 #define call_func3(func,_this,a,b) call_thiscall_func3(func,_this,(void*)(a),(void*)(b))
146 #define call_func4(func,_this,a,b,c) call_thiscall_func4(func,_this,(void*)(a),(void*)(b),(void*)(c))
147 #define call_func5(func,_this,a,b,c,d) call_thiscall_func5(func,_this,(void*)(a),(void*)(b),(void*)(c),(void*)(d))
148 #define call_func6(func,_this,a,b,c,d,e) call_thiscall_func6(func,_this,(void*)(a),(void*)(b),(void*)(c),(void*)(d),(void*)(e))
149 #define call_func7(func,_this,a,b,c,d,e,f) call_thiscall_func7(func,_this,(void*)(a),(void*)(b),(void*)(c),(void*)(d),(void*)(e),(void*)(f))
150 #else
152 #define init_thiscall_thunk()
153 #define call_func1(func,_this) func(_this)
154 #define call_func2(func,_this,a) func(_this,a)
155 #define call_func3(func,_this,a,b) func(_this,a,b)
156 #define call_func4(func,_this,a,b,c) func(_this,a,b,c)
157 #define call_func5(func,_this,a,b,c,d) func(_this,a,b,c,d)
158 #define call_func6(func,_this,a,b,c,d,e) func(_this,a,b,c,d,e)
159 #define call_func7(func,_this,a,b,c,d,e,f) func(_this,a,b,c,d,e,f)
160 #endif /* __i386__ */
162 typedef int MSVCRT_long;
163 typedef unsigned char MSVCP_bool;
165 /* xtime */
166 typedef struct {
167 __time64_t sec;
168 MSVCRT_long nsec;
169 } xtime;
171 typedef struct {
172 unsigned page;
173 int mb_max;
174 int unk;
175 BYTE isleadbyte[32];
176 } _Cvtvec;
178 struct space_info {
179 ULONGLONG capacity;
180 ULONGLONG free;
181 ULONGLONG available;
184 enum file_type {
185 status_unknown, file_not_found, regular_file, directory_file,
186 symlink_file, block_file, character_file, fifo_file, socket_file,
187 type_unknown
190 static BOOL compare_float(float f, float g, unsigned int ulps)
192 int x = *(int *)&f;
193 int y = *(int *)&g;
195 if (x < 0)
196 x = INT_MIN - x;
197 if (y < 0)
198 y = INT_MIN - y;
200 if (abs(x - y) > ulps)
201 return FALSE;
203 return TRUE;
206 static char* (__cdecl *p_setlocale)(int, const char*);
207 static int (__cdecl *p__setmbcp)(int);
208 static int (__cdecl *p__ismbblead)(unsigned int);
210 static MSVCRT_long (__cdecl *p__Xtime_diff_to_millis2)(const xtime*, const xtime*);
211 static int (__cdecl *p_xtime_get)(xtime*, int);
212 static _Cvtvec* (__cdecl *p__Getcvt)(_Cvtvec*);
213 static void (CDECL *p__Call_once)(int *once, void (CDECL *func)(void));
214 static void (CDECL *p__Call_onceEx)(int *once, void (CDECL *func)(void*), void *argv);
215 static void (CDECL *p__Do_call)(void *this);
216 static short (__cdecl *p__Dtest)(double *d);
217 static short (__cdecl *p__Dscale)(double *d, int exp);
218 static short (__cdecl *p__FExp)(float *x, float y, int exp);
219 static const char* (__cdecl *p__Syserror_map)(int err);
221 /* filesystem */
222 static ULONGLONG(__cdecl *p_tr2_sys__File_size)(char const*);
223 static ULONGLONG(__cdecl *p_tr2_sys__File_size_wchar)(WCHAR const*);
224 static int (__cdecl *p_tr2_sys__Equivalent)(char const*, char const*);
225 static int (__cdecl *p_tr2_sys__Equivalent_wchar)(WCHAR const*, WCHAR const*);
226 static char* (__cdecl *p_tr2_sys__Current_get)(char *);
227 static WCHAR* (__cdecl *p_tr2_sys__Current_get_wchar)(WCHAR *);
228 static MSVCP_bool (__cdecl *p_tr2_sys__Current_set)(char const*);
229 static MSVCP_bool (__cdecl *p_tr2_sys__Current_set_wchar)(WCHAR const*);
230 static int (__cdecl *p_tr2_sys__Make_dir)(char const*);
231 static int (__cdecl *p_tr2_sys__Make_dir_wchar)(WCHAR const*);
232 static MSVCP_bool (__cdecl *p_tr2_sys__Remove_dir)(char const*);
233 static MSVCP_bool (__cdecl *p_tr2_sys__Remove_dir_wchar)(WCHAR const*);
234 static int (__cdecl *p_tr2_sys__Copy_file)(char const*, char const*, MSVCP_bool);
235 static int (__cdecl *p_tr2_sys__Copy_file_wchar)(WCHAR const*, WCHAR const*, MSVCP_bool);
236 static int (__cdecl *p_tr2_sys__Rename)(char const*, char const*);
237 static int (__cdecl *p_tr2_sys__Rename_wchar)(WCHAR const*, WCHAR const*);
238 static struct space_info* (__cdecl *p_tr2_sys__Statvfs)(struct space_info*, char const*);
239 static struct space_info* (__cdecl *p_tr2_sys__Statvfs_wchar)(struct space_info*, WCHAR const*);
240 static enum file_type (__cdecl *p_tr2_sys__Stat)(char const*, int *);
241 static enum file_type (__cdecl *p_tr2_sys__Stat_wchar)(WCHAR const*, int *);
242 static enum file_type (__cdecl *p_tr2_sys__Lstat)(char const*, int *);
243 static enum file_type (__cdecl *p_tr2_sys__Lstat_wchar)(WCHAR const*, int *);
244 static __int64 (__cdecl *p_tr2_sys__Last_write_time)(char const*);
245 static __int64 (__cdecl *p_tr2_sys__Last_write_time_wchar)(WCHAR const*);
246 static void (__cdecl *p_tr2_sys__Last_write_time_set)(char const*, __int64);
247 static void* (__cdecl *p_tr2_sys__Open_dir)(char*, char const*, int *, enum file_type*);
248 static char* (__cdecl *p_tr2_sys__Read_dir)(char*, void*, enum file_type*);
249 static void (__cdecl *p_tr2_sys__Close_dir)(void*);
250 static int (__cdecl *p_tr2_sys__Link)(char const*, char const*);
251 static int (__cdecl *p_tr2_sys__Symlink)(char const*, char const*);
252 static int (__cdecl *p_tr2_sys__Unlink)(char const*);
254 /* thrd */
255 typedef struct
257 HANDLE hnd;
258 DWORD id;
259 } _Thrd_t;
261 #define TIMEDELTA 250 /* 250 ms uncertainty allowed */
263 typedef int (__cdecl *_Thrd_start_t)(void*);
265 static int (__cdecl *p__Thrd_equal)(_Thrd_t, _Thrd_t);
266 static int (__cdecl *p__Thrd_lt)(_Thrd_t, _Thrd_t);
267 static void (__cdecl *p__Thrd_sleep)(const xtime*);
268 static _Thrd_t (__cdecl *p__Thrd_current)(void);
269 static int (__cdecl *p__Thrd_create)(_Thrd_t*, _Thrd_start_t, void*);
270 static int (__cdecl *p__Thrd_join)(_Thrd_t, int*);
271 static int (__cdecl *p__Thrd_detach)(_Thrd_t);
273 #ifdef __i386__
274 static ULONGLONG (__cdecl *p_i386_Thrd_current)(void);
275 static _Thrd_t __cdecl i386_Thrd_current(void)
277 union {
278 _Thrd_t thr;
279 ULONGLONG ull;
280 } r;
281 r.ull = p_i386_Thrd_current();
282 return r.thr;
284 #endif
286 /* mtx */
287 typedef struct cs_queue
289 struct cs_queue *next;
290 BOOL free;
291 int unknown;
292 } cs_queue;
294 typedef struct
296 ULONG_PTR unk_thread_id;
297 cs_queue unk_active;
298 void *unknown[2];
299 cs_queue *head;
300 void *tail;
301 } critical_section;
303 #define MTX_PLAIN 0x1
304 #define MTX_TRY 0x2
305 #define MTX_TIMED 0x4
306 #define MTX_RECURSIVE 0x100
307 typedef struct
309 DWORD flags;
310 critical_section cs;
311 DWORD thread_id;
312 DWORD count;
313 } *_Mtx_t;
315 static int (__cdecl *p__Mtx_init)(_Mtx_t*, int);
316 static void (__cdecl *p__Mtx_destroy)(_Mtx_t*);
317 static int (__cdecl *p__Mtx_lock)(_Mtx_t*);
318 static int (__cdecl *p__Mtx_unlock)(_Mtx_t*);
319 static int (__cdecl *p__Mtx_trylock)(_Mtx_t*);
321 /* cnd */
322 typedef void *_Cnd_t;
324 static int (__cdecl *p__Cnd_init)(_Cnd_t*);
325 static void (__cdecl *p__Cnd_destroy)(_Cnd_t*);
326 static int (__cdecl *p__Cnd_wait)(_Cnd_t*, _Mtx_t*);
327 static int (__cdecl *p__Cnd_timedwait)(_Cnd_t*, _Mtx_t*, const xtime*);
328 static int (__cdecl *p__Cnd_broadcast)(_Cnd_t*);
329 static int (__cdecl *p__Cnd_signal)(_Cnd_t*);
330 static void (__cdecl *p__Cnd_register_at_thread_exit)(_Cnd_t*, _Mtx_t*, int*);
331 static void (__cdecl *p__Cnd_unregister_at_thread_exit)(_Mtx_t*);
332 static void (__cdecl *p__Cnd_do_broadcast_at_thread_exit)(void);
334 /* _Pad */
335 typedef void (*vtable_ptr)(void);
337 typedef struct
339 const vtable_ptr *vtable;
340 _Cnd_t cnd;
341 _Mtx_t mtx;
342 MSVCP_bool launched;
343 } _Pad;
345 static _Pad* (__thiscall *p__Pad_ctor)(_Pad*);
346 static _Pad* (__thiscall *p__Pad_copy_ctor)(_Pad*, const _Pad*);
347 static void (__thiscall *p__Pad_dtor)(_Pad*);
348 static _Pad* (__thiscall *p__Pad_op_assign)(_Pad*, const _Pad*);
349 static void (__thiscall *p__Pad__Launch)(_Pad*, _Thrd_t*);
350 static void (__thiscall *p__Pad__Release)(_Pad*);
352 static void (__cdecl *p_threads__Mtx_new)(void **mtx);
353 static void (__cdecl *p_threads__Mtx_delete)(void *mtx);
354 static void (__cdecl *p_threads__Mtx_lock)(void *mtx);
355 static void (__cdecl *p_threads__Mtx_unlock)(void *mtx);
357 static BOOLEAN (WINAPI *pCreateSymbolicLinkA)(LPCSTR,LPCSTR,DWORD);
359 static size_t (__cdecl *p_vector_base_v4__Segment_index_of)(size_t);
361 typedef struct
363 const vtable_ptr *vtable;
364 void *data;
365 size_t alloc_count;
366 size_t item_size;
367 } queue_base_v4;
369 typedef struct
371 struct _Page *_Next;
372 size_t _Mask;
373 char data[1];
374 } _Page;
376 static queue_base_v4* (__thiscall *p_queue_base_v4_ctor)(queue_base_v4*, size_t);
377 static void (__thiscall *p_queue_base_v4_dtor)(queue_base_v4*);
378 static MSVCP_bool (__thiscall *p_queue_base_v4__Internal_empty)(queue_base_v4*);
379 static size_t (__thiscall *p_queue_base_v4__Internal_size)(queue_base_v4*);
380 static void (__thiscall *p_queue_base_v4__Internal_push)(queue_base_v4*, const void*);
381 static void (__thiscall *p_queue_base_v4__Internal_move_push)(queue_base_v4*, void*);
382 static MSVCP_bool (__thiscall *p_queue_base_v4__Internal_pop_if_present)(queue_base_v4*, void*);
383 static void (__thiscall *p_queue_base_v4__Internal_finish_clear)(queue_base_v4*);
385 typedef struct vector_base_v4
387 void* (__cdecl *allocator)(struct vector_base_v4*, size_t);
388 void *storage[3];
389 size_t first_block;
390 size_t early_size;
391 void **segment;
392 } vector_base_v4;
394 static void (__thiscall *p_vector_base_v4_dtor)(vector_base_v4*);
395 static size_t (__thiscall *p_vector_base_v4__Internal_capacity)(vector_base_v4*);
396 static void* (__thiscall *p_vector_base_v4__Internal_push_back)(
397 vector_base_v4*, size_t, size_t*);
398 static size_t (__thiscall *p_vector_base_v4__Internal_clear)(
399 vector_base_v4*, void (__cdecl*)(void*, size_t));
400 static void (__thiscall *p_vector_base_v4__Internal_copy)(
401 vector_base_v4*, vector_base_v4*, size_t, void (__cdecl*)(void*, const void*, size_t));
402 static void (__thiscall *p_vector_base_v4__Internal_assign)(
403 vector_base_v4*, vector_base_v4*, size_t, void (__cdecl*)(void*, size_t),
404 void (__cdecl*)(void*, const void*, size_t), void (__cdecl*)(void*, const void*, size_t));
405 static void (__thiscall *p_vector_base_v4__Internal_swap)(
406 vector_base_v4*, const vector_base_v4*);
407 static void* (__thiscall *p_vector_base_v4__Internal_compact)(
408 vector_base_v4*, size_t, void*, void (__cdecl*)(void*, size_t),
409 void (__cdecl*)(void*, const void*, size_t));
410 static size_t (__thiscall *p_vector_base_v4__Internal_grow_by)(
411 vector_base_v4*, size_t, size_t, void (__cdecl*)(void*, const void*, size_t), const void *);
412 static size_t (__thiscall *p_vector_base_v4__Internal_grow_to_at_least_with_result)(
413 vector_base_v4*, size_t, size_t, void (__cdecl*)(void*, const void*, size_t), const void *);
414 static void (__thiscall *p_vector_base_v4__Internal_reserve)(
415 vector_base_v4*, size_t, size_t, size_t);
416 static void (__thiscall *p_vector_base_v4__Internal_resize)(
417 vector_base_v4*, size_t, size_t, size_t, void (__cdecl*)(void*, size_t),
418 void (__cdecl *copy)(void*, const void*, size_t), const void*);
420 static HMODULE msvcp;
421 #define SETNOFAIL(x,y) x = (void*)GetProcAddress(msvcp,y)
422 #define SET(x,y) do { SETNOFAIL(x,y); ok(x != NULL, "Export '%s' not found\n", y); } while(0)
423 static BOOL init(void)
425 HANDLE hdll;
427 msvcp = LoadLibraryA("msvcp120.dll");
428 if(!msvcp)
430 win_skip("msvcp120.dll not installed\n");
431 return FALSE;
434 SET(p__Xtime_diff_to_millis2,
435 "_Xtime_diff_to_millis2");
436 SET(p_xtime_get,
437 "xtime_get");
438 SET(p__Getcvt,
439 "_Getcvt");
440 SET(p__Call_once,
441 "_Call_once");
442 SET(p__Call_onceEx,
443 "_Call_onceEx");
444 SET(p__Do_call,
445 "_Do_call");
446 SET(p__Dtest,
447 "_Dtest");
448 SET(p__Dscale,
449 "_Dscale");
450 SET(p__FExp,
451 "_FExp");
452 if(sizeof(void*) == 8) { /* 64-bit initialization */
453 SET(p_tr2_sys__File_size,
454 "?_File_size@sys@tr2@std@@YA_KPEBD@Z");
455 SET(p_tr2_sys__File_size_wchar,
456 "?_File_size@sys@tr2@std@@YA_KPEB_W@Z");
457 SET(p_tr2_sys__Equivalent,
458 "?_Equivalent@sys@tr2@std@@YAHPEBD0@Z");
459 SET(p_tr2_sys__Equivalent_wchar,
460 "?_Equivalent@sys@tr2@std@@YAHPEB_W0@Z");
461 SET(p_tr2_sys__Current_get,
462 "?_Current_get@sys@tr2@std@@YAPEADAEAY0BAE@D@Z");
463 SET(p_tr2_sys__Current_get_wchar,
464 "?_Current_get@sys@tr2@std@@YAPEA_WAEAY0BAE@_W@Z");
465 SET(p_tr2_sys__Current_set,
466 "?_Current_set@sys@tr2@std@@YA_NPEBD@Z");
467 SET(p_tr2_sys__Current_set_wchar,
468 "?_Current_set@sys@tr2@std@@YA_NPEB_W@Z");
469 SET(p_tr2_sys__Make_dir,
470 "?_Make_dir@sys@tr2@std@@YAHPEBD@Z");
471 SET(p_tr2_sys__Make_dir_wchar,
472 "?_Make_dir@sys@tr2@std@@YAHPEB_W@Z");
473 SET(p_tr2_sys__Remove_dir,
474 "?_Remove_dir@sys@tr2@std@@YA_NPEBD@Z");
475 SET(p_tr2_sys__Remove_dir_wchar,
476 "?_Remove_dir@sys@tr2@std@@YA_NPEB_W@Z");
477 SET(p_tr2_sys__Copy_file,
478 "?_Copy_file@sys@tr2@std@@YAHPEBD0_N@Z");
479 SET(p_tr2_sys__Copy_file_wchar,
480 "?_Copy_file@sys@tr2@std@@YAHPEB_W0_N@Z");
481 SET(p_tr2_sys__Rename,
482 "?_Rename@sys@tr2@std@@YAHPEBD0@Z");
483 SET(p_tr2_sys__Rename_wchar,
484 "?_Rename@sys@tr2@std@@YAHPEB_W0@Z");
485 SET(p_tr2_sys__Statvfs,
486 "?_Statvfs@sys@tr2@std@@YA?AUspace_info@123@PEBD@Z");
487 SET(p_tr2_sys__Statvfs_wchar,
488 "?_Statvfs@sys@tr2@std@@YA?AUspace_info@123@PEB_W@Z");
489 SET(p_tr2_sys__Stat,
490 "?_Stat@sys@tr2@std@@YA?AW4file_type@123@PEBDAEAH@Z");
491 SET(p_tr2_sys__Stat_wchar,
492 "?_Stat@sys@tr2@std@@YA?AW4file_type@123@PEB_WAEAH@Z");
493 SET(p_tr2_sys__Lstat,
494 "?_Lstat@sys@tr2@std@@YA?AW4file_type@123@PEBDAEAH@Z");
495 SET(p_tr2_sys__Lstat_wchar,
496 "?_Lstat@sys@tr2@std@@YA?AW4file_type@123@PEB_WAEAH@Z");
497 SET(p_tr2_sys__Last_write_time,
498 "?_Last_write_time@sys@tr2@std@@YA_JPEBD@Z");
499 SET(p_tr2_sys__Last_write_time_wchar,
500 "?_Last_write_time@sys@tr2@std@@YA_JPEB_W@Z");
501 SET(p_tr2_sys__Last_write_time_set,
502 "?_Last_write_time@sys@tr2@std@@YAXPEBD_J@Z");
503 SET(p_tr2_sys__Open_dir,
504 "?_Open_dir@sys@tr2@std@@YAPEAXAEAY0BAE@DPEBDAEAHAEAW4file_type@123@@Z");
505 SET(p_tr2_sys__Read_dir,
506 "?_Read_dir@sys@tr2@std@@YAPEADAEAY0BAE@DPEAXAEAW4file_type@123@@Z");
507 SET(p_tr2_sys__Close_dir,
508 "?_Close_dir@sys@tr2@std@@YAXPEAX@Z");
509 SET(p_tr2_sys__Link,
510 "?_Link@sys@tr2@std@@YAHPEBD0@Z");
511 SET(p_tr2_sys__Symlink,
512 "?_Symlink@sys@tr2@std@@YAHPEBD0@Z");
513 SET(p_tr2_sys__Unlink,
514 "?_Unlink@sys@tr2@std@@YAHPEBD@Z");
515 SET(p__Thrd_current,
516 "_Thrd_current");
517 SET(p__Pad_ctor,
518 "??0_Pad@std@@QEAA@XZ");
519 SET(p__Pad_copy_ctor,
520 "??0_Pad@std@@QEAA@AEBV01@@Z");
521 SET(p__Pad_dtor,
522 "??1_Pad@std@@QEAA@XZ");
523 SET(p__Pad_op_assign,
524 "??4_Pad@std@@QEAAAEAV01@AEBV01@@Z");
525 SET(p__Pad__Launch,
526 "?_Launch@_Pad@std@@QEAAXPEAU_Thrd_imp_t@@@Z");
527 SET(p__Pad__Release,
528 "?_Release@_Pad@std@@QEAAXXZ");
529 SET(p_threads__Mtx_new,
530 "?_Mtx_new@threads@stdext@@YAXAEAPEAX@Z");
531 SET(p_threads__Mtx_delete,
532 "?_Mtx_delete@threads@stdext@@YAXPEAX@Z");
533 SET(p_threads__Mtx_lock,
534 "?_Mtx_lock@threads@stdext@@YAXPEAX@Z");
535 SET(p_threads__Mtx_unlock,
536 "?_Mtx_unlock@threads@stdext@@YAXPEAX@Z");
537 SET(p_vector_base_v4__Segment_index_of,
538 "?_Segment_index_of@_Concurrent_vector_base_v4@details@Concurrency@@KA_K_K@Z");
539 SET(p_queue_base_v4_ctor,
540 "??0_Concurrent_queue_base_v4@details@Concurrency@@IEAA@_K@Z");
541 SET(p_queue_base_v4_dtor,
542 "??1_Concurrent_queue_base_v4@details@Concurrency@@MEAA@XZ");
543 SET(p_queue_base_v4__Internal_empty,
544 "?_Internal_empty@_Concurrent_queue_base_v4@details@Concurrency@@IEBA_NXZ");
545 SET(p_queue_base_v4__Internal_size,
546 "?_Internal_size@_Concurrent_queue_base_v4@details@Concurrency@@IEBA_KXZ");
547 SET(p_queue_base_v4__Internal_push,
548 "?_Internal_push@_Concurrent_queue_base_v4@details@Concurrency@@IEAAXPEBX@Z");
549 SET(p_queue_base_v4__Internal_move_push,
550 "?_Internal_move_push@_Concurrent_queue_base_v4@details@Concurrency@@IEAAXPEAX@Z");
551 SET(p_queue_base_v4__Internal_pop_if_present,
552 "?_Internal_pop_if_present@_Concurrent_queue_base_v4@details@Concurrency@@IEAA_NPEAX@Z");
553 SET(p_queue_base_v4__Internal_finish_clear,
554 "?_Internal_finish_clear@_Concurrent_queue_base_v4@details@Concurrency@@IEAAXXZ");
555 SET(p_vector_base_v4_dtor,
556 "??1_Concurrent_vector_base_v4@details@Concurrency@@IEAA@XZ");
557 SET(p_vector_base_v4__Internal_capacity,
558 "?_Internal_capacity@_Concurrent_vector_base_v4@details@Concurrency@@IEBA_KXZ");
559 SET(p_vector_base_v4__Internal_push_back,
560 "?_Internal_push_back@_Concurrent_vector_base_v4@details@Concurrency@@IEAAPEAX_KAEA_K@Z");
561 SET(p_vector_base_v4__Internal_clear,
562 "?_Internal_clear@_Concurrent_vector_base_v4@details@Concurrency@@IEAA_KP6AXPEAX_K@Z@Z");
563 SET(p_vector_base_v4__Internal_copy,
564 "?_Internal_copy@_Concurrent_vector_base_v4@details@Concurrency@@IEAAXAEBV123@_KP6AXPEAXPEBX1@Z@Z");
565 SET(p_vector_base_v4__Internal_assign,
566 "?_Internal_assign@_Concurrent_vector_base_v4@details@Concurrency@@IEAAXAEBV123@_KP6AXPEAX1@ZP6AX2PEBX1@Z5@Z");
567 SET(p_vector_base_v4__Internal_swap,
568 "?_Internal_swap@_Concurrent_vector_base_v4@details@Concurrency@@IEAAXAEAV123@@Z");
569 SET(p_vector_base_v4__Internal_compact,
570 "?_Internal_compact@_Concurrent_vector_base_v4@details@Concurrency@@IEAAPEAX_KPEAXP6AX10@ZP6AX1PEBX0@Z@Z");
571 SET(p_vector_base_v4__Internal_grow_by,
572 "?_Internal_grow_by@_Concurrent_vector_base_v4@details@Concurrency@@IEAA_K_K0P6AXPEAXPEBX0@Z2@Z");
573 SET(p_vector_base_v4__Internal_grow_to_at_least_with_result,
574 "?_Internal_grow_to_at_least_with_result@_Concurrent_vector_base_v4@details@Concurrency@@IEAA_K_K0P6AXPEAXPEBX0@Z2@Z");
575 SET(p_vector_base_v4__Internal_reserve,
576 "?_Internal_reserve@_Concurrent_vector_base_v4@details@Concurrency@@IEAAX_K00@Z");
577 SET(p_vector_base_v4__Internal_resize,
578 "?_Internal_resize@_Concurrent_vector_base_v4@details@Concurrency@@IEAAX_K00P6AXPEAX0@ZP6AX1PEBX0@Z3@Z");
579 SET(p__Syserror_map,
580 "?_Syserror_map@std@@YAPEBDH@Z");
581 } else {
582 SET(p_tr2_sys__File_size,
583 "?_File_size@sys@tr2@std@@YA_KPBD@Z");
584 SET(p_tr2_sys__File_size_wchar,
585 "?_File_size@sys@tr2@std@@YA_KPB_W@Z");
586 SET(p_tr2_sys__Equivalent,
587 "?_Equivalent@sys@tr2@std@@YAHPBD0@Z");
588 SET(p_tr2_sys__Equivalent_wchar,
589 "?_Equivalent@sys@tr2@std@@YAHPB_W0@Z");
590 SET(p_tr2_sys__Current_get,
591 "?_Current_get@sys@tr2@std@@YAPADAAY0BAE@D@Z");
592 SET(p_tr2_sys__Current_get_wchar,
593 "?_Current_get@sys@tr2@std@@YAPA_WAAY0BAE@_W@Z");
594 SET(p_tr2_sys__Current_set,
595 "?_Current_set@sys@tr2@std@@YA_NPBD@Z");
596 SET(p_tr2_sys__Current_set_wchar,
597 "?_Current_set@sys@tr2@std@@YA_NPB_W@Z");
598 SET(p_tr2_sys__Make_dir,
599 "?_Make_dir@sys@tr2@std@@YAHPBD@Z");
600 SET(p_tr2_sys__Make_dir_wchar,
601 "?_Make_dir@sys@tr2@std@@YAHPB_W@Z");
602 SET(p_tr2_sys__Remove_dir,
603 "?_Remove_dir@sys@tr2@std@@YA_NPBD@Z");
604 SET(p_tr2_sys__Remove_dir_wchar,
605 "?_Remove_dir@sys@tr2@std@@YA_NPB_W@Z");
606 SET(p_tr2_sys__Copy_file,
607 "?_Copy_file@sys@tr2@std@@YAHPBD0_N@Z");
608 SET(p_tr2_sys__Copy_file_wchar,
609 "?_Copy_file@sys@tr2@std@@YAHPB_W0_N@Z");
610 SET(p_tr2_sys__Rename,
611 "?_Rename@sys@tr2@std@@YAHPBD0@Z");
612 SET(p_tr2_sys__Rename_wchar,
613 "?_Rename@sys@tr2@std@@YAHPB_W0@Z");
614 SET(p_tr2_sys__Statvfs,
615 "?_Statvfs@sys@tr2@std@@YA?AUspace_info@123@PBD@Z");
616 SET(p_tr2_sys__Statvfs_wchar,
617 "?_Statvfs@sys@tr2@std@@YA?AUspace_info@123@PB_W@Z");
618 SET(p_tr2_sys__Stat,
619 "?_Stat@sys@tr2@std@@YA?AW4file_type@123@PBDAAH@Z");
620 SET(p_tr2_sys__Stat_wchar,
621 "?_Stat@sys@tr2@std@@YA?AW4file_type@123@PB_WAAH@Z");
622 SET(p_tr2_sys__Lstat,
623 "?_Lstat@sys@tr2@std@@YA?AW4file_type@123@PBDAAH@Z");
624 SET(p_tr2_sys__Lstat_wchar,
625 "?_Lstat@sys@tr2@std@@YA?AW4file_type@123@PB_WAAH@Z");
626 SET(p_tr2_sys__Last_write_time,
627 "?_Last_write_time@sys@tr2@std@@YA_JPBD@Z");
628 SET(p_tr2_sys__Last_write_time_wchar,
629 "?_Last_write_time@sys@tr2@std@@YA_JPB_W@Z");
630 SET(p_tr2_sys__Last_write_time_set,
631 "?_Last_write_time@sys@tr2@std@@YAXPBD_J@Z");
632 SET(p_tr2_sys__Open_dir,
633 "?_Open_dir@sys@tr2@std@@YAPAXAAY0BAE@DPBDAAHAAW4file_type@123@@Z");
634 SET(p_tr2_sys__Read_dir,
635 "?_Read_dir@sys@tr2@std@@YAPADAAY0BAE@DPAXAAW4file_type@123@@Z");
636 SET(p_tr2_sys__Close_dir,
637 "?_Close_dir@sys@tr2@std@@YAXPAX@Z");
638 SET(p_tr2_sys__Link,
639 "?_Link@sys@tr2@std@@YAHPBD0@Z");
640 SET(p_tr2_sys__Symlink,
641 "?_Symlink@sys@tr2@std@@YAHPBD0@Z");
642 SET(p_tr2_sys__Unlink,
643 "?_Unlink@sys@tr2@std@@YAHPBD@Z");
644 SET(p_threads__Mtx_new,
645 "?_Mtx_new@threads@stdext@@YAXAAPAX@Z");
646 SET(p_threads__Mtx_delete,
647 "?_Mtx_delete@threads@stdext@@YAXPAX@Z");
648 SET(p_threads__Mtx_lock,
649 "?_Mtx_lock@threads@stdext@@YAXPAX@Z");
650 SET(p_threads__Mtx_unlock,
651 "?_Mtx_unlock@threads@stdext@@YAXPAX@Z");
652 SET(p_vector_base_v4__Segment_index_of,
653 "?_Segment_index_of@_Concurrent_vector_base_v4@details@Concurrency@@KAII@Z");
654 SET(p__Syserror_map,
655 "?_Syserror_map@std@@YAPBDH@Z");
656 #ifdef __i386__
657 SET(p_i386_Thrd_current,
658 "_Thrd_current");
659 p__Thrd_current = i386_Thrd_current;
660 SET(p__Pad_ctor,
661 "??0_Pad@std@@QAE@XZ");
662 SET(p__Pad_copy_ctor,
663 "??0_Pad@std@@QAE@ABV01@@Z");
664 SET(p__Pad_dtor,
665 "??1_Pad@std@@QAE@XZ");
666 SET(p__Pad_op_assign,
667 "??4_Pad@std@@QAEAAV01@ABV01@@Z");
668 SET(p__Pad__Launch,
669 "?_Launch@_Pad@std@@QAEXPAU_Thrd_imp_t@@@Z");
670 SET(p__Pad__Release,
671 "?_Release@_Pad@std@@QAEXXZ");
672 SET(p_queue_base_v4_ctor,
673 "??0_Concurrent_queue_base_v4@details@Concurrency@@IAE@I@Z");
674 SET(p_queue_base_v4_dtor,
675 "??1_Concurrent_queue_base_v4@details@Concurrency@@MAE@XZ");
676 SET(p_queue_base_v4__Internal_empty,
677 "?_Internal_empty@_Concurrent_queue_base_v4@details@Concurrency@@IBE_NXZ");
678 SET(p_queue_base_v4__Internal_size,
679 "?_Internal_size@_Concurrent_queue_base_v4@details@Concurrency@@IBEIXZ");
680 SET(p_queue_base_v4__Internal_push,
681 "?_Internal_push@_Concurrent_queue_base_v4@details@Concurrency@@IAEXPBX@Z");
682 SET(p_queue_base_v4__Internal_move_push,
683 "?_Internal_move_push@_Concurrent_queue_base_v4@details@Concurrency@@IAEXPAX@Z");
684 SET(p_queue_base_v4__Internal_pop_if_present,
685 "?_Internal_pop_if_present@_Concurrent_queue_base_v4@details@Concurrency@@IAE_NPAX@Z");
686 SET(p_queue_base_v4__Internal_finish_clear,
687 "?_Internal_finish_clear@_Concurrent_queue_base_v4@details@Concurrency@@IAEXXZ");
688 SET(p_vector_base_v4_dtor,
689 "??1_Concurrent_vector_base_v4@details@Concurrency@@IAE@XZ");
690 SET(p_vector_base_v4__Internal_capacity,
691 "?_Internal_capacity@_Concurrent_vector_base_v4@details@Concurrency@@IBEIXZ");
692 SET(p_vector_base_v4__Internal_push_back,
693 "?_Internal_push_back@_Concurrent_vector_base_v4@details@Concurrency@@IAEPAXIAAI@Z");
694 SET(p_vector_base_v4__Internal_clear,
695 "?_Internal_clear@_Concurrent_vector_base_v4@details@Concurrency@@IAEIP6AXPAXI@Z@Z");
696 SET(p_vector_base_v4__Internal_copy,
697 "?_Internal_copy@_Concurrent_vector_base_v4@details@Concurrency@@IAEXABV123@IP6AXPAXPBXI@Z@Z");
698 SET(p_vector_base_v4__Internal_assign,
699 "?_Internal_assign@_Concurrent_vector_base_v4@details@Concurrency@@IAEXABV123@IP6AXPAXI@ZP6AX1PBXI@Z4@Z");
700 SET(p_vector_base_v4__Internal_swap,
701 "?_Internal_swap@_Concurrent_vector_base_v4@details@Concurrency@@IAEXAAV123@@Z");
702 SET(p_vector_base_v4__Internal_compact,
703 "?_Internal_compact@_Concurrent_vector_base_v4@details@Concurrency@@IAEPAXIPAXP6AX0I@ZP6AX0PBXI@Z@Z");
704 SET(p_vector_base_v4__Internal_grow_by,
705 "?_Internal_grow_by@_Concurrent_vector_base_v4@details@Concurrency@@IAEIIIP6AXPAXPBXI@Z1@Z");
706 SET(p_vector_base_v4__Internal_grow_to_at_least_with_result,
707 "?_Internal_grow_to_at_least_with_result@_Concurrent_vector_base_v4@details@Concurrency@@IAEIIIP6AXPAXPBXI@Z1@Z");
708 SET(p_vector_base_v4__Internal_reserve,
709 "?_Internal_reserve@_Concurrent_vector_base_v4@details@Concurrency@@IAEXIII@Z");
710 SET(p_vector_base_v4__Internal_resize,
711 "?_Internal_resize@_Concurrent_vector_base_v4@details@Concurrency@@IAEXIIIP6AXPAXI@ZP6AX0PBXI@Z2@Z");
712 #else
713 SET(p__Thrd_current,
714 "_Thrd_current");
715 SET(p__Pad_ctor,
716 "??0_Pad@std@@QAA@XZ");
717 SET(p__Pad_copy_ctor,
718 "??0_Pad@std@@QAA@ABV01@@Z");
719 SET(p__Pad_dtor,
720 "??1_Pad@std@@QAA@XZ");
721 SET(p__Pad_op_assign,
722 "??4_Pad@std@@QAAAAV01@ABV01@@Z");
723 SET(p__Pad__Launch,
724 "?_Launch@_Pad@std@@QAAXPAU_Thrd_imp_t@@@Z");
725 SET(p__Pad__Release,
726 "?_Release@_Pad@std@@QAAXXZ");
727 SET(p_queue_base_v4_ctor,
728 "??0_Concurrent_queue_base_v4@details@Concurrency@@IAA@I@Z");
729 SET(p_queue_base_v4_dtor,
730 "??1_Concurrent_queue_base_v4@details@Concurrency@@MAA@XZ");
731 SET(p_queue_base_v4__Internal_empty,
732 "?_Internal_empty@_Concurrent_queue_base_v4@details@Concurrency@@IBA_NXZ");
733 SET(p_queue_base_v4__Internal_size,
734 "?_Internal_size@_Concurrent_queue_base_v4@details@Concurrency@@IBAIXZ");
735 SET(p_queue_base_v4__Internal_push,
736 "?_Internal_push@_Concurrent_queue_base_v4@details@Concurrency@@IAAXPBX@Z");
737 SET(p_queue_base_v4__Internal_move_push,
738 "?_Internal_move_push@_Concurrent_queue_base_v4@details@Concurrency@@IAAXPAX@Z");
739 SET(p_queue_base_v4__Internal_pop_if_present,
740 "?_Internal_pop_if_present@_Concurrent_queue_base_v4@details@Concurrency@@IAA_NPAX@Z");
741 SET(p_queue_base_v4__Internal_finish_clear,
742 "?_Internal_finish_clear@_Concurrent_queue_base_v4@details@Concurrency@@IAAXXZ");
743 SET(p_vector_base_v4_dtor,
744 "??1_Concurrent_vector_base_v4@details@Concurrency@@IAA@XZ");
745 SET(p_vector_base_v4__Internal_capacity,
746 "?_Internal_capacity@_Concurrent_vector_base_v4@details@Concurrency@@IBAIXZ");
747 SET(p_vector_base_v4__Internal_push_back,
748 "?_Internal_push_back@_Concurrent_vector_base_v4@details@Concurrency@@IAAPAXIAAI@Z");
749 SET(p_vector_base_v4__Internal_clear,
750 "?_Internal_clear@_Concurrent_vector_base_v4@details@Concurrency@@IAAIP6AXPAXI@Z@Z");
751 SET(p_vector_base_v4__Internal_copy,
752 "?_Internal_copy@_Concurrent_vector_base_v4@details@Concurrency@@IAAXABV123@IP6AXPAXPBXI@Z@Z");
753 SET(p_vector_base_v4__Internal_assign,
754 "?_Internal_assign@_Concurrent_vector_base_v4@details@Concurrency@@IAAXABV123@IP6AXPAXI@ZP6AX1PBXI@Z4@Z");
755 SET(p_vector_base_v4__Internal_swap,
756 "?_Internal_swap@_Concurrent_vector_base_v4@details@Concurrency@@IAAXAAV123@@Z");
757 SET(p_vector_base_v4__Internal_compact,
758 "?_Internal_compact@_Concurrent_vector_base_v4@details@Concurrency@@IAAPAXIPAXP6AX0I@ZP6AX0PBXI@Z@Z");
759 SET(p_vector_base_v4__Internal_grow_by,
760 "?_Internal_grow_by@_Concurrent_vector_base_v4@details@Concurrency@@IAAIIIP6AXPAXPBXI@Z1@Z");
761 SET(p_vector_base_v4__Internal_grow_to_at_least_with_result,
762 "?_Internal_grow_to_at_least_with_result@_Concurrent_vector_base_v4@details@Concurrency@@IAAIIIP6AXPAXPBXI@Z1@Z");
763 SET(p_vector_base_v4__Internal_reserve,
764 "?_Internal_reserve@_Concurrent_vector_base_v4@details@Concurrency@@IAAXIII@Z");
765 SET(p_vector_base_v4__Internal_resize,
766 "?_Internal_resize@_Concurrent_vector_base_v4@details@Concurrency@@IAEXIIIP6AXPAXI@ZP6AX0PBXI@Z2@Z");
767 #endif
769 SET(p__Thrd_equal,
770 "_Thrd_equal");
771 SET(p__Thrd_lt,
772 "_Thrd_lt");
773 SET(p__Thrd_sleep,
774 "_Thrd_sleep");
775 SET(p__Thrd_create,
776 "_Thrd_create");
777 SET(p__Thrd_join,
778 "_Thrd_join");
779 SET(p__Thrd_detach,
780 "_Thrd_detach");
782 SET(p__Mtx_init,
783 "_Mtx_init");
784 SET(p__Mtx_destroy,
785 "_Mtx_destroy");
786 SET(p__Mtx_lock,
787 "_Mtx_lock");
788 SET(p__Mtx_unlock,
789 "_Mtx_unlock");
790 SET(p__Mtx_trylock,
791 "_Mtx_trylock");
793 SET(p__Cnd_init,
794 "_Cnd_init");
795 SET(p__Cnd_destroy,
796 "_Cnd_destroy");
797 SET(p__Cnd_wait,
798 "_Cnd_wait");
799 SET(p__Cnd_timedwait,
800 "_Cnd_timedwait");
801 SET(p__Cnd_broadcast,
802 "_Cnd_broadcast");
803 SET(p__Cnd_signal,
804 "_Cnd_signal");
805 SET(p__Cnd_register_at_thread_exit,
806 "_Cnd_register_at_thread_exit");
807 SET(p__Cnd_unregister_at_thread_exit,
808 "_Cnd_unregister_at_thread_exit");
809 SET(p__Cnd_do_broadcast_at_thread_exit,
810 "_Cnd_do_broadcast_at_thread_exit");
812 hdll = GetModuleHandleA("msvcr120.dll");
813 p_setlocale = (void*)GetProcAddress(hdll, "setlocale");
814 p__setmbcp = (void*)GetProcAddress(hdll, "_setmbcp");
815 p__ismbblead = (void*)GetProcAddress(hdll, "_ismbblead");
817 hdll = GetModuleHandleA("kernel32.dll");
818 pCreateSymbolicLinkA = (void*)GetProcAddress(hdll, "CreateSymbolicLinkA");
820 init_thiscall_thunk();
821 return TRUE;
824 static void test__Xtime_diff_to_millis2(void)
826 struct {
827 __time64_t sec_before;
828 MSVCRT_long nsec_before;
829 __time64_t sec_after;
830 MSVCRT_long nsec_after;
831 MSVCRT_long expect;
832 } tests[] = {
833 {1, 0, 2, 0, 1000},
834 {0, 1000000000, 0, 2000000000, 1000},
835 {1, 100000000, 2, 100000000, 1000},
836 {1, 100000000, 1, 200000000, 100},
837 {0, 0, 0, 1000000000, 1000},
838 {0, 0, 0, 1200000000, 1200},
839 {0, 0, 0, 1230000000, 1230},
840 {0, 0, 0, 1234000000, 1234},
841 {0, 0, 0, 1234100000, 1235},
842 {0, 0, 0, 1234900000, 1235},
843 {0, 0, 0, 1234010000, 1235},
844 {0, 0, 0, 1234090000, 1235},
845 {0, 0, 0, 1234000001, 1235},
846 {0, 0, 0, 1234000009, 1235},
847 {0, 0, -1, 0, 0},
848 {1, 0, 0, 0, 0},
849 {0, 1000000000, 0, 0, 0},
850 {0x7FFFFFFF / 1000, 0, 0, 0, 0},
851 {2147484, 0, 0, 0, 0}, /* ceil(0x80000000 / 1000) */
852 {2147485, 0, 0, 0, 0}, /* ceil(0x80000000 / 1000) + 1*/
853 {0, 0, 0x7FFFFFFF / 1000, 0, 2147483000},
854 {0, 0, 0x7FFFFFFF / 1000, 647000000, 0x7FFFFFFF}, /* max */
855 {0, 0, 0x7FFFFFFF / 1000, 647000001, -2147483648}, /* overflow. */
856 {0, 0, 2147484, 0, -2147483296}, /* ceil(0x80000000 / 1000), overflow*/
857 {0, 0, 0, -10000000, 0},
858 {0, 0, -1, -100000000, 0},
859 {-1, 0, 0, 0, 1000},
860 {0, -100000000, 0, 0, 100},
861 {-1, -100000000, 0, 0, 1100},
862 {0, 0, -1, 2000000000, 1000},
863 {0, 0, -2, 2000000000, 0},
864 {0, 0, -2, 2100000000, 100},
865 {0, 0, _I64_MAX / 1000, 0, -808}, /* Still fits in a signed 64 bit number */
866 {0, 0, _I64_MAX / 1000, 1000000000, 192}, /* Overflows a signed 64 bit number */
867 {0, 0, (((ULONGLONG)0x80000000 << 32) | 0x1000) / 1000, 1000000000, 4192}, /* 64 bit overflow */
868 {_I64_MAX - 2, 0, _I64_MAX, 0, 2000}, /* Not an overflow */
869 {_I64_MAX, 0, _I64_MAX - 2, 0, 0}, /* Not an overflow */
871 /* October 11th 2017, 12:34:59 UTC */
872 {1507725144, 983274000, 0, 0, 0},
873 {0, 0, 1507725144, 983274000, 191624088},
874 {1507725144, 983274000, 1507725145, 983274000, 1000},
875 {1507725145, 983274000, 1507725145, 983274000, 0},
877 int i;
878 MSVCRT_long ret;
879 xtime t1, t2;
881 for(i = 0; i < ARRAY_SIZE(tests); ++ i)
883 t1.sec = tests[i].sec_before;
884 t1.nsec = tests[i].nsec_before;
885 t2.sec = tests[i].sec_after;
886 t2.nsec = tests[i].nsec_after;
887 ret = p__Xtime_diff_to_millis2(&t2, &t1);
888 ok(ret == tests[i].expect,
889 "_Xtime_diff_to_millis2(): test: %d expect: %d, got: %d\n",
890 i, tests[i].expect, ret);
894 static void test_xtime_get(void)
896 static const MSVCRT_long tests[] = {1, 50, 100, 200, 500};
897 MSVCRT_long diff;
898 xtime before, after;
899 int i;
901 for(i = 0; i < ARRAY_SIZE(tests); i ++)
903 p_xtime_get(&before, 1);
904 Sleep(tests[i]);
905 p_xtime_get(&after, 1);
907 diff = p__Xtime_diff_to_millis2(&after, &before);
909 ok(diff >= tests[i],
910 "xtime_get() not functioning correctly, test: %d, expect: %d, got: %d\n",
911 i, tests[i], diff);
914 /* Test parameter and return value */
915 before.sec = 0xdeadbeef; before.nsec = 0xdeadbeef;
916 i = p_xtime_get(&before, 0);
917 ok(i == 0, "expect xtime_get() to return 0, got: %d\n", i);
918 ok(before.sec == 0xdeadbeef && before.nsec == 0xdeadbeef,
919 "xtime_get() shouldn't have modified the xtime struct with the given option\n");
921 before.sec = 0xdeadbeef; before.nsec = 0xdeadbeef;
922 i = p_xtime_get(&before, 1);
923 ok(i == 1, "expect xtime_get() to return 1, got: %d\n", i);
924 ok(before.sec != 0xdeadbeef && before.nsec != 0xdeadbeef,
925 "xtime_get() should have modified the xtime struct with the given option\n");
928 static void test__Getcvt(void)
930 _Cvtvec cvtvec;
931 int i;
933 p__Getcvt(&cvtvec);
934 ok(cvtvec.page == 0, "cvtvec.page = %d\n", cvtvec.page);
935 ok(cvtvec.mb_max == 1, "cvtvec.mb_max = %d\n", cvtvec.mb_max);
936 todo_wine ok(cvtvec.unk == 1, "cvtvec.unk = %d\n", cvtvec.unk);
937 for(i=0; i<32; i++)
938 ok(cvtvec.isleadbyte[i] == 0, "cvtvec.isleadbyte[%d] = %x\n", i, cvtvec.isleadbyte[i]);
940 if(!p_setlocale(LC_ALL, ".936")) {
941 win_skip("_Getcvt tests\n");
942 return;
944 p__Getcvt(&cvtvec);
945 ok(cvtvec.page == 936, "cvtvec.page = %d\n", cvtvec.page);
946 ok(cvtvec.mb_max == 2, "cvtvec.mb_max = %d\n", cvtvec.mb_max);
947 ok(cvtvec.unk == 0, "cvtvec.unk = %d\n", cvtvec.unk);
948 for(i=0; i<32; i++) {
949 BYTE b = 0;
950 int j;
952 for(j=0; j<8; j++)
953 b |= (p__ismbblead(i*8+j) ? 1 : 0) << j;
954 ok(cvtvec.isleadbyte[i] ==b, "cvtvec.isleadbyte[%d] = %x (%x)\n", i, cvtvec.isleadbyte[i], b);
957 p__setmbcp(936);
958 p__Getcvt(&cvtvec);
959 ok(cvtvec.page == 936, "cvtvec.page = %d\n", cvtvec.page);
960 ok(cvtvec.mb_max == 2, "cvtvec.mb_max = %d\n", cvtvec.mb_max);
961 ok(cvtvec.unk == 0, "cvtvec.unk = %d\n", cvtvec.unk);
962 for(i=0; i<32; i++) {
963 BYTE b = 0;
964 int j;
966 for(j=0; j<8; j++)
967 b |= (p__ismbblead(i*8+j) ? 1 : 0) << j;
968 ok(cvtvec.isleadbyte[i] ==b, "cvtvec.isleadbyte[%d] = %x (%x)\n", i, cvtvec.isleadbyte[i], b);
972 static int cnt;
973 static int once;
975 static void __cdecl call_once_func(void)
977 ok(!once, "once != 0\n");
978 cnt += 0x10000;
981 static void __cdecl call_once_ex_func(void *arg)
983 int *i = arg;
985 ok(!once, "once != 0\n");
986 (*i)++;
989 static DWORD WINAPI call_once_thread(void *arg)
991 p__Call_once(&once, call_once_func);
992 return 0;
995 static DWORD WINAPI call_once_ex_thread(void *arg)
997 p__Call_onceEx(&once, call_once_ex_func, &cnt);
998 return 0;
1001 static void test__Call_once(void)
1003 HANDLE h[4];
1004 int i;
1006 for(i=0; i<4; i++)
1007 h[i] = CreateThread(NULL, 0, call_once_thread, &once, 0, NULL);
1008 ok(WaitForMultipleObjects(4, h, TRUE, INFINITE) == WAIT_OBJECT_0,
1009 "error waiting for all threads to finish\n");
1010 ok(cnt == 0x10000, "cnt = %x\n", cnt);
1011 ok(once == 1, "once = %x\n", once);
1013 once = cnt = 0;
1014 for(i=0; i<4; i++)
1015 h[i] = CreateThread(NULL, 0, call_once_ex_thread, &once, 0, NULL);
1016 ok(WaitForMultipleObjects(4, h, TRUE, INFINITE) == WAIT_OBJECT_0,
1017 "error waiting for all threads to finish\n");
1018 ok(cnt == 1, "cnt = %x\n", cnt);
1019 ok(once == 1, "once = %x\n", once);
1022 static void **vtbl_func0;
1023 #ifdef __i386__
1024 /* TODO: this should be a __thiscall function */
1025 static void __stdcall thiscall_func(void)
1027 cnt = 1;
1029 #else
1030 static void __cdecl thiscall_func(void *this)
1032 ok(this == &vtbl_func0, "incorrect this value\n");
1033 cnt = 1;
1035 #endif
1037 static void test__Do_call(void)
1039 void *pfunc = thiscall_func;
1041 cnt = 0;
1042 vtbl_func0 = &pfunc;
1043 p__Do_call(&vtbl_func0);
1044 ok(cnt == 1, "func was not called\n");
1047 static void test__Dtest(void)
1049 double d;
1050 short ret;
1052 d = 0;
1053 ret = p__Dtest(&d);
1054 ok(ret == FP_ZERO, "_Dtest(0) returned %x\n", ret);
1056 d = 1;
1057 ret = p__Dtest(&d);
1058 ok(ret == FP_NORMAL, "_Dtest(1) returned %x\n", ret);
1060 d = -1;
1061 ret = p__Dtest(&d);
1062 ok(ret == FP_NORMAL, "_Dtest(-1) returned %x\n", ret);
1064 d = INFINITY;
1065 ret = p__Dtest(&d);
1066 ok(ret == FP_INFINITE, "_Dtest(INF) returned %x\n", ret);
1068 d = NAN;
1069 ret = p__Dtest(&d);
1070 ok(ret == FP_NAN, "_Dtest(NAN) returned %x\n", ret);
1073 static void test__Dscale(void)
1075 double d;
1076 short ret;
1078 d = 0;
1079 ret = p__Dscale(&d, 0);
1080 ok(d == 0, "d = %f\n", d);
1081 ok(ret == FP_ZERO, "ret = %x\n", ret);
1083 d = 0;
1084 ret = p__Dscale(&d, 1);
1085 ok(d == 0, "d = %f\n", d);
1086 ok(ret == FP_ZERO, "ret = %x\n", ret);
1088 d = 0;
1089 ret = p__Dscale(&d, -1);
1090 ok(d == 0, "d = %f\n", d);
1091 ok(ret == FP_ZERO, "ret = %x\n", ret);
1093 d = 1;
1094 ret = p__Dscale(&d, 0);
1095 ok(d == 1, "d = %f\n", d);
1096 ok(ret == FP_NORMAL, "ret = %x\n", ret);
1098 d = 1;
1099 ret = p__Dscale(&d, 1);
1100 ok(d == 2, "d = %f\n", d);
1101 ok(ret == FP_NORMAL, "ret = %x\n", ret);
1103 d = 1;
1104 ret = p__Dscale(&d, -1);
1105 ok(d == 0.5, "d = %f\n", d);
1106 ok(ret == FP_NORMAL, "ret = %x\n", ret);
1108 d = 1;
1109 ret = p__Dscale(&d, -99999);
1110 ok(d == 0, "d = %f\n", d);
1111 ok(ret == FP_ZERO, "ret = %x\n", ret);
1113 d = 1;
1114 ret = p__Dscale(&d, 999999);
1115 ok(d == INFINITY, "d = %f\n", d);
1116 ok(ret == FP_INFINITE, "ret = %x\n", ret);
1118 d = NAN;
1119 ret = p__Dscale(&d, 1);
1120 ok(ret == FP_NAN, "ret = %x\n", ret);
1123 static void test__FExp(void)
1125 float d;
1126 short ret;
1128 d = 0;
1129 ret = p__FExp(&d, 0, 0);
1130 ok(d == 0, "d = %f\n", d);
1131 ok(ret == FP_ZERO, "ret = %x\n", ret);
1133 d = 0;
1134 ret = p__FExp(&d, 1, 0);
1135 ok(d == 1.0, "d = %f\n", d);
1136 ok(ret == FP_NORMAL, "ret = %x\n", ret);
1138 d = 0;
1139 ret = p__FExp(&d, 1, 1);
1140 ok(d == 2.0, "d = %f\n", d);
1141 ok(ret == FP_NORMAL, "ret = %x\n", ret);
1143 d = 0;
1144 ret = p__FExp(&d, 1, 2);
1145 ok(d == 4.0, "d = %f\n", d);
1146 ok(ret == FP_NORMAL, "ret = %x\n", ret);
1148 d = 0;
1149 ret = p__FExp(&d, 10, 0);
1150 ok(d == 10.0, "d = %f\n", d);
1151 ok(ret == FP_NORMAL, "ret = %x\n", ret);
1153 d = 1;
1154 ret = p__FExp(&d, 0, 0);
1155 ok(d == 0, "d = %f\n", d);
1156 ok(ret == FP_ZERO, "ret = %x\n", ret);
1158 d = 1;
1159 ret = p__FExp(&d, 1, 0);
1160 ok(compare_float(d, 2.7182817, 4), "d = %f\n", d);
1161 ok(ret == FP_NORMAL, "ret = %x\n", ret);
1163 d = 9e20;
1164 ret = p__FExp(&d, 0, 0);
1165 ok(d == 0, "d = %f\n", d);
1166 ok(ret == FP_ZERO, "ret = %x\n", ret);
1168 d = 90;
1169 ret = p__FExp(&d, 1, 0);
1170 ok(ret == FP_INFINITE, "ret = %x\n", ret);
1172 d = 90;
1173 ret = p__FExp(&d, 1, -50);
1174 ok(compare_float(d, 1.0839359e+024, 4), "d = %g\n", d);
1175 ok(ret == FP_NORMAL, "ret = %x\n", ret);
1178 static void test__Syserror_map(void)
1180 const char *r;
1182 r = p__Syserror_map(0);
1183 ok(!r, "_Syserror_map(0) returned %p\n", r);
1186 static void test_tr2_sys__File_size(void)
1188 ULONGLONG val;
1189 HANDLE file;
1190 LARGE_INTEGER file_size;
1191 CreateDirectoryA("tr2_test_dir", NULL);
1193 file = CreateFileA("tr2_test_dir/f1", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
1194 ok(file != INVALID_HANDLE_VALUE, "create file failed: INVALID_HANDLE_VALUE\n");
1195 file_size.QuadPart = 7;
1196 ok(SetFilePointerEx(file, file_size, NULL, FILE_BEGIN), "SetFilePointerEx failed\n");
1197 ok(SetEndOfFile(file), "SetEndOfFile failed\n");
1198 CloseHandle(file);
1199 val = p_tr2_sys__File_size("tr2_test_dir/f1");
1200 ok(val == 7, "file_size is %s\n", wine_dbgstr_longlong(val));
1201 val = p_tr2_sys__File_size_wchar(L"tr2_test_dir/f1");
1202 ok(val == 7, "file_size is %s\n", wine_dbgstr_longlong(val));
1204 file = CreateFileA("tr2_test_dir/f2", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
1205 ok(file != INVALID_HANDLE_VALUE, "create file failed: INVALID_HANDLE_VALUE\n");
1206 CloseHandle(file);
1207 val = p_tr2_sys__File_size("tr2_test_dir/f2");
1208 ok(val == 0, "file_size is %s\n", wine_dbgstr_longlong(val));
1210 val = p_tr2_sys__File_size("tr2_test_dir");
1211 ok(val == 0, "file_size is %s\n", wine_dbgstr_longlong(val));
1213 errno = 0xdeadbeef;
1214 val = p_tr2_sys__File_size("tr2_test_dir/not_exists_file");
1215 ok(val == 0, "file_size is %s\n", wine_dbgstr_longlong(val));
1216 ok(errno == 0xdeadbeef, "errno = %d\n", errno);
1218 errno = 0xdeadbeef;
1219 val = p_tr2_sys__File_size(NULL);
1220 ok(val == 0, "file_size is %s\n", wine_dbgstr_longlong(val));
1221 ok(errno == 0xdeadbeef, "errno = %d\n", errno);
1223 ok(DeleteFileA("tr2_test_dir/f1"), "expect tr2_test_dir/f1 to exist\n");
1224 ok(DeleteFileA("tr2_test_dir/f2"), "expect tr2_test_dir/f2 to exist\n");
1225 ok(p_tr2_sys__Remove_dir("tr2_test_dir"), "expect tr2_test_dir to exist\n");
1228 static void test_tr2_sys__Equivalent(void)
1230 int val, i;
1231 HANDLE file;
1232 char temp_path[MAX_PATH], current_path[MAX_PATH];
1233 struct {
1234 char const *path1;
1235 char const *path2;
1236 int equivalent;
1237 } tests[] = {
1238 { NULL, NULL, -1 },
1239 { NULL, "f1", -1 },
1240 { "f1", NULL, -1 },
1241 { "f1", "tr2_test_dir", -1 },
1242 { "tr2_test_dir", "f1", -1 },
1243 { "tr2_test_dir", "tr2_test_dir", -1 },
1244 { "tr2_test_dir/./f1", "tr2_test_dir/f2", 0 },
1245 { "tr2_test_dir/f1" , "tr2_test_dir/f1", 1 },
1246 { "not_exists_file" , "tr2_test_dir/f1", 0 },
1247 { "tr2_test_dir\\f1" , "tr2_test_dir/./f1", 1 },
1248 { "not_exists_file" , "not_exists_file", -1 },
1249 { "tr2_test_dir/f1" , "not_exists_file", 0 },
1250 { "tr2_test_dir/../tr2_test_dir/f1", "tr2_test_dir/f1", 1 }
1253 GetCurrentDirectoryA(MAX_PATH, current_path);
1254 GetTempPathA(MAX_PATH, temp_path);
1255 ok(SetCurrentDirectoryA(temp_path), "SetCurrentDirectoryA to temp_path failed\n");
1256 CreateDirectoryA("tr2_test_dir", NULL);
1258 file = CreateFileA("tr2_test_dir/f1", 0, 0, NULL, CREATE_ALWAYS, 0, NULL);
1259 ok(file != INVALID_HANDLE_VALUE, "create file failed: INVALID_HANDLE_VALUE\n");
1260 CloseHandle(file);
1261 file = CreateFileA("tr2_test_dir/f2", 0, 0, NULL, CREATE_ALWAYS, 0, NULL);
1262 ok(file != INVALID_HANDLE_VALUE, "create file failed: INVALID_HANDLE_VALUE\n");
1263 CloseHandle(file);
1265 for(i=0; i<ARRAY_SIZE(tests); i++) {
1266 errno = 0xdeadbeef;
1267 val = p_tr2_sys__Equivalent(tests[i].path1, tests[i].path2);
1268 ok(tests[i].equivalent == val, "tr2_sys__Equivalent(): test %d expect: %d, got %d\n", i+1, tests[i].equivalent, val);
1269 ok(errno == 0xdeadbeef, "errno = %d\n", errno);
1272 val = p_tr2_sys__Equivalent_wchar(L"tr2_test_dir/f1", L"tr2_test_dir/f1");
1273 ok(val == 1, "tr2_sys__Equivalent(): expect: 1, got %d\n", val);
1274 val = p_tr2_sys__Equivalent_wchar(L"tr2_test_dir/f1", L"tr2_test_dir/f2");
1275 ok(val == 0, "tr2_sys__Equivalent(): expect: 0, got %d\n", val);
1276 val = p_tr2_sys__Equivalent_wchar(L"tr2_test_dir", L"tr2_test_dir");
1277 ok(val == -1, "tr2_sys__Equivalent(): expect: -1, got %d\n", val);
1279 ok(DeleteFileA("tr2_test_dir/f1"), "expect tr2_test_dir/f1 to exist\n");
1280 ok(DeleteFileA("tr2_test_dir/f2"), "expect tr2_test_dir/f2 to exist\n");
1281 ok(p_tr2_sys__Remove_dir("tr2_test_dir"), "expect tr2_test_dir to exist\n");
1282 ok(SetCurrentDirectoryA(current_path), "SetCurrentDirectoryA failed\n");
1285 static void test_tr2_sys__Current_get(void)
1287 char temp_path[MAX_PATH], current_path[MAX_PATH], origin_path[MAX_PATH];
1288 char *temp;
1289 WCHAR temp_path_wchar[MAX_PATH], current_path_wchar[MAX_PATH];
1290 WCHAR *temp_wchar;
1292 GetCurrentDirectoryA(MAX_PATH, origin_path);
1293 GetTempPathA(MAX_PATH, temp_path);
1295 ok(SetCurrentDirectoryA(temp_path), "SetCurrentDirectoryA to temp_path failed\n");
1296 temp = p_tr2_sys__Current_get(current_path);
1297 ok(temp == current_path, "p_tr2_sys__Current_get returned different buffer\n");
1298 strcat(temp, "\\");
1299 ok(!strcmp(temp_path, current_path), "test_tr2_sys__Current_get(): expect: %s, got %s\n", temp_path, current_path);
1301 GetTempPathW(MAX_PATH, temp_path_wchar);
1302 ok(SetCurrentDirectoryW(temp_path_wchar), "SetCurrentDirectoryW to temp_path_wchar failed\n");
1303 temp_wchar = p_tr2_sys__Current_get_wchar(current_path_wchar);
1304 ok(temp_wchar == current_path_wchar, "p_tr2_sys__Current_get_wchar returned different buffer\n");
1305 wcscat(temp_wchar, L"\\");
1306 ok(!wcscmp(temp_path_wchar, current_path_wchar), "test_tr2_sys__Current_get(): expect: %s, got %s\n", wine_dbgstr_w(temp_path_wchar), wine_dbgstr_w(current_path_wchar));
1308 ok(SetCurrentDirectoryA(origin_path), "SetCurrentDirectoryA to origin_path failed\n");
1309 temp = p_tr2_sys__Current_get(current_path);
1310 ok(temp == current_path, "p_tr2_sys__Current_get returned different buffer\n");
1311 ok(!strcmp(origin_path, current_path), "test_tr2_sys__Current_get(): expect: %s, got %s\n", origin_path, current_path);
1314 static void test_tr2_sys__Current_set(void)
1316 char temp_path[MAX_PATH], current_path[MAX_PATH], origin_path[MAX_PATH];
1317 char *temp;
1319 GetTempPathA(MAX_PATH, temp_path);
1320 GetCurrentDirectoryA(MAX_PATH, origin_path);
1321 temp = p_tr2_sys__Current_get(origin_path);
1322 ok(temp == origin_path, "p_tr2_sys__Current_get returned different buffer\n");
1324 ok(p_tr2_sys__Current_set(temp_path), "p_tr2_sys__Current_set to temp_path failed\n");
1325 temp = p_tr2_sys__Current_get(current_path);
1326 ok(temp == current_path, "p_tr2_sys__Current_get returned different buffer\n");
1327 strcat(temp, "\\");
1328 ok(!strcmp(temp_path, current_path), "test_tr2_sys__Current_get(): expect: %s, got %s\n", temp_path, current_path);
1330 ok(p_tr2_sys__Current_set_wchar(L"./"), "p_tr2_sys__Current_set_wchar to temp_path failed\n");
1331 temp = p_tr2_sys__Current_get(current_path);
1332 ok(temp == current_path, "p_tr2_sys__Current_get returned different buffer\n");
1333 strcat(temp, "\\");
1334 ok(!strcmp(temp_path, current_path), "test_tr2_sys__Current_get(): expect: %s, got %s\n", temp_path, current_path);
1336 errno = 0xdeadbeef;
1337 ok(!p_tr2_sys__Current_set("not_exisist_dir"), "p_tr2_sys__Current_set to not_exist_dir succeed\n");
1338 ok(errno == 0xdeadbeef, "errno = %d\n", errno);
1340 errno = 0xdeadbeef;
1341 ok(!p_tr2_sys__Current_set("??invalid_name>>"), "p_tr2_sys__Current_set to ??invalid_name>> succeed\n");
1342 ok(errno == 0xdeadbeef, "errno = %d\n", errno);
1344 ok(p_tr2_sys__Current_set(origin_path), "p_tr2_sys__Current_set to origin_path failed\n");
1345 temp = p_tr2_sys__Current_get(current_path);
1346 ok(temp == current_path, "p_tr2_sys__Current_get returned different buffer\n");
1347 ok(!strcmp(origin_path, current_path), "test_tr2_sys__Current_get(): expect: %s, got %s\n", origin_path, current_path);
1350 static void test_tr2_sys__Make_dir(void)
1352 int ret, i;
1353 struct {
1354 char const *path;
1355 int val;
1356 } tests[] = {
1357 { "tr2_test_dir", 1 },
1358 { "tr2_test_dir", 0 },
1359 { NULL, -1 },
1360 { "??invalid_name>>", -1 }
1363 for(i=0; i<ARRAY_SIZE(tests); i++) {
1364 errno = 0xdeadbeef;
1365 ret = p_tr2_sys__Make_dir(tests[i].path);
1366 ok(ret == tests[i].val, "tr2_sys__Make_dir(): test %d expect: %d, got %d\n", i+1, tests[i].val, ret);
1367 ok(errno == 0xdeadbeef, "tr2_sys__Make_dir(): test %d errno expect 0xdeadbeef, got %d\n", i+1, errno);
1369 ret = p_tr2_sys__Make_dir_wchar(L"wd");
1370 ok(ret == 1, "tr2_sys__Make_dir(): expect: 1, got %d\n", ret);
1372 ok(p_tr2_sys__Remove_dir("tr2_test_dir"), "expect tr2_test_dir to exist\n");
1373 ok(p_tr2_sys__Remove_dir_wchar(L"wd"), "expect wd to exist\n");
1376 static void test_tr2_sys__Remove_dir(void)
1378 MSVCP_bool ret;
1379 int i;
1380 struct {
1381 char const *path;
1382 MSVCP_bool val;
1383 } tests[] = {
1384 { "tr2_test_dir", TRUE },
1385 { "tr2_test_dir", FALSE },
1386 { NULL, FALSE },
1387 { "??invalid_name>>", FALSE }
1390 ok(p_tr2_sys__Make_dir("tr2_test_dir"), "tr2_sys__Make_dir() failed\n");
1392 for(i=0; i<ARRAY_SIZE(tests); i++) {
1393 errno = 0xdeadbeef;
1394 ret = p_tr2_sys__Remove_dir(tests[i].path);
1395 ok(ret == tests[i].val, "test_tr2_sys__Remove_dir(): test %d expect: %d, got %d\n", i+1, tests[i].val, ret);
1396 ok(errno == 0xdeadbeef, "test_tr2_sys__Remove_dir(): test %d errno expect 0xdeadbeef, got %d\n", i+1, errno);
1400 static void test_tr2_sys__Copy_file(void)
1402 HANDLE file;
1403 int ret, i;
1404 LARGE_INTEGER file_size;
1405 struct {
1406 char const *source;
1407 char const *dest;
1408 MSVCP_bool fail_if_exists;
1409 int last_error;
1410 int last_error2;
1411 } tests[] = {
1412 { "f1", "f1_copy", TRUE, ERROR_SUCCESS, ERROR_SUCCESS },
1413 { "f1", "tr2_test_dir\\f1_copy", TRUE, ERROR_SUCCESS, ERROR_SUCCESS },
1414 { "f1", "tr2_test_dir\\f1_copy", TRUE, ERROR_FILE_EXISTS, ERROR_FILE_EXISTS },
1415 { "f1", "tr2_test_dir\\f1_copy", FALSE, ERROR_SUCCESS, ERROR_SUCCESS },
1416 { "tr2_test_dir", "f1", TRUE, ERROR_ACCESS_DENIED, ERROR_ACCESS_DENIED },
1417 { "tr2_test_dir", "tr2_test_dir_copy", TRUE, ERROR_ACCESS_DENIED, ERROR_ACCESS_DENIED },
1418 { NULL, "f1", TRUE, ERROR_INVALID_PARAMETER, ERROR_INVALID_PARAMETER },
1419 { "f1", NULL, TRUE, ERROR_INVALID_PARAMETER, ERROR_INVALID_PARAMETER },
1420 { "not_exist", "tr2_test_dir", TRUE, ERROR_FILE_NOT_FOUND, ERROR_FILE_NOT_FOUND },
1421 { "f1", "not_exist_dir\\f1_copy", TRUE, ERROR_PATH_NOT_FOUND, ERROR_FILE_NOT_FOUND },
1422 { "f1", "tr2_test_dir", TRUE, ERROR_ACCESS_DENIED, ERROR_FILE_EXISTS }
1425 ret = p_tr2_sys__Make_dir("tr2_test_dir");
1426 ok(ret == 1, "test_tr2_sys__Make_dir(): expect 1 got %d\n", ret);
1427 file = CreateFileA("f1", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
1428 ok(file != INVALID_HANDLE_VALUE, "create file failed: INVALID_HANDLE_VALUE\n");
1429 file_size.QuadPart = 7;
1430 ok(SetFilePointerEx(file, file_size, NULL, FILE_BEGIN), "SetFilePointerEx failed\n");
1431 ok(SetEndOfFile(file), "SetEndOfFile failed\n");
1432 CloseHandle(file);
1434 for(i=0; i<ARRAY_SIZE(tests); i++) {
1435 errno = 0xdeadbeef;
1436 ret = p_tr2_sys__Copy_file(tests[i].source, tests[i].dest, tests[i].fail_if_exists);
1437 ok(ret == tests[i].last_error || ret == tests[i].last_error2,
1438 "test_tr2_sys__Copy_file(): test %d expect: %d, got %d\n", i+1, tests[i].last_error, ret);
1439 ok(errno == 0xdeadbeef, "test_tr2_sys__Copy_file(): test %d errno expect 0xdeadbeef, got %d\n", i+1, errno);
1440 if(ret == ERROR_SUCCESS)
1441 ok(p_tr2_sys__File_size(tests[i].source) == p_tr2_sys__File_size(tests[i].dest),
1442 "test_tr2_sys__Copy_file(): test %d failed, mismatched file sizes\n", i+1);
1444 ret = p_tr2_sys__Copy_file_wchar(L"f1", L"fw", TRUE);
1445 ok(ret == ERROR_SUCCESS, "test_tr2_sys__Copy_file_wchar() expect ERROR_SUCCESS, got %d\n", ret);
1447 ok(DeleteFileA("f1"), "expect f1 to exist\n");
1448 ok(DeleteFileW(L"fw"), "expect fw to exist\n");
1449 ok(DeleteFileA("f1_copy"), "expect f1_copy to exist\n");
1450 ok(DeleteFileA("tr2_test_dir/f1_copy"), "expect tr2_test_dir/f1 to exist\n");
1451 ret = p_tr2_sys__Remove_dir("tr2_test_dir");
1452 ok(ret == 1, "test_tr2_sys__Remove_dir(): expect 1 got %d\n", ret);
1455 static void test_tr2_sys__Rename(void)
1457 int ret, i;
1458 HANDLE file, h1, h2;
1459 BY_HANDLE_FILE_INFORMATION info1, info2;
1460 char temp_path[MAX_PATH], current_path[MAX_PATH];
1461 LARGE_INTEGER file_size;
1462 static const struct {
1463 char const *old_path;
1464 char const *new_path;
1465 int val;
1466 } tests[] = {
1467 { "tr2_test_dir\\f1", "tr2_test_dir\\f1_rename", ERROR_SUCCESS },
1468 { "tr2_test_dir\\f1", NULL, ERROR_INVALID_PARAMETER },
1469 { "tr2_test_dir\\f1", "tr2_test_dir\\f1_rename", ERROR_FILE_NOT_FOUND },
1470 { NULL, "tr2_test_dir\\NULL_rename", ERROR_INVALID_PARAMETER },
1471 { "tr2_test_dir\\f1_rename", "tr2_test_dir\\??invalid_name>>", ERROR_INVALID_NAME },
1472 { "tr2_test_dir\\not_exist_file", "tr2_test_dir\\not_exist_rename", ERROR_FILE_NOT_FOUND }
1474 static const struct {
1475 const WCHAR *old_path;
1476 const WCHAR *new_path;
1477 int val;
1478 } testsW[] = {
1479 { L"tr2_test_dir/f1", L"tr2_test_dir\\f1_rename", ERROR_SUCCESS },
1480 { L"tr2_test_dir/f1", NULL, ERROR_FILE_NOT_FOUND }, /* Differs from the A version */
1481 { L"tr2_test_dir/f1", L"tr2_test_dir\\f1_rename", ERROR_FILE_NOT_FOUND },
1482 { NULL, L"tr2_test_dir\\f1_rename2", ERROR_PATH_NOT_FOUND }, /* Differs from the A version */
1483 { L"tr2_test_dir\\f1_rename", L"tr2_test_dir\\??invalid>", ERROR_INVALID_NAME },
1484 { L"tr2_test_dir\\not_exist", L"tr2_test_dir\\not_exist2", ERROR_FILE_NOT_FOUND },
1485 { L"tr2_test_dir\\not_exist", L"tr2_test_dir\\??invalid>", ERROR_FILE_NOT_FOUND }
1488 GetCurrentDirectoryA(MAX_PATH, current_path);
1489 GetTempPathA(MAX_PATH, temp_path);
1490 ok(SetCurrentDirectoryA(temp_path), "SetCurrentDirectoryA to temp_path failed\n");
1491 ret = p_tr2_sys__Make_dir("tr2_test_dir");
1493 ok(ret == 1, "test_tr2_sys__Make_dir(): expect 1 got %d\n", ret);
1494 file = CreateFileA("tr2_test_dir\\f1", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
1495 ok(file != INVALID_HANDLE_VALUE, "create file failed: INVALID_HANDLE_VALUE\n");
1496 CloseHandle(file);
1498 ret = p_tr2_sys__Rename("tr2_test_dir\\f1", "tr2_test_dir\\f1");
1499 ok(ERROR_SUCCESS == ret, "test_tr2_sys__Rename(): expect: ERROR_SUCCESS, got %d\n", ret);
1500 for(i=0; i<ARRAY_SIZE(tests); i++) {
1501 errno = 0xdeadbeef;
1502 if(tests[i].val == ERROR_SUCCESS) {
1503 h1 = CreateFileA(tests[i].old_path, 0, FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE,
1504 NULL, OPEN_EXISTING, 0, 0);
1505 ok(h1 != INVALID_HANDLE_VALUE, "create file failed: INVALID_HANDLE_VALUE\n");
1506 ok(GetFileInformationByHandle(h1, &info1), "GetFileInformationByHandle failed\n");
1507 CloseHandle(h1);
1509 SetLastError(0xdeadbeef);
1510 ret = p_tr2_sys__Rename(tests[i].old_path, tests[i].new_path);
1511 ok(ret == tests[i].val, "test_tr2_sys__Rename(): test %d expect: %d, got %d\n", i+1, tests[i].val, ret);
1512 ok(errno == 0xdeadbeef, "test_tr2_sys__Rename(): test %d errno expect 0xdeadbeef, got %d\n", i+1, errno);
1513 if(ret == ERROR_SUCCESS) {
1514 h2 = CreateFileA(tests[i].new_path, 0, FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE,
1515 NULL, OPEN_EXISTING, 0, 0);
1516 ok(h2 != INVALID_HANDLE_VALUE, "create file failed: INVALID_HANDLE_VALUE\n");
1517 ok(GetFileInformationByHandle(h2, &info2), "GetFileInformationByHandle failed\n");
1518 CloseHandle(h2);
1519 ok(info1.nFileIndexHigh == info2.nFileIndexHigh
1520 && info1.nFileIndexLow == info2.nFileIndexLow,
1521 "test_tr2_sys__Rename(): test %d expect two files equivalent\n", i+1);
1525 file = CreateFileA("tr2_test_dir\\f1", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
1526 ok(file != INVALID_HANDLE_VALUE, "create file failed: INVALID_HANDLE_VALUE\n");
1527 file_size.QuadPart = 7;
1528 ok(SetFilePointerEx(file, file_size, NULL, FILE_BEGIN), "SetFilePointerEx failed\n");
1529 ok(SetEndOfFile(file), "SetEndOfFile failed\n");
1530 CloseHandle(file);
1531 ret = p_tr2_sys__Rename("tr2_test_dir\\f1", "tr2_test_dir\\f1_rename");
1532 ok(ret == ERROR_ALREADY_EXISTS, "test_tr2_sys__Rename(): expect: ERROR_ALREADY_EXISTS, got %d\n", ret);
1533 ok(p_tr2_sys__File_size("tr2_test_dir\\f1") == 7, "test_tr2_sys__Rename(): expect: 7, got %s\n", wine_dbgstr_longlong(p_tr2_sys__File_size("tr2_test_dir\\f1")));
1534 ok(p_tr2_sys__File_size("tr2_test_dir\\f1_rename") == 0, "test_tr2_sys__Rename(): expect: 0, got %s\n",wine_dbgstr_longlong(p_tr2_sys__File_size("tr2_test_dir\\f1_rename")));
1536 ok(DeleteFileA("tr2_test_dir\\f1_rename"), "expect f1_rename to exist\n");
1538 for(i=0; i<ARRAY_SIZE(testsW); i++) {
1539 errno = 0xdeadbeef;
1540 if(testsW[i].val == ERROR_SUCCESS) {
1541 h1 = CreateFileW(testsW[i].old_path, 0, FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE,
1542 NULL, OPEN_EXISTING, 0, 0);
1543 ok(h1 != INVALID_HANDLE_VALUE, "create file failed: INVALID_HANDLE_VALUE\n");
1544 ok(GetFileInformationByHandle(h1, &info1), "GetFileInformationByHandle failed\n");
1545 CloseHandle(h1);
1547 SetLastError(0xdeadbeef);
1548 ret = p_tr2_sys__Rename_wchar(testsW[i].old_path, testsW[i].new_path);
1549 ok(ret == testsW[i].val, "test_tr2_sys__Rename_wchar(): test %d expect: %d, got %d\n", i+1, testsW[i].val, ret);
1550 ok(errno == 0xdeadbeef, "test_tr2_sys__Rename_wchar(): test %d errno expect 0xdeadbeef, got %d\n", i+1, errno);
1551 if(ret == ERROR_SUCCESS) {
1552 h2 = CreateFileW(testsW[i].new_path, 0, FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE,
1553 NULL, OPEN_EXISTING, 0, 0);
1554 ok(h2 != INVALID_HANDLE_VALUE, "create file failed: INVALID_HANDLE_VALUE\n");
1555 ok(GetFileInformationByHandle(h2, &info2), "GetFileInformationByHandle failed\n");
1556 CloseHandle(h2);
1557 ok(info1.nFileIndexHigh == info2.nFileIndexHigh
1558 && info1.nFileIndexLow == info2.nFileIndexLow,
1559 "test_tr2_sys__Rename_wchar(): test %d expect two files equivalent\n", i+1);
1563 ok(DeleteFileA("tr2_test_dir\\f1_rename"), "expect f1_rename to exist\n");
1564 ret = p_tr2_sys__Remove_dir("tr2_test_dir");
1565 ok(ret == 1, "test_tr2_sys__Remove_dir(): expect %d got %d\n", 1, ret);
1566 ok(SetCurrentDirectoryA(current_path), "SetCurrentDirectoryA failed\n");
1569 static void test_tr2_sys__Statvfs(void)
1571 struct space_info info;
1572 char current_path[MAX_PATH];
1573 WCHAR current_path_wchar[MAX_PATH];
1575 p_tr2_sys__Current_get(current_path);
1576 p_tr2_sys__Current_get_wchar(current_path_wchar);
1578 p_tr2_sys__Statvfs(&info, current_path);
1579 ok(info.capacity >= info.free, "test_tr2_sys__Statvfs(): info.capacity < info.free\n");
1580 ok(info.free >= info.available, "test_tr2_sys__Statvfs(): info.free < info.available\n");
1582 p_tr2_sys__Statvfs_wchar(&info, current_path_wchar);
1583 ok(info.capacity >= info.free, "tr2_sys__Statvfs_wchar(): info.capacity < info.free\n");
1584 ok(info.free >= info.available, "tr2_sys__Statvfs_wchar(): info.free < info.available\n");
1586 p_tr2_sys__Statvfs(&info, NULL);
1587 ok(info.available == 0, "test_tr2_sys__Statvfs(): info.available expect: %d, got %s\n",
1588 0, wine_dbgstr_longlong(info.available));
1589 ok(info.capacity == 0, "test_tr2_sys__Statvfs(): info.capacity expect: %d, got %s\n",
1590 0, wine_dbgstr_longlong(info.capacity));
1591 ok(info.free == 0, "test_tr2_sys__Statvfs(): info.free expect: %d, got %s\n",
1592 0, wine_dbgstr_longlong(info.free));
1594 p_tr2_sys__Statvfs(&info, "not_exist");
1595 ok(info.available == 0, "test_tr2_sys__Statvfs(): info.available expect: %d, got %s\n",
1596 0, wine_dbgstr_longlong(info.available));
1597 ok(info.capacity == 0, "test_tr2_sys__Statvfs(): info.capacity expect: %d, got %s\n",
1598 0, wine_dbgstr_longlong(info.capacity));
1599 ok(info.free == 0, "test_tr2_sys__Statvfs(): info.free expect: %d, got %s\n",
1600 0, wine_dbgstr_longlong(info.free));
1603 static void test_tr2_sys__Stat(void)
1605 int i, err_code, ret;
1606 HANDLE file;
1607 enum file_type val;
1608 struct {
1609 char const *path;
1610 enum file_type ret;
1611 int err_code;
1612 int is_todo;
1613 } tests[] = {
1614 { NULL, status_unknown, ERROR_INVALID_PARAMETER, FALSE },
1615 { "tr2_test_dir", directory_file, ERROR_SUCCESS, FALSE },
1616 { "tr2_test_dir\\f1", regular_file, ERROR_SUCCESS, FALSE },
1617 { "tr2_test_dir\\not_exist_file ", file_not_found, ERROR_SUCCESS, FALSE },
1618 { "tr2_test_dir\\??invalid_name>>", file_not_found, ERROR_SUCCESS, FALSE },
1619 { "tr2_test_dir\\f1_link" , regular_file, ERROR_SUCCESS, TRUE },
1620 { "tr2_test_dir\\dir_link", directory_file, ERROR_SUCCESS, TRUE },
1623 CreateDirectoryA("tr2_test_dir", NULL);
1624 file = CreateFileA("tr2_test_dir/f1", 0, 0, NULL, CREATE_ALWAYS, 0, NULL);
1625 ok(file != INVALID_HANDLE_VALUE, "create file failed: INVALID_HANDLE_VALUE\n");
1626 ok(CloseHandle(file), "CloseHandle\n");
1627 SetLastError(0xdeadbeef);
1628 ret = pCreateSymbolicLinkA ? pCreateSymbolicLinkA("tr2_test_dir/f1_link", "tr2_test_dir/f1", 0) : FALSE;
1629 if(!ret && (!pCreateSymbolicLinkA || GetLastError()==ERROR_PRIVILEGE_NOT_HELD||GetLastError()==ERROR_INVALID_FUNCTION)) {
1630 tests[5].ret = tests[6].ret = file_not_found;
1631 win_skip("Privilege not held or symbolic link not supported, skipping symbolic link tests.\n");
1632 }else {
1633 ok(ret, "CreateSymbolicLinkA failed\n");
1634 ok(pCreateSymbolicLinkA("tr2_test_dir/dir_link", "tr2_test_dir", 1), "CreateSymbolicLinkA failed\n");
1637 file = CreateNamedPipeA("\\\\.\\PiPe\\tests_pipe.c",
1638 PIPE_ACCESS_DUPLEX, PIPE_TYPE_BYTE | PIPE_WAIT, 2, 1024, 1024,
1639 NMPWAIT_USE_DEFAULT_WAIT, NULL);
1640 ok(file != INVALID_HANDLE_VALUE, "CreateNamedPipe failed\n");
1641 err_code = 0xdeadbeef;
1642 val = p_tr2_sys__Stat("\\\\.\\PiPe\\tests_pipe.c", &err_code);
1643 todo_wine ok(regular_file == val, "tr2_sys__Stat(): expect: regular_file, got %d\n", val);
1644 todo_wine ok(ERROR_SUCCESS == err_code, "tr2_sys__Stat(): err_code expect: ERROR_SUCCESS, got %d\n", err_code);
1645 err_code = 0xdeadbeef;
1646 val = p_tr2_sys__Lstat("\\\\.\\PiPe\\tests_pipe.c", &err_code);
1647 ok(status_unknown == val, "tr2_sys__Lstat(): expect: status_unknown, got %d\n", val);
1648 todo_wine ok(ERROR_PIPE_BUSY == err_code, "tr2_sys__Lstat(): err_code expect: ERROR_PIPE_BUSY, got %d\n", err_code);
1649 ok(CloseHandle(file), "CloseHandle\n");
1650 file = CreateNamedPipeA("\\\\.\\PiPe\\tests_pipe.c",
1651 PIPE_ACCESS_DUPLEX, PIPE_TYPE_BYTE | PIPE_WAIT, 2, 1024, 1024,
1652 NMPWAIT_USE_DEFAULT_WAIT, NULL);
1653 ok(file != INVALID_HANDLE_VALUE, "CreateNamedPipe failed\n");
1654 err_code = 0xdeadbeef;
1655 val = p_tr2_sys__Lstat("\\\\.\\PiPe\\tests_pipe.c", &err_code);
1656 todo_wine ok(regular_file == val, "tr2_sys__Lstat(): expect: regular_file, got %d\n", val);
1657 todo_wine ok(ERROR_SUCCESS == err_code, "tr2_sys__Lstat(): err_code expect: ERROR_SUCCESS, got %d\n", err_code);
1658 ok(CloseHandle(file), "CloseHandle\n");
1660 for(i=0; i<ARRAY_SIZE(tests); i++) {
1661 err_code = 0xdeadbeef;
1662 val = p_tr2_sys__Stat(tests[i].path, &err_code);
1663 todo_wine_if(tests[i].is_todo)
1664 ok(tests[i].ret == val, "tr2_sys__Stat(): test %d expect: %d, got %d\n", i+1, tests[i].ret, val);
1665 ok(tests[i].err_code == err_code, "tr2_sys__Stat(): test %d err_code expect: %d, got %d\n",
1666 i+1, tests[i].err_code, err_code);
1668 /* test tr2_sys__Lstat */
1669 err_code = 0xdeadbeef;
1670 val = p_tr2_sys__Lstat(tests[i].path, &err_code);
1671 todo_wine_if(tests[i].is_todo)
1672 ok(tests[i].ret == val, "tr2_sys__Lstat(): test %d expect: %d, got %d\n", i+1, tests[i].ret, val);
1673 ok(tests[i].err_code == err_code, "tr2_sys__Lstat(): test %d err_code expect: %d, got %d\n",
1674 i+1, tests[i].err_code, err_code);
1677 err_code = 0xdeadbeef;
1678 val = p_tr2_sys__Stat_wchar(L"tr2_test_dir", &err_code);
1679 ok(directory_file == val, "tr2_sys__Stat_wchar() expect directory_file, got %d\n", val);
1680 ok(ERROR_SUCCESS == err_code, "tr2_sys__Stat_wchar(): err_code expect ERROR_SUCCESS, got %d\n", err_code);
1681 err_code = 0xdeadbeef;
1682 val = p_tr2_sys__Lstat_wchar(L"tr2_test_dir/f1", &err_code);
1683 ok(regular_file == val, "tr2_sys__Lstat_wchar() expect regular_file, got %d\n", val);
1684 ok(ERROR_SUCCESS == err_code, "tr2_sys__Lstat_wchar(): err_code expect ERROR_SUCCESS, got %d\n", err_code);
1686 if(ret) {
1687 todo_wine ok(DeleteFileA("tr2_test_dir/f1_link"), "expect tr2_test_dir/f1_link to exist\n");
1688 todo_wine ok(RemoveDirectoryA("tr2_test_dir/dir_link"), "expect tr2_test_dir/dir_link to exist\n");
1690 ok(DeleteFileA("tr2_test_dir/f1"), "expect tr2_test_dir/f1 to exist\n");
1691 ok(RemoveDirectoryA("tr2_test_dir"), "expect tr2_test_dir to exist\n");
1694 static void test_tr2_sys__Last_write_time(void)
1696 HANDLE file;
1697 int ret;
1698 __int64 last_write_time, newtime;
1699 ret = p_tr2_sys__Make_dir("tr2_test_dir");
1700 ok(ret == 1, "tr2_sys__Make_dir() expect 1 got %d\n", ret);
1702 file = CreateFileA("tr2_test_dir/f1", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
1703 ok(file != INVALID_HANDLE_VALUE, "create file failed: INVALID_HANDLE_VALUE\n");
1704 CloseHandle(file);
1706 last_write_time = p_tr2_sys__Last_write_time("tr2_test_dir/f1");
1707 newtime = p_tr2_sys__Last_write_time_wchar(L"tr2_test_dir/f1");
1708 ok(last_write_time == newtime, "last_write_time = %s, newtime = %s\n",
1709 wine_dbgstr_longlong(last_write_time), wine_dbgstr_longlong(newtime));
1710 newtime = last_write_time + 123456789;
1711 p_tr2_sys__Last_write_time_set("tr2_test_dir/f1", newtime);
1712 todo_wine ok(last_write_time == p_tr2_sys__Last_write_time("tr2_test_dir/f1"),
1713 "last_write_time should have changed: %s\n",
1714 wine_dbgstr_longlong(last_write_time));
1716 errno = 0xdeadbeef;
1717 last_write_time = p_tr2_sys__Last_write_time("not_exist");
1718 ok(errno == 0xdeadbeef, "tr2_sys__Last_write_time(): errno expect 0xdeadbeef, got %d\n", errno);
1719 ok(last_write_time == 0, "expect 0 got %s\n", wine_dbgstr_longlong(last_write_time));
1720 last_write_time = p_tr2_sys__Last_write_time(NULL);
1721 ok(last_write_time == 0, "expect 0 got %s\n", wine_dbgstr_longlong(last_write_time));
1723 p_tr2_sys__Last_write_time_set("not_exist", newtime);
1724 errno = 0xdeadbeef;
1725 p_tr2_sys__Last_write_time_set(NULL, newtime);
1726 ok(errno == 0xdeadbeef, "tr2_sys__Last_write_time(): errno expect 0xdeadbeef, got %d\n", errno);
1728 ok(DeleteFileA("tr2_test_dir/f1"), "expect tr2_test_dir/f1 to exist\n");
1729 ret = p_tr2_sys__Remove_dir("tr2_test_dir");
1730 ok(ret == 1, "test_tr2_sys__Remove_dir(): expect 1 got %d\n", ret);
1733 static void test_tr2_sys__dir_operation(void)
1735 char *file_name, first_file_name[MAX_PATH], dest[MAX_PATH], longer_path[MAX_PATH];
1736 HANDLE file, result_handle;
1737 enum file_type type;
1738 int err, num_of_f1 = 0, num_of_f2 = 0, num_of_sub_dir = 0, num_of_other_files = 0;
1740 CreateDirectoryA("tr2_test_dir", NULL);
1741 file = CreateFileA("tr2_test_dir/f1", 0, 0, NULL, CREATE_ALWAYS, 0, NULL);
1742 ok(file != INVALID_HANDLE_VALUE, "create file failed: INVALID_HANDLE_VALUE\n");
1743 CloseHandle(file);
1744 file = CreateFileA("tr2_test_dir/f2", 0, 0, NULL, CREATE_ALWAYS, 0, NULL);
1745 ok(file != INVALID_HANDLE_VALUE, "create file failed: INVALID_HANDLE_VALUE\n");
1746 CloseHandle(file);
1747 CreateDirectoryA("tr2_test_dir/sub_dir", NULL);
1748 file = CreateFileA("tr2_test_dir/sub_dir/sub_f1", 0, 0, NULL, CREATE_ALWAYS, 0, NULL);
1749 ok(file != INVALID_HANDLE_VALUE, "create file failed: INVALID_HANDLE_VALUE\n");
1750 CloseHandle(file);
1752 GetCurrentDirectoryA(MAX_PATH, longer_path);
1753 strcat(longer_path, "\\tr2_test_dir\\");
1754 while(lstrlenA(longer_path) < MAX_PATH-1)
1755 strcat(longer_path, "s");
1756 ok(lstrlenA(longer_path) == MAX_PATH-1, "tr2_sys__Open_dir(): expect MAX_PATH, got %d\n", lstrlenA(longer_path));
1757 memset(first_file_name, 0xff, MAX_PATH);
1758 type = err = 0xdeadbeef;
1759 result_handle = NULL;
1760 result_handle = p_tr2_sys__Open_dir(first_file_name, longer_path, &err, &type);
1761 ok(result_handle == NULL, "tr2_sys__Open_dir(): expect NULL, got %p\n", result_handle);
1762 ok(!*first_file_name, "tr2_sys__Open_dir(): expect: 0, got %s\n", first_file_name);
1763 ok(err == ERROR_BAD_PATHNAME, "tr2_sys__Open_dir(): expect: ERROR_BAD_PATHNAME, got %d\n", err);
1764 ok((int)type == 0xdeadbeef, "tr2_sys__Open_dir(): expect 0xdeadbeef, got %d\n", type);
1766 memset(first_file_name, 0xff, MAX_PATH);
1767 memset(dest, 0, MAX_PATH);
1768 type = err = 0xdeadbeef;
1769 result_handle = NULL;
1770 result_handle = p_tr2_sys__Open_dir(first_file_name, "tr2_test_dir", &err, &type);
1771 ok(result_handle != NULL, "tr2_sys__Open_dir(): expect: not NULL, got %p\n", result_handle);
1772 ok(err == ERROR_SUCCESS, "tr2_sys__Open_dir(): expect: ERROR_SUCCESS, got %d\n", err);
1773 file_name = first_file_name;
1774 while(*file_name) {
1775 if (!strcmp(file_name, "f1")) {
1776 ++num_of_f1;
1777 ok(type == regular_file, "expect regular_file, got %d\n", type);
1778 }else if(!strcmp(file_name, "f2")) {
1779 ++num_of_f2;
1780 ok(type == regular_file, "expect regular_file, got %d\n", type);
1781 }else if(!strcmp(file_name, "sub_dir")) {
1782 ++num_of_sub_dir;
1783 ok(type == directory_file, "expect directory_file, got %d\n", type);
1784 }else {
1785 ++num_of_other_files;
1787 file_name = p_tr2_sys__Read_dir(dest, result_handle, &type);
1789 ok(type == status_unknown, "p_tr2_sys__Read_dir(): expect: status_unknown, got %d\n", type);
1790 p_tr2_sys__Close_dir(result_handle);
1791 ok(result_handle != NULL, "tr2_sys__Open_dir(): expect: not NULL, got %p\n", result_handle);
1792 ok(num_of_f1 == 1, "found f1 %d times\n", num_of_f1);
1793 ok(num_of_f2 == 1, "found f2 %d times\n", num_of_f2);
1794 ok(num_of_sub_dir == 1, "found sub_dir %d times\n", num_of_sub_dir);
1795 ok(num_of_other_files == 0, "found %d other files\n", num_of_other_files);
1797 memset(first_file_name, 0xff, MAX_PATH);
1798 type = err = 0xdeadbeef;
1799 result_handle = file;
1800 result_handle = p_tr2_sys__Open_dir(first_file_name, "not_exist", &err, &type);
1801 ok(result_handle == NULL, "tr2_sys__Open_dir(): expect: NULL, got %p\n", result_handle);
1802 ok(err == ERROR_BAD_PATHNAME, "tr2_sys__Open_dir(): expect: ERROR_BAD_PATHNAME, got %d\n", err);
1803 ok((int)type == 0xdeadbeef, "tr2_sys__Open_dir(): expect: 0xdeadbeef, got %d\n", type);
1804 ok(!*first_file_name, "tr2_sys__Open_dir(): expect: 0, got %s\n", first_file_name);
1806 CreateDirectoryA("empty_dir", NULL);
1807 memset(first_file_name, 0xff, MAX_PATH);
1808 type = err = 0xdeadbeef;
1809 result_handle = file;
1810 result_handle = p_tr2_sys__Open_dir(first_file_name, "empty_dir", &err, &type);
1811 ok(result_handle == NULL, "tr2_sys__Open_dir(): expect: NULL, got %p\n", result_handle);
1812 ok(err == ERROR_SUCCESS, "tr2_sys__Open_dir(): expect: ERROR_SUCCESS, got %d\n", err);
1813 ok(type == status_unknown, "tr2_sys__Open_dir(): expect: status_unknown, got %d\n", type);
1814 ok(!*first_file_name, "tr2_sys__Open_dir(): expect: 0, got %s\n", first_file_name);
1815 p_tr2_sys__Close_dir(result_handle);
1816 ok(result_handle == NULL, "tr2_sys__Open_dir(): expect: NULL, got %p\n", result_handle);
1818 ok(RemoveDirectoryA("empty_dir"), "expect empty_dir to exist\n");
1819 ok(DeleteFileA("tr2_test_dir/sub_dir/sub_f1"), "expect tr2_test_dir/sub_dir/sub_f1 to exist\n");
1820 ok(RemoveDirectoryA("tr2_test_dir/sub_dir"), "expect tr2_test_dir/sub_dir to exist\n");
1821 ok(DeleteFileA("tr2_test_dir/f1"), "expect tr2_test_dir/f1 to exist\n");
1822 ok(DeleteFileA("tr2_test_dir/f2"), "expect tr2_test_dir/f2 to exist\n");
1823 ok(RemoveDirectoryA("tr2_test_dir"), "expect tr2_test_dir to exist\n");
1826 static void test_tr2_sys__Link(void)
1828 int ret, i;
1829 HANDLE file, h1, h2;
1830 BY_HANDLE_FILE_INFORMATION info1, info2;
1831 char temp_path[MAX_PATH], current_path[MAX_PATH];
1832 LARGE_INTEGER file_size;
1833 struct {
1834 char const *existing_path;
1835 char const *new_path;
1836 MSVCP_bool fail_if_exists;
1837 int last_error;
1838 } tests[] = {
1839 { "f1", "f1_link", TRUE, ERROR_SUCCESS },
1840 { "f1", "tr2_test_dir\\f1_link", TRUE, ERROR_SUCCESS },
1841 { "tr2_test_dir\\f1_link", "tr2_test_dir\\f1_link_link", TRUE, ERROR_SUCCESS },
1842 { "tr2_test_dir", "dir_link", TRUE, ERROR_ACCESS_DENIED },
1843 { NULL, "NULL_link", TRUE, ERROR_INVALID_PARAMETER },
1844 { "f1", NULL, TRUE, ERROR_INVALID_PARAMETER },
1845 { "not_exist", "not_exist_link", TRUE, ERROR_FILE_NOT_FOUND },
1846 { "f1", "not_exist_dir\\f1_link", TRUE, ERROR_PATH_NOT_FOUND }
1849 GetCurrentDirectoryA(MAX_PATH, current_path);
1850 GetTempPathA(MAX_PATH, temp_path);
1851 ok(SetCurrentDirectoryA(temp_path), "SetCurrentDirectoryA to temp_path failed\n");
1853 ret = p_tr2_sys__Make_dir("tr2_test_dir");
1854 ok(ret == 1, "test_tr2_sys__Make_dir(): expect 1 got %d\n", ret);
1855 file = CreateFileA("f1", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
1856 ok(file != INVALID_HANDLE_VALUE, "create file failed: INVALID_HANDLE_VALUE\n");
1857 file_size.QuadPart = 7;
1858 ok(SetFilePointerEx(file, file_size, NULL, FILE_BEGIN), "SetFilePointerEx failed\n");
1859 ok(SetEndOfFile(file), "SetEndOfFile failed\n");
1860 CloseHandle(file);
1862 for(i=0; i<ARRAY_SIZE(tests); i++) {
1863 errno = 0xdeadbeef;
1864 ret = p_tr2_sys__Link(tests[i].existing_path, tests[i].new_path);
1865 ok(ret == tests[i].last_error, "tr2_sys__Link(): test %d expect: %d, got %d\n",
1866 i+1, tests[i].last_error, ret);
1867 ok(errno == 0xdeadbeef, "tr2_sys__Link(): test %d errno expect 0xdeadbeef, got %d\n", i+1, errno);
1868 if(ret == ERROR_SUCCESS)
1869 ok(p_tr2_sys__File_size(tests[i].existing_path) == p_tr2_sys__File_size(tests[i].new_path),
1870 "tr2_sys__Link(): test %d failed, mismatched file sizes\n", i+1);
1873 ok(DeleteFileA("f1"), "expect f1 to exist\n");
1874 ok(p_tr2_sys__File_size("f1_link") == p_tr2_sys__File_size("tr2_test_dir/f1_link") &&
1875 p_tr2_sys__File_size("tr2_test_dir/f1_link") == p_tr2_sys__File_size("tr2_test_dir/f1_link_link"),
1876 "tr2_sys__Link(): expect links' size are equal, got %s\n", wine_dbgstr_longlong(p_tr2_sys__File_size("tr2_test_dir/f1_link_link")));
1877 ok(p_tr2_sys__File_size("f1_link") == 7, "tr2_sys__Link(): expect f1_link's size equals to 7, got %s\n", wine_dbgstr_longlong(p_tr2_sys__File_size("f1_link")));
1879 file = CreateFileA("f1_link", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
1880 ok(file != INVALID_HANDLE_VALUE, "create file failed: INVALID_HANDLE_VALUE\n");
1881 file_size.QuadPart = 20;
1882 ok(SetFilePointerEx(file, file_size, NULL, FILE_BEGIN), "SetFilePointerEx failed\n");
1883 ok(SetEndOfFile(file), "SetEndOfFile failed\n");
1884 CloseHandle(file);
1885 h1 = CreateFileA("f1_link", 0, FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE,
1886 NULL, OPEN_EXISTING, 0, 0);
1887 ok(h1 != INVALID_HANDLE_VALUE, "create file failed: INVALID_HANDLE_VALUE\n");
1888 ok(GetFileInformationByHandle(h1, &info1), "GetFileInformationByHandle failed\n");
1889 CloseHandle(h1);
1890 h2 = CreateFileA("tr2_test_dir/f1_link", 0, FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE,
1891 NULL, OPEN_EXISTING, 0, 0);
1892 ok(h2 != INVALID_HANDLE_VALUE, "create file failed: INVALID_HANDLE_VALUE\n");
1893 ok(GetFileInformationByHandle(h2, &info2), "GetFileInformationByHandle failed\n");
1894 CloseHandle(h2);
1895 ok(info1.nFileIndexHigh == info2.nFileIndexHigh
1896 && info1.nFileIndexLow == info2.nFileIndexLow,
1897 "tr2_sys__Link(): test %d expect two files equivalent\n", i+1);
1898 ok(p_tr2_sys__File_size("f1_link") == 20, "tr2_sys__Link(): expect f1_link's size equals to 20, got %s\n", wine_dbgstr_longlong(p_tr2_sys__File_size("f1_link")));
1900 ok(DeleteFileA("f1_link"), "expect f1_link to exist\n");
1901 ok(DeleteFileA("tr2_test_dir/f1_link"), "expect tr2_test_dir/f1_link to exist\n");
1902 ok(DeleteFileA("tr2_test_dir/f1_link_link"), "expect tr2_test_dir/f1_link_link to exist\n");
1903 ret = p_tr2_sys__Remove_dir("tr2_test_dir");
1904 ok(ret == 1, "tr2_sys__Remove_dir(): expect 1 got %d\n", ret);
1905 ok(SetCurrentDirectoryA(current_path), "SetCurrentDirectoryA failed\n");
1908 static void test_tr2_sys__Symlink(void)
1910 int ret, i;
1911 HANDLE file;
1912 LARGE_INTEGER file_size;
1913 struct {
1914 char const *existing_path;
1915 char const *new_path;
1916 int last_error;
1917 MSVCP_bool is_todo;
1918 } tests[] = {
1919 { "f1", "f1_link", ERROR_SUCCESS, FALSE },
1920 { "f1", "tr2_test_dir\\f1_link", ERROR_SUCCESS, FALSE },
1921 { "tr2_test_dir\\f1_link", "tr2_test_dir\\f1_link_link", ERROR_SUCCESS, FALSE },
1922 { "tr2_test_dir", "dir_link", ERROR_SUCCESS, FALSE },
1923 { NULL, "NULL_link", ERROR_INVALID_PARAMETER, FALSE },
1924 { "f1", NULL, ERROR_INVALID_PARAMETER, FALSE },
1925 { "not_exist", "not_exist_link", ERROR_SUCCESS, FALSE },
1926 { "f1", "not_exist_dir\\f1_link", ERROR_PATH_NOT_FOUND, TRUE }
1929 ret = p_tr2_sys__Make_dir("tr2_test_dir");
1930 ok(ret == 1, "test_tr2_sys__Make_dir(): expect 1 got %d\n", ret);
1931 file = CreateFileA("f1", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
1932 ok(file != INVALID_HANDLE_VALUE, "create file failed: INVALID_HANDLE_VALUE\n");
1933 file_size.QuadPart = 7;
1934 ok(SetFilePointerEx(file, file_size, NULL, FILE_BEGIN), "SetFilePointerEx failed\n");
1935 ok(SetEndOfFile(file), "SetEndOfFile failed\n");
1936 CloseHandle(file);
1938 for(i=0; i<ARRAY_SIZE(tests); i++) {
1939 errno = 0xdeadbeef;
1940 SetLastError(0xdeadbeef);
1941 ret = p_tr2_sys__Symlink(tests[i].existing_path, tests[i].new_path);
1942 if(!i && (ret==ERROR_PRIVILEGE_NOT_HELD || ret==ERROR_INVALID_FUNCTION || ret==ERROR_CALL_NOT_IMPLEMENTED)) {
1943 win_skip("Privilege not held or symbolic link not supported, skipping symbolic link tests.\n");
1944 ok(DeleteFileA("f1"), "expect f1 to exist\n");
1945 ret = p_tr2_sys__Remove_dir("tr2_test_dir");
1946 ok(ret == 1, "tr2_sys__Remove_dir(): expect 1 got %d\n", ret);
1947 return;
1950 ok(errno == 0xdeadbeef, "tr2_sys__Symlink(): test %d errno expect 0xdeadbeef, got %d\n", i+1, errno);
1951 todo_wine_if(tests[i].is_todo)
1952 ok(ret == tests[i].last_error, "tr2_sys__Symlink(): test %d expect: %d, got %d\n", i+1, tests[i].last_error, ret);
1953 if(ret == ERROR_SUCCESS)
1954 ok(p_tr2_sys__File_size(tests[i].new_path) == 0, "tr2_sys__Symlink(): expect 0, got %s\n", wine_dbgstr_longlong(p_tr2_sys__File_size(tests[i].new_path)));
1957 ok(DeleteFileA("f1"), "expect f1 to exist\n");
1958 todo_wine ok(DeleteFileA("f1_link"), "expect f1_link to exist\n");
1959 todo_wine ok(DeleteFileA("tr2_test_dir/f1_link"), "expect tr2_test_dir/f1_link to exist\n");
1960 todo_wine ok(DeleteFileA("tr2_test_dir/f1_link_link"), "expect tr2_test_dir/f1_link_link to exist\n");
1961 todo_wine ok(DeleteFileA("not_exist_link"), "expect not_exist_link to exist\n");
1962 todo_wine ok(DeleteFileA("dir_link"), "expect dir_link to exist\n");
1963 ret = p_tr2_sys__Remove_dir("tr2_test_dir");
1964 ok(ret == 1, "tr2_sys__Remove_dir(): expect 1 got %d\n", ret);
1967 static void test_tr2_sys__Unlink(void)
1969 char temp_path[MAX_PATH], current_path[MAX_PATH];
1970 int ret, i;
1971 HANDLE file;
1972 LARGE_INTEGER file_size;
1973 struct {
1974 char const *path;
1975 int last_error;
1976 MSVCP_bool is_todo;
1977 } tests[] = {
1978 { "tr2_test_dir\\f1_symlink", ERROR_SUCCESS, TRUE },
1979 { "tr2_test_dir\\f1_link", ERROR_SUCCESS, FALSE },
1980 { "tr2_test_dir\\f1", ERROR_SUCCESS, FALSE },
1981 { "tr2_test_dir", ERROR_ACCESS_DENIED, FALSE },
1982 { "not_exist", ERROR_FILE_NOT_FOUND, FALSE },
1983 { "not_exist_dir\\not_exist_file", ERROR_PATH_NOT_FOUND, FALSE },
1984 { NULL, ERROR_PATH_NOT_FOUND, FALSE }
1987 GetCurrentDirectoryA(MAX_PATH, current_path);
1988 GetTempPathA(MAX_PATH, temp_path);
1989 ok(SetCurrentDirectoryA(temp_path), "SetCurrentDirectoryA to temp_path failed\n");
1991 ret = p_tr2_sys__Make_dir("tr2_test_dir");
1992 ok(ret == 1, "tr2_sys__Make_dir(): expect 1 got %d\n", ret);
1993 file = CreateFileA("tr2_test_dir/f1", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
1994 ok(file != INVALID_HANDLE_VALUE, "create file failed: INVALID_HANDLE_VALUE\n");
1995 file_size.QuadPart = 7;
1996 ok(SetFilePointerEx(file, file_size, NULL, FILE_BEGIN), "SetFilePointerEx failed\n");
1997 ok(SetEndOfFile(file), "SetEndOfFile failed\n");
1998 CloseHandle(file);
2000 ret = p_tr2_sys__Symlink("tr2_test_dir/f1", "tr2_test_dir/f1_symlink");
2001 if(ret==ERROR_PRIVILEGE_NOT_HELD || ret==ERROR_INVALID_FUNCTION || ret==ERROR_CALL_NOT_IMPLEMENTED) {
2002 tests[0].last_error = ERROR_FILE_NOT_FOUND;
2003 win_skip("Privilege not held or symbolic link not supported, skipping symbolic link tests.\n");
2004 }else {
2005 ok(ret == ERROR_SUCCESS, "tr2_sys__Symlink(): expect: ERROR_SUCCESS, got %d\n", ret);
2007 ret = p_tr2_sys__Link("tr2_test_dir/f1", "tr2_test_dir/f1_link");
2008 ok(ret == ERROR_SUCCESS, "tr2_sys__Link(): expect: ERROR_SUCCESS, got %d\n", ret);
2010 for(i=0; i<ARRAY_SIZE(tests); i++) {
2011 errno = 0xdeadbeef;
2012 ret = p_tr2_sys__Unlink(tests[i].path);
2013 todo_wine_if(tests[i].is_todo)
2014 ok(ret == tests[i].last_error, "tr2_sys__Unlink(): test %d expect: %d, got %d\n",
2015 i+1, tests[i].last_error, ret);
2016 ok(errno == 0xdeadbeef, "tr2_sys__Unlink(): test %d errno expect: 0xdeadbeef, got %d\n", i+1, ret);
2019 ok(!DeleteFileA("tr2_test_dir/f1"), "expect tr2_test_dir/f1 not to exist\n");
2020 ok(!DeleteFileA("tr2_test_dir/f1_link"), "expect tr2_test_dir/f1_link not to exist\n");
2021 ok(!DeleteFileA("tr2_test_dir/f1_symlink"), "expect tr2_test_dir/f1_symlink not to exist\n");
2022 ret = p_tr2_sys__Remove_dir("tr2_test_dir");
2023 ok(ret == 1, "tr2_sys__Remove_dir(): expect 1 got %d\n", ret);
2025 ok(SetCurrentDirectoryA(current_path), "SetCurrentDirectoryA failed\n");
2028 static int __cdecl thrd_thread(void *arg)
2030 _Thrd_t *thr = arg;
2032 if(thr)
2033 *thr = p__Thrd_current();
2034 return 0x42;
2037 static void test_thrd(void)
2039 int ret, i, r;
2040 struct test {
2041 _Thrd_t a;
2042 _Thrd_t b;
2043 int r;
2045 const HANDLE hnd1 = (HANDLE)0xcccccccc;
2046 const HANDLE hnd2 = (HANDLE)0xdeadbeef;
2047 xtime xt, before, after;
2048 MSVCRT_long diff;
2049 _Thrd_t ta, tb;
2051 struct test testeq[] = {
2052 { {0, 0}, {0, 0}, 1 },
2053 { {0, 1}, {0, 0}, 0 },
2054 { {hnd1, 0}, {hnd1, 1}, 0 },
2055 { {hnd1, 0}, {hnd2, 0}, 1 }
2058 struct test testlt[] = {
2059 { {0, 0}, {0, 0}, 0 },
2060 { {0, 0}, {0, 1}, 1 },
2061 { {0, 1}, {0, 0}, 0 },
2062 { {hnd1, 0}, {hnd2, 0}, 0 },
2063 { {hnd1, 0}, {hnd2, 1}, 1 }
2066 /* test for equal */
2067 for(i=0; i<ARRAY_SIZE(testeq); i++) {
2068 ret = p__Thrd_equal(testeq[i].a, testeq[i].b);
2069 ok(ret == testeq[i].r, "(%p %u) = (%p %u) expected %d, got %d\n",
2070 testeq[i].a.hnd, testeq[i].a.id, testeq[i].b.hnd, testeq[i].b.id, testeq[i].r, ret);
2073 /* test for less than */
2074 for(i=0; i<ARRAY_SIZE(testlt); i++) {
2075 ret = p__Thrd_lt(testlt[i].a, testlt[i].b);
2076 ok(ret == testlt[i].r, "(%p %u) < (%p %u) expected %d, got %d\n",
2077 testlt[i].a.hnd, testlt[i].a.id, testlt[i].b.hnd, testlt[i].b.id, testlt[i].r, ret);
2080 /* test for sleep */
2081 if (0) /* crash on Windows */
2082 p__Thrd_sleep(NULL);
2083 p_xtime_get(&xt, 1);
2084 xt.sec += 2;
2085 p_xtime_get(&before, 1);
2086 p__Thrd_sleep(&xt);
2087 p_xtime_get(&after, 1);
2088 diff = p__Xtime_diff_to_millis2(&after, &before);
2089 ok(diff > 2000 - TIMEDELTA, "got %d\n", diff);
2091 /* test for current */
2092 ta = p__Thrd_current();
2093 tb = p__Thrd_current();
2094 ok(ta.id == tb.id, "got a %d b %d\n", ta.id, tb.id);
2095 ok(ta.id == GetCurrentThreadId(), "expected %d, got %d\n", GetCurrentThreadId(), ta.id);
2096 /* these can be different if new threads are created at same time */
2097 ok(ta.hnd == tb.hnd, "got a %p b %p\n", ta.hnd, tb.hnd);
2098 ok(!CloseHandle(ta.hnd), "handle %p not closed\n", ta.hnd);
2099 ok(!CloseHandle(tb.hnd), "handle %p not closed\n", tb.hnd);
2101 /* test for create/join */
2102 if (0) /* crash on Windows */
2104 p__Thrd_create(NULL, thrd_thread, NULL);
2105 p__Thrd_create(&ta, NULL, NULL);
2107 r = -1;
2108 ret = p__Thrd_create(&ta, thrd_thread, (void*)&tb);
2109 ok(!ret, "failed to create thread, got %d\n", ret);
2110 ret = p__Thrd_join(ta, &r);
2111 ok(!ret, "failed to join thread, got %d\n", ret);
2112 ok(ta.id == tb.id, "expected %d, got %d\n", ta.id, tb.id);
2113 ok(ta.hnd != tb.hnd, "same handles, got %p\n", ta.hnd);
2114 ok(r == 0x42, "expected 0x42, got %d\n", r);
2115 ret = p__Thrd_detach(ta);
2116 ok(ret == 4, "_Thrd_detach should have failed with error 4, got %d\n", ret);
2118 ret = p__Thrd_create(&ta, thrd_thread, NULL);
2119 ok(!ret, "failed to create thread, got %d\n", ret);
2120 ret = p__Thrd_detach(ta);
2121 ok(!ret, "_Thrd_detach failed, got %d\n", ret);
2125 #define NUM_THREADS 10
2126 struct cndmtx
2128 HANDLE initialized;
2129 int started;
2130 int thread_no;
2132 _Cnd_t cnd;
2133 _Mtx_t mtx;
2134 BOOL timed_wait;
2137 static int __cdecl cnd_wait_thread(void *arg)
2139 struct cndmtx *cm = arg;
2140 int r;
2142 p__Mtx_lock(&cm->mtx);
2144 if(InterlockedIncrement(&cm->started) == cm->thread_no)
2145 SetEvent(cm->initialized);
2147 if(cm->timed_wait) {
2148 xtime xt;
2150 p_xtime_get(&xt, 1);
2151 xt.sec += 2;
2152 r = p__Cnd_timedwait(&cm->cnd, &cm->mtx, &xt);
2153 ok(!r, "timed wait failed\n");
2154 } else {
2155 r = p__Cnd_wait(&cm->cnd, &cm->mtx);
2156 ok(!r, "wait failed\n");
2159 p__Mtx_unlock(&cm->mtx);
2160 return 0;
2163 static void test_cnd(void)
2165 _Thrd_t threads[NUM_THREADS];
2166 xtime xt, before, after;
2167 MSVCRT_long diff;
2168 struct cndmtx cm;
2169 _Cnd_t cnd;
2170 _Mtx_t mtx;
2171 int r, i;
2173 r = p__Cnd_init(&cnd);
2174 ok(!r, "failed to init cnd\n");
2176 r = p__Mtx_init(&mtx, 0);
2177 ok(!r, "failed to init mtx\n");
2179 if (0) /* crash on Windows */
2181 p__Cnd_init(NULL);
2182 p__Cnd_wait(NULL, &mtx);
2183 p__Cnd_wait(&cnd, NULL);
2184 p__Cnd_timedwait(NULL, &mtx, &xt);
2185 p__Cnd_timedwait(&cnd, &mtx, &xt);
2187 p__Cnd_destroy(NULL);
2189 /* test _Cnd_signal/_Cnd_wait */
2190 cm.initialized = CreateEventW(NULL, FALSE, FALSE, NULL);
2191 cm.started = 0;
2192 cm.thread_no = 1;
2193 cm.cnd = cnd;
2194 cm.mtx = mtx;
2195 cm.timed_wait = FALSE;
2196 p__Thrd_create(&threads[0], cnd_wait_thread, (void*)&cm);
2198 WaitForSingleObject(cm.initialized, INFINITE);
2199 p__Mtx_lock(&mtx);
2200 p__Mtx_unlock(&mtx);
2202 r = p__Cnd_signal(&cm.cnd);
2203 ok(!r, "failed to signal\n");
2204 p__Thrd_join(threads[0], NULL);
2206 /* test _Cnd_timedwait time out */
2207 p__Mtx_lock(&mtx);
2208 p_xtime_get(&before, 1);
2209 xt = before;
2210 xt.sec += 1;
2211 r = p__Cnd_timedwait(&cnd, &mtx, &xt);
2212 p_xtime_get(&after, 1);
2213 p__Mtx_unlock(&mtx);
2215 diff = p__Xtime_diff_to_millis2(&after, &before);
2216 ok(r == 2, "should have timed out\n");
2217 ok(diff > 1000 - TIMEDELTA, "got %d\n", diff);
2219 /* test _Cnd_timedwait */
2220 cm.started = 0;
2221 cm.timed_wait = TRUE;
2222 p__Thrd_create(&threads[0], cnd_wait_thread, (void*)&cm);
2224 WaitForSingleObject(cm.initialized, INFINITE);
2225 p__Mtx_lock(&mtx);
2226 p__Mtx_unlock(&mtx);
2228 r = p__Cnd_signal(&cm.cnd);
2229 ok(!r, "failed to signal\n");
2230 p__Thrd_join(threads[0], NULL);
2232 /* test _Cnd_do_broadcast_at_thread_exit */
2233 cm.started = 0;
2234 cm.timed_wait = FALSE;
2235 p__Thrd_create(&threads[0], cnd_wait_thread, (void*)&cm);
2237 WaitForSingleObject(cm.initialized, INFINITE);
2238 p__Mtx_lock(&mtx);
2240 r = 0xcafe;
2241 p__Cnd_unregister_at_thread_exit((_Mtx_t*)0xdeadbeef);
2242 p__Cnd_register_at_thread_exit(&cnd, &mtx, &r);
2243 ok(r == 0xcafe, "r = %x\n", r);
2244 p__Cnd_register_at_thread_exit(&cnd, &mtx, &r);
2245 p__Cnd_unregister_at_thread_exit(&mtx);
2246 p__Cnd_do_broadcast_at_thread_exit();
2247 ok(mtx->count == 1, "mtx.count = %d\n", mtx->count);
2249 p__Cnd_register_at_thread_exit(&cnd, &mtx, &r);
2250 ok(r == 0xcafe, "r = %x\n", r);
2252 p__Cnd_do_broadcast_at_thread_exit();
2253 ok(r == 1, "r = %x\n", r);
2254 p__Thrd_join(threads[0], NULL);
2256 /* crash if _Cnd_do_broadcast_at_thread_exit is called on exit */
2257 p__Cnd_register_at_thread_exit((_Cnd_t*)0xdeadbeef, (_Mtx_t*)0xdeadbeef, (int*)0xdeadbeef);
2259 /* test _Cnd_broadcast */
2260 cm.started = 0;
2261 cm.thread_no = NUM_THREADS;
2263 for(i = 0; i < cm.thread_no; i++)
2264 p__Thrd_create(&threads[i], cnd_wait_thread, (void*)&cm);
2266 WaitForSingleObject(cm.initialized, INFINITE);
2267 p__Mtx_lock(&mtx);
2268 p__Mtx_unlock(&mtx);
2270 r = p__Cnd_broadcast(&cnd);
2271 ok(!r, "failed to broadcast\n");
2272 for(i = 0; i < cm.thread_no; i++)
2273 p__Thrd_join(threads[i], NULL);
2275 /* test broadcast with _Cnd_destroy */
2276 cm.started = 0;
2277 for(i = 0; i < cm.thread_no; i++)
2278 p__Thrd_create(&threads[i], cnd_wait_thread, (void*)&cm);
2280 WaitForSingleObject(cm.initialized, INFINITE);
2281 p__Mtx_lock(&mtx);
2282 p__Mtx_unlock(&mtx);
2284 p__Cnd_destroy(&cnd);
2285 for(i = 0; i < cm.thread_no; i++)
2286 p__Thrd_join(threads[i], NULL);
2288 p__Mtx_destroy(&mtx);
2289 CloseHandle(cm.initialized);
2292 static struct {
2293 int value[2];
2294 const char* export_name;
2295 } vbtable_size_exports_list[] = {
2296 {{0x20, 0x20}, "??_8?$basic_iostream@DU?$char_traits@D@std@@@std@@7B?$basic_istream@DU?$char_traits@D@std@@@1@@"},
2297 {{0x10, 0x10}, "??_8?$basic_iostream@DU?$char_traits@D@std@@@std@@7B?$basic_ostream@DU?$char_traits@D@std@@@1@@"},
2298 {{0x20, 0x20}, "??_8?$basic_iostream@GU?$char_traits@G@std@@@std@@7B?$basic_istream@GU?$char_traits@G@std@@@1@@"},
2299 {{0x10, 0x10}, "??_8?$basic_iostream@GU?$char_traits@G@std@@@std@@7B?$basic_ostream@GU?$char_traits@G@std@@@1@@"},
2300 {{0x20, 0x20}, "??_8?$basic_iostream@_WU?$char_traits@_W@std@@@std@@7B?$basic_istream@_WU?$char_traits@_W@std@@@1@@"},
2301 {{0x10, 0x10}, "??_8?$basic_iostream@_WU?$char_traits@_W@std@@@std@@7B?$basic_ostream@_WU?$char_traits@_W@std@@@1@@"},
2302 {{0x18, 0x18}, "??_8?$basic_istream@DU?$char_traits@D@std@@@std@@7B@"},
2303 {{0x18, 0x18}, "??_8?$basic_istream@GU?$char_traits@G@std@@@std@@7B@"},
2304 {{0x18, 0x18}, "??_8?$basic_istream@_WU?$char_traits@_W@std@@@std@@7B@"},
2305 {{ 0x8, 0x10}, "??_8?$basic_ostream@DU?$char_traits@D@std@@@std@@7B@"},
2306 {{ 0x8, 0x10}, "??_8?$basic_ostream@GU?$char_traits@G@std@@@std@@7B@"},
2307 {{ 0x8, 0x10}, "??_8?$basic_ostream@_WU?$char_traits@_W@std@@@std@@7B@"},
2308 {{ 0x0, 0x0}, 0}
2311 static void test_vbtable_size_exports(void)
2313 int i;
2314 const int *p_vbtable;
2315 int arch_idx = (sizeof(void*) == 8);
2317 for (i = 0; vbtable_size_exports_list[i].export_name; i++)
2319 SET(p_vbtable, vbtable_size_exports_list[i].export_name);
2321 ok(p_vbtable[0] == 0, "vbtable[0] wrong, got 0x%x\n", p_vbtable[0]);
2322 ok(p_vbtable[1] == vbtable_size_exports_list[i].value[arch_idx],
2323 "%d: %s[1] wrong, got 0x%x\n", i, vbtable_size_exports_list[i].export_name, p_vbtable[1]);
2327 HANDLE _Pad__Launch_returned;
2328 _Pad pad;
2329 #ifdef __i386__
2330 /* TODO: this should be a __thiscall function */
2331 static unsigned int __stdcall vtbl_func__Go(void)
2332 #else
2333 static unsigned int __cdecl vtbl_func__Go(_Pad *this)
2334 #endif
2336 DWORD ret;
2338 ret = WaitForSingleObject(_Pad__Launch_returned, 100);
2339 ok(ret == WAIT_TIMEOUT, "WiatForSingleObject returned %x\n", ret);
2340 ok(!pad.mtx->count, "pad.mtx.count = %d\n", pad.mtx->count);
2341 ok(!pad.launched, "pad.launched = %x\n", pad.launched);
2342 call_func1(p__Pad__Release, &pad);
2343 ok(pad.launched, "pad.launched = %x\n", pad.launched);
2344 ret = WaitForSingleObject(_Pad__Launch_returned, 100);
2345 ok(ret == WAIT_OBJECT_0, "WiatForSingleObject returned %x\n", ret);
2346 ok(pad.mtx->count == 1, "pad.mtx.count = %d\n", pad.mtx->count);
2347 return 0;
2350 static void test__Pad(void)
2352 _Pad pad_copy;
2353 _Thrd_t thrd;
2354 vtable_ptr pfunc = (vtable_ptr)&vtbl_func__Go;
2356 _Pad__Launch_returned = CreateEventW(NULL, FALSE, FALSE, NULL);
2358 pad.vtable = (void*)1;
2359 pad.cnd = (void*)2;
2360 pad.mtx = (void*)3;
2361 pad.launched = TRUE;
2362 memset(&pad_copy, 0, sizeof(pad_copy));
2363 call_func2(p__Pad_copy_ctor, &pad_copy, &pad);
2364 ok(pad_copy.vtable != (void*)1, "pad_copy.vtable was not set\n");
2365 ok(pad_copy.cnd == (void*)2, "pad_copy.cnd = %p\n", pad_copy.cnd);
2366 ok(pad_copy.mtx == (void*)3, "pad_copy.mtx = %p\n", pad_copy.mtx);
2367 ok(pad_copy.launched, "pad_copy.launched = %x\n", pad_copy.launched);
2369 memset(&pad_copy, 0xde, sizeof(pad_copy));
2370 pad_copy.vtable = (void*)4;
2371 pad_copy.cnd = (void*)5;
2372 pad_copy.mtx = (void*)6;
2373 pad_copy.launched = FALSE;
2374 call_func2(p__Pad_op_assign, &pad_copy, &pad);
2375 ok(pad_copy.vtable == (void*)4, "pad_copy.vtable was set\n");
2376 ok(pad_copy.cnd == (void*)2, "pad_copy.cnd = %p\n", pad_copy.cnd);
2377 ok(pad_copy.mtx == (void*)3, "pad_copy.mtx = %p\n", pad_copy.mtx);
2378 ok(pad_copy.launched, "pad_copy.launched = %x\n", pad_copy.launched);
2380 call_func1(p__Pad_ctor, &pad);
2381 call_func2(p__Pad_copy_ctor, &pad_copy, &pad);
2382 ok(pad.vtable == pad_copy.vtable, "pad.vtable = %p, pad_copy.vtable = %p\n", pad.vtable, pad_copy.vtable);
2383 ok(pad.cnd == pad_copy.cnd, "pad.cnd = %p, pad_copy.cnd = %p\n", pad.cnd, pad_copy.cnd);
2384 ok(pad.mtx == pad_copy.mtx, "pad.mtx = %p, pad_copy.mtx = %p\n", pad.mtx, pad_copy.mtx);
2385 ok(pad.launched == pad_copy.launched, "pad.launched = %x, pad_copy.launched = %x\n", pad.launched, pad_copy.launched);
2386 call_func1(p__Pad_dtor, &pad);
2387 /* call_func1(p__Pad_dtor, &pad_copy); - copy constructor is broken, this causes a crash */
2389 memset(&pad, 0xfe, sizeof(pad));
2390 call_func1(p__Pad_ctor, &pad);
2391 ok(!pad.launched, "pad.launched = %x\n", pad.launched);
2392 ok(pad.mtx->count == 1, "pad.mtx.count = %d\n", pad.mtx->count);
2394 pad.vtable = &pfunc;
2395 call_func2(p__Pad__Launch, &pad, &thrd);
2396 SetEvent(_Pad__Launch_returned);
2397 ok(!p__Thrd_join(thrd, NULL), "_Thrd_join failed\n");
2399 call_func1(p__Pad_dtor, &pad);
2400 CloseHandle(_Pad__Launch_returned);
2403 static void test__Mtx(void)
2406 static int flags[] =
2408 0, MTX_PLAIN, MTX_TRY, MTX_TIMED, MTX_RECURSIVE,
2409 MTX_PLAIN|MTX_TRY, MTX_PLAIN|MTX_RECURSIVE, MTX_PLAIN|0xbeef
2411 _Mtx_t mtx;
2412 int i, r, expect;
2414 for (i=0; i<ARRAY_SIZE(flags); i++)
2416 if (flags[i] == MTX_PLAIN || flags[i] & MTX_RECURSIVE)
2417 expect = 0;
2418 else
2419 expect = 3;
2421 r = p__Mtx_init(&mtx, flags[i]);
2422 ok(!r, "failed to init mtx (flags %x)\n", flags[i]);
2424 r = p__Mtx_trylock(&mtx);
2425 ok(!r, "_Mtx_trylock returned %x (flags %x)\n", r, flags[i]);
2426 r = p__Mtx_trylock(&mtx);
2427 ok(r == expect, "_Mtx_trylock returned %x (flags %x)\n", r, flags[i]);
2428 if(!r) p__Mtx_unlock(&mtx);
2430 r = p__Mtx_lock(&mtx);
2431 ok(r == expect, "_Mtx_lock returned %x (flags %x)\n", r, flags[i]);
2432 if(!r) p__Mtx_unlock(&mtx);
2434 p__Mtx_unlock(&mtx);
2435 p__Mtx_destroy(&mtx);
2439 static void test_threads__Mtx(void)
2441 void *mtx = NULL;
2443 p_threads__Mtx_new(&mtx);
2444 ok(mtx != NULL, "mtx == NULL\n");
2446 p_threads__Mtx_lock(mtx);
2447 p_threads__Mtx_lock(mtx);
2448 p_threads__Mtx_unlock(mtx);
2449 p_threads__Mtx_unlock(mtx);
2450 p_threads__Mtx_unlock(mtx);
2452 p_threads__Mtx_delete(mtx);
2455 static void test_vector_base_v4__Segment_index_of(void)
2457 size_t i;
2458 size_t ret;
2459 struct {
2460 size_t x;
2461 size_t expect;
2462 } tests[] = {
2463 {0, 0},
2464 {1, 0},
2465 {2, 1},
2466 {3, 1},
2467 {4, 2},
2468 {7, 2},
2469 {8, 3},
2470 {15, 3},
2471 {16, 4},
2472 {31, 4},
2473 {32, 5},
2474 {~0, 8*sizeof(void*)-1}
2477 for(i=0; i<ARRAY_SIZE(tests); i++) {
2478 ret = p_vector_base_v4__Segment_index_of(tests[i].x);
2479 ok(ret == tests[i].expect, "expected %ld, got %ld for %ld\n",
2480 (long)tests[i].expect, (long)ret, (long)tests[i].x);
2484 static HANDLE block_start, block_end;
2485 static BOOL block;
2487 static void __thiscall queue_char__Move_item(
2488 #ifndef __i386__
2489 queue_base_v4 *this,
2490 #endif
2491 _Page *dst, size_t idx, void *src)
2493 CHECK_EXPECT(queue_char__Move_item);
2494 if(block) {
2495 block = FALSE;
2496 SetEvent(block_start);
2497 WaitForSingleObject(block_end, INFINITE);
2499 memcpy(dst->data + idx, src, sizeof(char));
2502 static void __thiscall queue_char__Copy_item(
2503 #ifndef __i386__
2504 queue_base_v4 *this,
2505 #endif
2506 _Page *dst, size_t idx, const void *src)
2508 CHECK_EXPECT(queue_char__Copy_item);
2509 if(block) {
2510 block = FALSE;
2511 SetEvent(block_start);
2512 WaitForSingleObject(block_end, INFINITE);
2514 memcpy(dst->data + idx, src, sizeof(char));
2517 static void __thiscall queue_char__Assign_and_destroy_item(
2518 #ifndef __i386__
2519 queue_base_v4 *this,
2520 #endif
2521 void *dst, _Page *src, size_t idx)
2523 CHECK_EXPECT(queue_char__Assign_and_destroy_item);
2524 if(block) {
2525 block = FALSE;
2526 SetEvent(block_start);
2527 WaitForSingleObject(block_end, INFINITE);
2529 memcpy(dst, src->data + idx, sizeof(char));
2532 #ifndef __i386__
2533 static _Page* __thiscall queue_char__Allocate_page(queue_base_v4 *this)
2534 #else
2535 static _Page* __thiscall queue_char__Allocate_page(void)
2536 #endif
2538 CHECK_EXPECT(queue_char__Allocate_page);
2539 return malloc(sizeof(_Page) + sizeof(char[256]));
2542 static void __thiscall queue_char__Deallocate_page(
2543 #ifndef __i386__
2544 queue_base_v4 *this,
2545 #endif
2546 _Page *page)
2548 CHECK_EXPECT2(queue_char__Deallocate_page);
2549 free(page);
2552 static const void* queue_char_vtbl[] =
2554 queue_char__Move_item,
2555 queue_char__Copy_item,
2556 queue_char__Assign_and_destroy_item,
2557 NULL, /* dtor */
2558 queue_char__Allocate_page,
2559 queue_char__Deallocate_page
2562 static DWORD WINAPI queue_move_push_thread(void *arg)
2564 queue_base_v4 *queue = arg;
2565 char c = 'm';
2567 alloc_expect_struct();
2568 SET_EXPECT(queue_char__Allocate_page); /* ignore page allocations */
2569 SET_EXPECT(queue_char__Move_item);
2570 call_func2(p_queue_base_v4__Internal_move_push, queue, &c);
2571 CHECK_CALLED(queue_char__Move_item);
2572 free_expect_struct();
2573 return 0;
2576 static DWORD WINAPI queue_push_thread(void *arg)
2578 queue_base_v4 *queue = arg;
2579 char c = 'c';
2581 alloc_expect_struct();
2582 SET_EXPECT(queue_char__Copy_item);
2583 call_func2(p_queue_base_v4__Internal_push, queue, &c);
2584 CHECK_CALLED(queue_char__Copy_item);
2585 free_expect_struct();
2586 return 0;
2589 static DWORD WINAPI queue_pop_thread(void*arg)
2591 queue_base_v4 *queue = arg;
2592 char c;
2594 alloc_expect_struct();
2595 SET_EXPECT(queue_char__Assign_and_destroy_item);
2596 call_func2(p_queue_base_v4__Internal_pop_if_present, queue, &c);
2597 CHECK_CALLED(queue_char__Assign_and_destroy_item);
2598 free_expect_struct();
2599 return 0;
2602 static void* __cdecl concurrent_vector_int_alloc(vector_base_v4 *this, size_t n)
2604 CHECK_EXPECT(concurrent_vector_int_alloc);
2605 vector_alloc_count++;
2606 return malloc(n*sizeof(int));
2609 static void __cdecl concurrent_vector_int_destroy(void *ptr, size_t n)
2611 CHECK_EXPECT2(concurrent_vector_int_destroy);
2612 ok(vector_elem_count >= n, "invalid destroy\n");
2613 vector_elem_count -= n;
2614 memset(ptr, 0xff, sizeof(int)*n);
2617 static void concurrent_vector_int_ctor(vector_base_v4 *this)
2619 memset(this, 0, sizeof(*this));
2620 this->allocator = concurrent_vector_int_alloc;
2621 this->segment = &this->storage[0];
2624 static void concurrent_vector_int_dtor(vector_base_v4 *this)
2626 size_t blocks;
2628 blocks = (size_t)call_func2(p_vector_base_v4__Internal_clear,
2629 this, concurrent_vector_int_destroy);
2630 for(blocks--; blocks >= this->first_block; blocks--) {
2631 vector_alloc_count--;
2632 free(this->segment[blocks]);
2635 if(this->first_block) {
2636 vector_alloc_count--;
2637 free(this->segment[0]);
2640 call_func1(p_vector_base_v4_dtor, this);
2643 static void __cdecl concurrent_vector_int_copy(void *dst, const void *src, size_t n)
2645 CHECK_EXPECT2(concurrent_vector_int_copy);
2646 vector_elem_count += n;
2647 memcpy(dst, src, n*sizeof(int));
2650 static void __cdecl concurrent_vector_int_assign(void *dst, const void *src, size_t n)
2652 CHECK_EXPECT2(concurrent_vector_int_assign);
2653 memcpy(dst, src, n*sizeof(int));
2656 static void test_queue_base_v4(void)
2658 queue_base_v4 queue;
2659 HANDLE thread[2];
2660 MSVCP_bool b;
2661 size_t size;
2662 DWORD ret;
2663 int i;
2664 char c;
2666 block_start = CreateEventW(NULL, FALSE, FALSE, NULL);
2667 block_end = CreateEventW(NULL, FALSE, FALSE, NULL);
2669 call_func2(p_queue_base_v4_ctor, &queue, 0);
2670 ok(queue.data != NULL, "queue.data = NULL\n");
2671 ok(queue.alloc_count == 32, "queue.alloc_count = %ld\n", (long)queue.alloc_count);
2672 ok(queue.item_size == 0, "queue.item_size = %ld\n", (long)queue.item_size);
2673 call_func1(p_queue_base_v4_dtor, &queue);
2675 call_func2(p_queue_base_v4_ctor, &queue, 8);
2676 ok(queue.data != NULL, "queue.data = NULL\n");
2677 ok(queue.alloc_count == 32, "queue.alloc_count = %ld\n", (long)queue.alloc_count);
2678 ok(queue.item_size == 8, "queue.item_size = %ld\n", (long)queue.item_size);
2679 call_func1(p_queue_base_v4_dtor, &queue);
2681 call_func2(p_queue_base_v4_ctor, &queue, 16);
2682 ok(queue.data != NULL, "queue.data = NULL\n");
2683 ok(queue.alloc_count == 16, "queue.alloc_count = %ld\n", (long)queue.alloc_count);
2684 ok(queue.item_size == 16, "queue.item_size = %ld\n", (long)queue.item_size);
2685 b = (DWORD_PTR)call_func1(p_queue_base_v4__Internal_empty, &queue);
2686 ok(b, "queue is not empty\n");
2687 size = (size_t)call_func1(p_queue_base_v4__Internal_size, &queue);
2688 ok(!size, "size = %ld\n", (long)size);
2689 call_func1(p_queue_base_v4_dtor, &queue);
2691 call_func2(p_queue_base_v4_ctor, &queue, 1);
2692 queue.vtable = (void*)&queue_char_vtbl;
2694 for(i=0; i<8; i++) {
2695 SET_EXPECT(queue_char__Allocate_page);
2696 SET_EXPECT(queue_char__Copy_item);
2697 c = 'a'+i;
2698 call_func2(p_queue_base_v4__Internal_push, &queue, &c);
2699 CHECK_CALLED(queue_char__Allocate_page);
2700 CHECK_CALLED(queue_char__Copy_item);
2702 b = (MSVCP_bool)(DWORD_PTR)call_func1(p_queue_base_v4__Internal_empty, &queue);
2703 ok(!b, "queue is empty\n");
2704 size = (size_t)call_func1(p_queue_base_v4__Internal_size, &queue);
2705 ok(size == i+1, "size = %ld, expected %ld\n", (long)size, (long)i);
2708 SET_EXPECT(queue_char__Copy_item);
2709 c = 'a'+i;
2710 call_func2(p_queue_base_v4__Internal_push, &queue, &c);
2711 CHECK_CALLED(queue_char__Copy_item);
2713 for(i=0; i<9; i++) {
2714 SET_EXPECT(queue_char__Assign_and_destroy_item);
2715 b = (DWORD_PTR)call_func2(p_queue_base_v4__Internal_pop_if_present, &queue, &c);
2716 CHECK_CALLED(queue_char__Assign_and_destroy_item);
2717 ok(b, "pop returned false\n");
2718 ok(c == 'a'+i, "got '%c', expected '%c'\n", c, 'a'+i);
2720 b = (DWORD_PTR)call_func2(p_queue_base_v4__Internal_pop_if_present, &queue, &c);
2721 ok(!b, "pop returned true\n");
2723 for(i=0; i<247; i++) {
2724 SET_EXPECT(queue_char__Copy_item);
2725 c = 'a'+i;
2726 call_func2(p_queue_base_v4__Internal_push, &queue, &c);
2727 CHECK_CALLED(queue_char__Copy_item);
2729 size = (size_t)call_func1(p_queue_base_v4__Internal_size, &queue);
2730 ok(size == i+1, "size = %ld, expected %ld\n", (long)size, (long)i);
2733 SET_EXPECT(queue_char__Allocate_page);
2734 SET_EXPECT(queue_char__Copy_item);
2735 c = 'a'+i;
2736 call_func2(p_queue_base_v4__Internal_push, &queue, &c);
2737 CHECK_CALLED(queue_char__Allocate_page);
2738 CHECK_CALLED(queue_char__Copy_item);
2740 for(i=0; i<239; i++) {
2741 SET_EXPECT(queue_char__Assign_and_destroy_item);
2742 b = (DWORD_PTR)call_func2(p_queue_base_v4__Internal_pop_if_present, &queue, &c);
2743 CHECK_CALLED(queue_char__Assign_and_destroy_item);
2744 ok(b, "pop returned false\n");
2745 ok(c == (char)('a'+i), "got '%c', expected '%c'\n", c, 'a'+i);
2748 SET_EXPECT(queue_char__Assign_and_destroy_item);
2749 SET_EXPECT(queue_char__Deallocate_page);
2750 b = (DWORD_PTR)call_func2(p_queue_base_v4__Internal_pop_if_present, &queue, &c);
2751 CHECK_CALLED(queue_char__Assign_and_destroy_item);
2752 CHECK_CALLED(queue_char__Deallocate_page);
2753 ok(b, "pop returned false\n");
2754 ok(c == (char)('a'+i), "got '%c', expected '%c'\n", c, 'a'+i);
2756 /* destructor doesn't clear the memory, _Internal_finish_clear needs to be called */
2757 SET_EXPECT(queue_char__Deallocate_page);
2758 call_func1(p_queue_base_v4__Internal_finish_clear, &queue);
2759 CHECK_CALLED(queue_char__Deallocate_page);
2761 call_func1(p_queue_base_v4_dtor, &queue);
2763 /* test parallel push */
2764 call_func2(p_queue_base_v4_ctor, &queue, 1);
2765 queue.vtable = (void*)&queue_char_vtbl;
2767 block = TRUE;
2768 thread[0] = CreateThread(NULL, 0, queue_move_push_thread, &queue, 0, NULL);
2769 WaitForSingleObject(block_start, INFINITE);
2771 c = 'a';
2772 for(i=0; i<7; i++) {
2773 SET_EXPECT(queue_char__Allocate_page);
2774 SET_EXPECT(queue_char__Copy_item);
2775 call_func2(p_queue_base_v4__Internal_push, &queue, &c);
2776 CHECK_CALLED(queue_char__Allocate_page);
2777 CHECK_CALLED(queue_char__Copy_item);
2780 thread[1] = CreateThread(NULL, 0, queue_push_thread, &queue, 0, NULL);
2781 ret = WaitForSingleObject(thread[1], 100);
2782 ok(ret == WAIT_TIMEOUT, "WaitForSingleObject returned %x\n", ret);
2784 SetEvent(block_end);
2785 WaitForSingleObject(thread[0], INFINITE);
2786 WaitForSingleObject(thread[1], INFINITE);
2787 CloseHandle(thread[0]);
2788 CloseHandle(thread[1]);
2790 /* test parallel pop */
2791 block = TRUE;
2792 thread[0] = CreateThread(NULL, 0, queue_pop_thread, &queue, 0, NULL);
2793 WaitForSingleObject(block_start, INFINITE);
2795 for(i=0; i<7; i++) {
2796 SET_EXPECT(queue_char__Assign_and_destroy_item);
2797 b = (DWORD_PTR)call_func2(p_queue_base_v4__Internal_pop_if_present, &queue, &c);
2798 CHECK_CALLED(queue_char__Assign_and_destroy_item);
2799 ok(b, "pop returned false\n");
2800 ok(c == 'a', "got '%c', expected 'a'\n", c);
2803 thread[1] = CreateThread(NULL, 0, queue_pop_thread, &queue, 0, NULL);
2804 ret = WaitForSingleObject(thread[1], 100);
2805 ok(ret == WAIT_TIMEOUT, "WaitForSingleObject returned %x\n", ret);
2807 SetEvent(block_end);
2808 WaitForSingleObject(thread[0], INFINITE);
2809 WaitForSingleObject(thread[1], INFINITE);
2810 CloseHandle(thread[0]);
2811 CloseHandle(thread[1]);
2813 /* test parallel push/pop */
2814 for(i=0; i<8; i++) {
2815 SET_EXPECT(queue_char__Copy_item);
2816 call_func2(p_queue_base_v4__Internal_push, &queue, &c);
2817 CHECK_CALLED(queue_char__Copy_item);
2820 block = TRUE;
2821 thread[0] = CreateThread(NULL, 0, queue_push_thread, &queue, 0, NULL);
2822 WaitForSingleObject(block_start, INFINITE);
2824 SET_EXPECT(queue_char__Assign_and_destroy_item);
2825 call_func2(p_queue_base_v4__Internal_pop_if_present, &queue, &c);
2826 CHECK_CALLED(queue_char__Assign_and_destroy_item);
2828 SetEvent(block_end);
2829 WaitForSingleObject(thread[0], INFINITE);
2830 CloseHandle(thread[0]);
2832 for(i=0; i<8; i++) {
2833 SET_EXPECT(queue_char__Assign_and_destroy_item);
2834 call_func2(p_queue_base_v4__Internal_pop_if_present, &queue, &c);
2835 CHECK_CALLED(queue_char__Assign_and_destroy_item);
2838 SET_EXPECT(queue_char__Deallocate_page);
2839 call_func1(p_queue_base_v4__Internal_finish_clear, &queue);
2840 CHECK_CALLED(queue_char__Deallocate_page);
2841 call_func1(p_queue_base_v4_dtor, &queue);
2843 CloseHandle(block_start);
2844 CloseHandle(block_end);
2847 static void test_vector_base_v4(void)
2849 vector_base_v4 vector, v2;
2850 size_t idx, size;
2851 compact_block b;
2852 int i, *data;
2854 concurrent_vector_int_ctor(&vector);
2856 size = (size_t)call_func1(p_vector_base_v4__Internal_capacity, &vector);
2857 ok(size == 0, "size of vector got %ld expected 0\n", (long)size);
2859 SET_EXPECT(concurrent_vector_int_alloc);
2860 data = call_func3(p_vector_base_v4__Internal_push_back, &vector, sizeof(int), &idx);
2861 if(!data) {
2862 skip("_Internal_push_back not yet implemented\n");
2863 return;
2865 CHECK_CALLED(concurrent_vector_int_alloc);
2866 ok(data != NULL, "_Internal_push_back returned NULL\n");
2867 ok(idx == 0, "idx got %ld expected %d\n", (long)idx, 0);
2868 vector_elem_count++;
2869 *data = 1;
2870 ok(data == vector.storage[0], "vector.storage[0] got %p expected %p\n",
2871 vector.storage[0], data);
2872 ok(vector.first_block == 1, "vector.first_block got %ld expected 1\n",
2873 (long)vector.first_block);
2874 ok(vector.early_size == 1, "vector.early_size got %ld expected 1\n",
2875 (long)vector.early_size);
2876 ok(vector.segment == vector.storage, "vector.segment got %p expected %p\n",
2877 vector.segment, vector.storage);
2878 size = (size_t)call_func1(p_vector_base_v4__Internal_capacity, &vector);
2879 ok(size == 2, "size of vector got %ld expected 2\n", (long)size);
2881 data = call_func3(p_vector_base_v4__Internal_push_back, &vector, sizeof(int), &idx);
2882 ok(data != NULL, "_Internal_push_back returned NULL\n");
2883 ok(idx == 1, "idx got %ld expected 1\n", (long)idx);
2884 vector_elem_count++;
2885 *data = 2;
2886 ok(vector.first_block == 1, "vector.first_block got %ld expected 1\n",
2887 (long)vector.first_block);
2888 ok(vector.early_size == 2, "vector.early_size got %ld expected 2\n",
2889 (long)vector.early_size);
2891 size = (size_t)call_func1(p_vector_base_v4__Internal_capacity, &vector);
2892 ok(size == 2, "size of vector got %ld expected 2\n", (long)size);
2894 SET_EXPECT(concurrent_vector_int_alloc);
2895 data = call_func3(p_vector_base_v4__Internal_push_back, &vector, sizeof(int), &idx);
2896 CHECK_CALLED(concurrent_vector_int_alloc);
2897 ok(data != NULL, "_Internal_push_back returned NULL\n");
2898 ok(idx == 2, "idx got %ld expected 2\n", (long)idx);
2899 vector_elem_count++;
2900 *data = 3;
2901 ok(vector.segment == vector.storage, "vector.segment got %p expected %p\n",
2902 vector.segment, vector.storage);
2903 ok(vector.first_block == 1, "vector.first_block got %ld expected 1\n",
2904 (long)vector.first_block);
2905 ok(vector.early_size == 3, "vector.early_size got %ld expected 3\n",
2906 (long)vector.early_size);
2907 size = (size_t)call_func1(p_vector_base_v4__Internal_capacity, &vector);
2908 ok(size == 4, "size of vector got %ld expected %d\n", (long)size, 4);
2910 data = call_func3(p_vector_base_v4__Internal_push_back, &vector, sizeof(int), &idx);
2911 ok(data != NULL, "_Internal_push_back returned NULL\n");
2912 ok(idx == 3, "idx got %ld expected 3\n", (long)idx);
2913 vector_elem_count++;
2914 *data = 4;
2915 size = (size_t)call_func1(p_vector_base_v4__Internal_capacity, &vector);
2916 ok(size == 4, "size of vector got %ld expected 4\n", (long)size);
2918 SET_EXPECT(concurrent_vector_int_alloc);
2919 data = call_func3(p_vector_base_v4__Internal_push_back, &vector, sizeof(int), &idx);
2920 CHECK_CALLED(concurrent_vector_int_alloc);
2921 ok(data != NULL, "_Internal_push_back returned NULL\n");
2922 ok(idx == 4, "idx got %ld expected 4\n", (long)idx);
2923 vector_elem_count++;
2924 *data = 5;
2925 ok(vector.segment == vector.storage, "vector.segment got %p expected %p\n",
2926 vector.segment, vector.storage);
2927 size = (size_t)call_func1(p_vector_base_v4__Internal_capacity, &vector);
2928 ok(size == 8, "size of vector got %ld expected 8\n", (long)size);
2930 concurrent_vector_int_ctor(&v2);
2931 SET_EXPECT(concurrent_vector_int_alloc);
2932 SET_EXPECT(concurrent_vector_int_copy);
2933 call_func4(p_vector_base_v4__Internal_copy, &v2, &vector,
2934 sizeof(int), concurrent_vector_int_copy);
2935 CHECK_CALLED(concurrent_vector_int_alloc);
2936 CHECK_CALLED(concurrent_vector_int_copy);
2937 ok(v2.first_block == 3, "v2.first_block got %ld expected 3\n",
2938 (long)v2.first_block);
2939 ok(v2.early_size == 5, "v2.early_size got %ld expected 5\n",
2940 (long)v2.early_size);
2941 ok(v2.segment == v2.storage, "v2.segment got %p expected %p\n",
2942 v2.segment, v2.storage);
2943 SET_EXPECT(concurrent_vector_int_destroy);
2944 size = (size_t)call_func2(p_vector_base_v4__Internal_clear,
2945 &v2, concurrent_vector_int_destroy);
2946 CHECK_CALLED(concurrent_vector_int_destroy);
2947 ok(size == 3, "_Internal_clear returned %ld expected 3\n", (long)size);
2948 concurrent_vector_int_dtor(&v2);
2950 concurrent_vector_int_ctor(&v2);
2951 SET_EXPECT(concurrent_vector_int_alloc);
2952 data = call_func3(p_vector_base_v4__Internal_push_back, &v2, sizeof(int), &idx);
2953 CHECK_CALLED(concurrent_vector_int_alloc);
2954 ok(data != NULL, "_Internal_push_back returned NULL\n");
2955 data = call_func3(p_vector_base_v4__Internal_push_back, &v2, sizeof(int), &idx);
2956 ok(data != NULL, "_Internal_push_back returned NULL\n");
2957 SET_EXPECT(concurrent_vector_int_alloc);
2958 data = call_func3(p_vector_base_v4__Internal_push_back, &v2, sizeof(int), &idx);
2959 ok(data != NULL, "_Internal_push_back returned NULL\n");
2960 CHECK_CALLED(concurrent_vector_int_alloc);
2961 vector_elem_count += 3;
2962 ok(idx == 2, "idx got %ld expected 2\n", (long)idx);
2963 SET_EXPECT(concurrent_vector_int_assign);
2964 SET_EXPECT(concurrent_vector_int_copy);
2965 SET_EXPECT(concurrent_vector_int_alloc);
2966 call_func6(p_vector_base_v4__Internal_assign, &v2, &vector, sizeof(int),
2967 concurrent_vector_int_destroy, concurrent_vector_int_assign,
2968 concurrent_vector_int_copy);
2969 CHECK_CALLED(concurrent_vector_int_assign);
2970 CHECK_CALLED(concurrent_vector_int_copy);
2971 CHECK_CALLED(concurrent_vector_int_alloc);
2972 ok(v2.first_block == 1, "v2.first_block got %ld expected 1\n",
2973 (long)v2.first_block);
2974 ok(v2.early_size == 5, "v2.early_size got %ld expected 5\n",
2975 (long)v2.early_size);
2976 ok(v2.segment == v2.storage, "v2.segment got %p expected %p\n",
2977 v2.segment, v2.storage);
2978 SET_EXPECT(concurrent_vector_int_destroy);
2979 size = (size_t)call_func2(p_vector_base_v4__Internal_clear,
2980 &v2, concurrent_vector_int_destroy);
2981 CHECK_CALLED(concurrent_vector_int_destroy);
2982 ok(size == 3, "_Internal_clear returned %ld expected 3\n", (long)size);
2983 concurrent_vector_int_dtor(&v2);
2985 concurrent_vector_int_ctor(&v2);
2986 SET_EXPECT(concurrent_vector_int_alloc);
2987 data = call_func3(p_vector_base_v4__Internal_push_back, &v2, sizeof(int), &idx);
2988 ok(data != NULL, "_Internal_push_back returned NULL\n");
2989 data = call_func3(p_vector_base_v4__Internal_push_back, &v2, sizeof(int), &idx);
2990 ok(data != NULL, "_Internal_push_back returned NULL\n");
2991 CHECK_CALLED(concurrent_vector_int_alloc);
2992 SET_EXPECT(concurrent_vector_int_alloc);
2993 data = call_func3(p_vector_base_v4__Internal_push_back, &v2, sizeof(int), &idx);
2994 ok(data != NULL, "_Internal_push_back returned NULL\n");
2995 CHECK_CALLED(concurrent_vector_int_alloc);
2996 vector_elem_count += 3;
2997 ok(idx == 2, "idx got %ld expected 2\n", (long)idx);
2998 call_func2(p_vector_base_v4__Internal_swap,
2999 &v2, &vector);
3000 ok(v2.first_block == 1, "v2.first_block got %ld expected 1\n",
3001 (long)v2.first_block);
3002 ok(v2.early_size == 5, "v2.early_size got %ld expected 5\n",
3003 (long)v2.early_size);
3004 ok(vector.early_size == 3, "vector.early_size got %ld expected 3\n",
3005 (long)vector.early_size);
3006 call_func2(p_vector_base_v4__Internal_swap,
3007 &v2, &vector);
3008 ok(v2.early_size == 3, "v2.early_size got %ld expected 3\n",
3009 (long)v2.early_size);
3010 ok(vector.early_size == 5, "vector.early_size got %ld expected 5\n",
3011 (long)vector.early_size);
3012 SET_EXPECT(concurrent_vector_int_destroy);
3013 size = (size_t)call_func2(p_vector_base_v4__Internal_clear,
3014 &v2, concurrent_vector_int_destroy);
3015 CHECK_CALLED(concurrent_vector_int_destroy);
3016 ok(size == 2, "_Internal_clear returned %ld expected 2\n", (long)size);
3017 concurrent_vector_int_dtor(&v2);
3019 /* test for _Internal_compact */
3020 concurrent_vector_int_ctor(&v2);
3021 for(i=0; i<2; i++) {
3022 SET_EXPECT(concurrent_vector_int_alloc);
3023 data = call_func3(p_vector_base_v4__Internal_push_back, &v2, sizeof(int), &idx);
3024 CHECK_CALLED(concurrent_vector_int_alloc);
3025 ok(data != NULL, "_Internal_push_back returned NULL\n");
3026 data = call_func3(p_vector_base_v4__Internal_push_back, &v2, sizeof(int), &idx);
3027 ok(data != NULL, "_Internal_push_back returned NULL\n");
3028 vector_elem_count += 2;
3030 ok(v2.first_block == 1, "v2.first_block got %ld expected 1\n", (long)v2.first_block);
3031 ok(v2.early_size == 4, "v2.early_size got %ld expected 4\n", (long)v2.early_size);
3032 ok(v2.segment == v2.storage, "v2.segment got %p expected %p\n",
3033 v2.segment, v2.storage);
3034 memset(&b, 0xff, sizeof(b));
3035 SET_EXPECT(concurrent_vector_int_alloc);
3036 SET_EXPECT(concurrent_vector_int_copy);
3037 SET_EXPECT(concurrent_vector_int_destroy);
3038 data = call_func5(p_vector_base_v4__Internal_compact,
3039 &v2, sizeof(int), &b, concurrent_vector_int_destroy,
3040 concurrent_vector_int_copy);
3041 CHECK_CALLED(concurrent_vector_int_alloc);
3042 CHECK_CALLED(concurrent_vector_int_copy);
3043 CHECK_CALLED(concurrent_vector_int_destroy);
3044 ok(v2.first_block == 2, "v2.first_block got %ld expected 2\n", (long)v2.first_block);
3045 ok(v2.early_size == 4,"v2.early_size got %ld expected 4\n", (long)v2.early_size);
3046 ok(b.first_block == 1, "b.first_block got %ld expected 1\n", (long)b.first_block);
3047 ok(v2.segment == v2.storage, "v2.segment got %p expected %p\n",
3048 v2.segment, v2.storage);
3049 for(i=0; i<2; i++){
3050 ok(b.blocks[i] != NULL, "b.blocks[%d] got NULL\n", i);
3051 free(b.blocks[i]);
3052 vector_alloc_count--;
3054 for(; i<ARRAY_SIZE(b.blocks); i++)
3055 ok(!b.blocks[i], "b.blocks[%d] != NULL\n", i);
3056 ok(b.size_check == -1, "b.size_check = %x\n", b.size_check);
3058 SET_EXPECT(concurrent_vector_int_alloc);
3059 data = call_func3(p_vector_base_v4__Internal_push_back, &v2, sizeof(int), &idx);
3060 CHECK_CALLED(concurrent_vector_int_alloc);
3061 ok(data != NULL, "_Internal_push_back returned NULL\n");
3062 for(i=0; i<3; i++){
3063 data = call_func3(p_vector_base_v4__Internal_push_back, &v2, sizeof(int), &idx);
3064 ok(data != NULL, "_Internal_push_back returned NULL\n");
3066 SET_EXPECT(concurrent_vector_int_alloc);
3067 data = call_func3(p_vector_base_v4__Internal_push_back, &v2, sizeof(int), &idx);
3068 CHECK_CALLED(concurrent_vector_int_alloc);
3069 ok(data != NULL, "_Internal_push_back returned NULL\n");
3070 vector_elem_count += 5;
3071 ok(v2.first_block == 2, "v2.first_block got %ld expected 2\n", (long)v2.first_block);
3072 ok(v2.early_size == 9, "v2.early_size got %ld expected 9\n", (long)v2.early_size);
3073 ok(v2.segment != v2.storage, "v2.segment got %p expected %p\n", v2.segment, v2.storage);
3074 for(i = 4;i < 32;i++)
3075 ok(v2.segment[i] == 0, "v2.segment[%d] got %p expected 0\n",
3076 i, v2.segment[i]);
3077 memset(&b, 0xff, sizeof(b));
3078 SET_EXPECT(concurrent_vector_int_alloc);
3079 SET_EXPECT(concurrent_vector_int_copy);
3080 SET_EXPECT(concurrent_vector_int_destroy);
3081 data = call_func5(p_vector_base_v4__Internal_compact,
3082 &v2, sizeof(int), &b, concurrent_vector_int_destroy,
3083 concurrent_vector_int_copy);
3084 CHECK_CALLED(concurrent_vector_int_alloc);
3085 CHECK_CALLED(concurrent_vector_int_copy);
3086 CHECK_CALLED(concurrent_vector_int_destroy);
3087 ok(v2.first_block == 4, "v2.first_block got %ld expected 4\n", (long)v2.first_block);
3088 ok(v2.early_size == 9, "v2.early_size got %ld expected 9\n", (long)v2.early_size);
3089 ok(b.first_block == 2, "b.first_block got %ld expected 2\n", (long)b.first_block);
3090 ok(v2.segment != v2.storage, "v2.segment got %p expected %p\n", v2.segment, v2.storage);
3091 for(i = 4;i < 32;i++)
3092 ok(v2.segment[i] == 0, "v2.segment[%d] got %p\n",
3093 i, v2.segment[i]);
3094 for(i=0; i<4; i++){
3095 ok(b.blocks[i] != NULL, "b.blocks[%d] got NULL\n", i);
3096 /* only b.blocks[0] and b.blocks[>=b.first_block] are used */
3097 if(i == b.first_block-1) continue;
3098 free(b.blocks[i]);
3099 vector_alloc_count--;
3101 for(; i<ARRAY_SIZE(b.blocks); i++)
3102 ok(!b.blocks[i], "b.blocks[%d] != NULL\n", i);
3103 SET_EXPECT(concurrent_vector_int_alloc);
3104 call_func4(p_vector_base_v4__Internal_reserve,
3105 &v2, 17, sizeof(int), 32);
3106 CHECK_CALLED(concurrent_vector_int_alloc);
3107 data = call_func5(p_vector_base_v4__Internal_compact,
3108 &v2, sizeof(int), &b, concurrent_vector_int_destroy,
3109 concurrent_vector_int_copy);
3110 ok(v2.first_block == 4, "v2.first_block got %ld expected 4\n", (long)v2.first_block);
3111 ok(v2.early_size == 9, "v2.early_size got %ld expected 9\n", (long)v2.early_size);
3112 ok(b.first_block == 4, "b.first_block got %ld expected 2\n", (long)b.first_block);
3113 ok(v2.segment != v2.storage, "v2.segment got %p expected %p\n", v2.segment, v2.storage);
3114 for(i = 4; i < 32; i++)
3115 ok(v2.segment[i] == 0, "v2.segment[%d] got %p\n",
3116 i, v2.segment[i]);
3117 for(i=0; i<4; i++)
3118 ok(!b.blocks[i], "b.blocks[%d] != NULL\n", i);
3119 for(; i < 5; i++) {
3120 ok(b.blocks[i] != NULL, "b.blocks[%d] got NULL\n", i);
3121 free(b.blocks[i]);
3122 vector_alloc_count--;
3124 for(; i<ARRAY_SIZE(b.blocks); i++)
3125 ok(!b.blocks[i], "b.blocks[%d] != NULL\n", i);
3126 SET_EXPECT(concurrent_vector_int_destroy);
3127 size = (size_t)call_func2(p_vector_base_v4__Internal_clear,
3128 &v2, concurrent_vector_int_destroy);
3129 CHECK_CALLED(concurrent_vector_int_destroy);
3130 ok(size == 4, "_Internal_clear returned %ld expected 4\n", (long)size);
3131 concurrent_vector_int_dtor(&v2);
3133 /* test for Internal_grow_by */
3134 concurrent_vector_int_ctor(&v2);
3135 SET_EXPECT(concurrent_vector_int_alloc);
3136 data = call_func3(p_vector_base_v4__Internal_push_back, &v2, sizeof(int), &idx);
3137 CHECK_CALLED(concurrent_vector_int_alloc);
3138 ok(data != NULL, "_Internal_push_back returned NULL\n");
3139 data = call_func3(p_vector_base_v4__Internal_push_back, &v2, sizeof(int), &idx);
3140 ok(data != NULL, "_Internal_push_back returned NULL\n");
3141 vector_elem_count += 2;
3142 ok(v2.first_block == 1, "v2.first_block got %ld expected 1\n", (long)v2.first_block);
3143 ok(v2.early_size == 2, "v2.early_size got %ld expected 2\n", (long)v2.early_size);
3144 i = 0;
3145 SET_EXPECT(concurrent_vector_int_alloc);
3146 SET_EXPECT(concurrent_vector_int_copy);
3147 idx = (size_t)call_func5(p_vector_base_v4__Internal_grow_by,
3148 &v2, 1, sizeof(int), concurrent_vector_int_copy, &i);
3149 CHECK_CALLED(concurrent_vector_int_alloc);
3150 CHECK_CALLED(concurrent_vector_int_copy);
3151 ok(idx == 2, "_Internal_grow_by returned %ld expected 2\n", (long)idx);
3152 ok(v2.first_block == 1, "v2.first_block got %ld expected 1\n", (long)v2.first_block);
3153 ok(v2.early_size == 3, "v2.early_size got %ld expected 3\n", (long)v2.early_size);
3154 SET_EXPECT(concurrent_vector_int_alloc);
3155 SET_EXPECT(concurrent_vector_int_copy);
3156 idx = (size_t)call_func5(p_vector_base_v4__Internal_grow_by,
3157 &v2, 2, sizeof(int), concurrent_vector_int_copy, &i);
3158 CHECK_CALLED(concurrent_vector_int_alloc);
3159 CHECK_CALLED(concurrent_vector_int_copy);
3160 ok(idx == 3, "_Internal_grow_by returned %ld expected 3\n", (long)idx);
3161 ok(v2.first_block == 1, "v2.first_block got %ld expected 1\n", (long)v2.first_block);
3162 ok(v2.early_size == 5, "v2.early_size got %ld expected 5\n", (long)v2.early_size);
3163 SET_EXPECT(concurrent_vector_int_destroy);
3164 size = (size_t)call_func2(p_vector_base_v4__Internal_clear,
3165 &v2, concurrent_vector_int_destroy);
3166 ok(size == 3, "_Internal_clear returned %ld expected 3\n", (long)size);
3167 CHECK_CALLED(concurrent_vector_int_destroy);
3168 concurrent_vector_int_dtor(&v2);
3170 /* test for Internal_grow_to_at_least_with_result */
3171 concurrent_vector_int_ctor(&v2);
3172 SET_EXPECT(concurrent_vector_int_alloc);
3173 data = call_func3(p_vector_base_v4__Internal_push_back, &v2, sizeof(int), &idx);
3174 CHECK_CALLED(concurrent_vector_int_alloc);
3175 ok(data != NULL, "_Internal_push_back returned NULL\n");
3176 data = call_func3(p_vector_base_v4__Internal_push_back, &v2, sizeof(int), &idx);
3177 ok(data != NULL, "_Internal_push_back returned NULL\n");
3178 vector_elem_count += 2;
3179 ok(v2.first_block == 1, "v2.first_block got %ld expected 1\n", (long)v2.first_block);
3180 ok(v2.early_size == 2, "v2.early_size got %ld expected 2\n", (long)v2.early_size);
3181 i = 0;
3182 SET_EXPECT(concurrent_vector_int_alloc);
3183 SET_EXPECT(concurrent_vector_int_copy);
3184 idx = (size_t)call_func5(p_vector_base_v4__Internal_grow_to_at_least_with_result,
3185 &v2, 3, sizeof(int), concurrent_vector_int_copy, &i);
3186 CHECK_CALLED(concurrent_vector_int_alloc);
3187 CHECK_CALLED(concurrent_vector_int_copy);
3188 ok(idx == 2, "_Internal_grow_to_at_least_with_result returned %ld expected 2\n", (long)idx);
3189 ok(v2.first_block == 1, "v2.first_block got %ld expected 1\n", (long)v2.first_block);
3190 ok(v2.early_size == 3, "v2.early_size got %ld expected 3\n", (long)v2.early_size);
3191 i = 0;
3192 SET_EXPECT(concurrent_vector_int_alloc);
3193 SET_EXPECT(concurrent_vector_int_copy);
3194 idx = (size_t)call_func5(p_vector_base_v4__Internal_grow_to_at_least_with_result,
3195 &v2, 5, sizeof(int), concurrent_vector_int_copy, &i);
3196 CHECK_CALLED(concurrent_vector_int_alloc);
3197 CHECK_CALLED(concurrent_vector_int_copy);
3198 ok(idx == 3, "_Internal_grow_to_at_least_with_result returned %ld expected 3\n", (long)idx);
3199 ok(v2.first_block == 1, "v2.first_block got %ld expected 1\n", (long)v2.first_block);
3200 ok(v2.early_size == 5, "v2.early_size got %ld expected 5\n", (long)v2.early_size);
3201 SET_EXPECT(concurrent_vector_int_destroy);
3202 size = (size_t)call_func2(p_vector_base_v4__Internal_clear,
3203 &v2, concurrent_vector_int_destroy);
3204 ok(size == 3, "_Internal_clear returned %ld expected 3\n", (long)size);
3205 CHECK_CALLED(concurrent_vector_int_destroy);
3206 concurrent_vector_int_dtor(&v2);
3208 /* test for _Internal_reserve */
3209 concurrent_vector_int_ctor(&v2);
3210 SET_EXPECT(concurrent_vector_int_alloc);
3211 data = call_func3(p_vector_base_v4__Internal_push_back, &v2, sizeof(int), &idx);
3212 CHECK_CALLED(concurrent_vector_int_alloc);
3213 ok(data != NULL, "_Internal_push_back returned NULL\n");
3214 data = call_func3(p_vector_base_v4__Internal_push_back, &v2, sizeof(int), &idx);
3215 ok(data != NULL, "_Internal_push_back returned NULL\n");
3216 vector_elem_count += 2;
3217 ok(v2.first_block == 1, "v2.first_block got %ld expected 1\n", (long)v2.first_block);
3218 ok(v2.early_size == 2, "v2.early_size got %ld expected 2\n", (long)v2.early_size);
3219 SET_EXPECT(concurrent_vector_int_alloc);
3220 call_func4(p_vector_base_v4__Internal_reserve,
3221 &v2, 3, sizeof(int), 4);
3222 CHECK_CALLED(concurrent_vector_int_alloc);
3223 ok(v2.first_block == 1, "v2.first_block got %ld expected 1\n", (long)v2.first_block);
3224 ok(v2.early_size == 2, "v2.early_size got %ld expected 2\n", (long)v2.early_size);
3225 ok(v2.segment == v2.storage, "v2.segment got %p expected %p\n",
3226 v2.segment, v2.storage);
3227 size = (size_t)call_func1(p_vector_base_v4__Internal_capacity, &v2);
3228 ok(size == 4, "size of vector got %ld expected 4\n", (long)size);
3229 SET_EXPECT(concurrent_vector_int_alloc);
3230 call_func4(p_vector_base_v4__Internal_reserve,
3231 &v2, 5, sizeof(int), 8);
3232 CHECK_CALLED(concurrent_vector_int_alloc);
3233 ok(v2.first_block == 1, "v2.first_block got %ld expected 1\n", (long)v2.first_block);
3234 ok(v2.early_size == 2, "v2.early_size got %ld expected 2\n", (long)v2.early_size);
3235 ok(v2.segment == v2.storage, "v2.segment got %p expected %p\n",
3236 v2.segment, v2.storage);
3237 size = (size_t)call_func1(p_vector_base_v4__Internal_capacity, &v2);
3238 ok(size == 8, "size of vector got %ld expected 8\n", (long)size);
3239 SET_EXPECT(concurrent_vector_int_alloc);
3240 call_func4(p_vector_base_v4__Internal_reserve,
3241 &v2, 9, sizeof(int), 16);
3242 CHECK_CALLED(concurrent_vector_int_alloc);
3243 ok(v2.first_block == 1, "v2.first_block got %ld expected 1\n", (long)v2.first_block);
3244 ok(v2.early_size == 2, "v2.early_size got %ld expected 2\n", (long)v2.early_size);
3245 ok(v2.segment != v2.storage, "v2.segment got %p expected %p\n", v2.segment, v2.storage);
3246 for(i = 4;i < 32;i++)
3247 ok(v2.segment[i] == 0, "v2.segment[%d] got %p\n",
3248 i, v2.segment[i]);
3249 size = (size_t)call_func1(p_vector_base_v4__Internal_capacity, &v2);
3250 ok(size == 16, "size of vector got %ld expected 8\n", (long)size);
3252 SET_EXPECT(concurrent_vector_int_destroy);
3253 size = (size_t)call_func2(p_vector_base_v4__Internal_clear,
3254 &v2, concurrent_vector_int_destroy);
3255 ok(size == 4, "_Internal_clear returned %ld expected 4\n", (long)size);
3256 CHECK_CALLED(concurrent_vector_int_destroy);
3257 concurrent_vector_int_dtor(&v2);
3259 /* test for _Internal_resize */
3260 concurrent_vector_int_ctor(&v2);
3261 SET_EXPECT(concurrent_vector_int_alloc);
3262 data = call_func3(p_vector_base_v4__Internal_push_back, &v2, sizeof(int), &idx);
3263 CHECK_CALLED(concurrent_vector_int_alloc);
3264 ok(data != NULL, "_Internal_push_back returned NULL\n");
3265 data = call_func3(p_vector_base_v4__Internal_push_back, &v2, sizeof(int), &idx);
3266 ok(data != NULL, "_Internal_push_back returned NULL\n");
3267 vector_elem_count += 2;
3268 ok(v2.first_block == 1, "v2.first_block got %ld expected 1\n", (long)v2.first_block);
3269 ok(v2.early_size == 2, "v2.early_size got %ld expected 2\n", (long)v2.early_size);
3270 i = 0;
3271 SET_EXPECT(concurrent_vector_int_destroy);
3272 call_func7(p_vector_base_v4__Internal_resize,
3273 &v2, 1, sizeof(int), 4, concurrent_vector_int_destroy, concurrent_vector_int_copy, &i);
3274 CHECK_CALLED(concurrent_vector_int_destroy);
3275 ok(v2.first_block == 1, "v2.first_block got %ld expected 1\n", (long)v2.first_block);
3276 ok(v2.early_size == 1, "v2.early_size got %ld expected 1\n", (long)v2.early_size);
3277 SET_EXPECT(concurrent_vector_int_alloc);
3278 SET_EXPECT(concurrent_vector_int_copy);
3279 call_func7(p_vector_base_v4__Internal_resize,
3280 &v2, 3, sizeof(int), 4, concurrent_vector_int_destroy, concurrent_vector_int_copy, &i);
3281 CHECK_CALLED(concurrent_vector_int_alloc);
3282 CHECK_CALLED(concurrent_vector_int_copy);
3283 ok(v2.first_block == 1, "v2.first_block got %ld expected 1\n", (long)v2.first_block);
3284 ok(v2.early_size == 3, "v2.early_size got %ld expected 3\n", (long)v2.early_size);
3285 SET_EXPECT(concurrent_vector_int_destroy);
3286 size = (size_t)call_func2(p_vector_base_v4__Internal_clear,
3287 &v2, concurrent_vector_int_destroy);
3288 ok(size == 2, "_Internal_clear returned %ld expected 2\n", (long)size);
3289 CHECK_CALLED(concurrent_vector_int_destroy);
3290 concurrent_vector_int_dtor(&v2);
3292 SET_EXPECT(concurrent_vector_int_destroy);
3293 size = (size_t)call_func2(p_vector_base_v4__Internal_clear,
3294 &vector, concurrent_vector_int_destroy);
3295 CHECK_CALLED(concurrent_vector_int_destroy);
3296 ok(size == 3, "_Internal_clear returned %ld\n", (long)size);
3297 ok(vector.first_block == 1, "vector.first_block got %ld expected 1\n",
3298 (long)vector.first_block);
3299 ok(vector.early_size == 0, "vector.early_size got %ld expected 0\n",
3300 (long)vector.early_size);
3301 concurrent_vector_int_dtor(&vector);
3303 ok(!vector_elem_count, "vector_elem_count = %d, expected 0\n", vector_elem_count);
3304 ok(!vector_alloc_count, "vector_alloc_count = %d, expected 0\n", vector_alloc_count);
3307 START_TEST(msvcp120)
3309 if(!init()) return;
3310 expect_idx = TlsAlloc();
3311 ok(expect_idx != TLS_OUT_OF_INDEXES, "TlsAlloc failed\n");
3312 alloc_expect_struct();
3314 test__Xtime_diff_to_millis2();
3315 test_xtime_get();
3316 test__Getcvt();
3317 test__Call_once();
3318 test__Do_call();
3319 test__Dtest();
3320 test__Dscale();
3321 test__FExp();
3322 test__Syserror_map();
3324 test_tr2_sys__File_size();
3325 test_tr2_sys__Equivalent();
3326 test_tr2_sys__Current_get();
3327 test_tr2_sys__Current_set();
3328 test_tr2_sys__Make_dir();
3329 test_tr2_sys__Remove_dir();
3330 test_tr2_sys__Copy_file();
3331 test_tr2_sys__Rename();
3332 test_tr2_sys__Statvfs();
3333 test_tr2_sys__Stat();
3334 test_tr2_sys__Last_write_time();
3335 test_tr2_sys__dir_operation();
3336 test_tr2_sys__Link();
3337 test_tr2_sys__Symlink();
3338 test_tr2_sys__Unlink();
3340 test_thrd();
3341 test_cnd();
3342 test__Pad();
3343 test__Mtx();
3344 test_threads__Mtx();
3346 test_vector_base_v4__Segment_index_of();
3347 test_queue_base_v4();
3348 test_vector_base_v4();
3350 test_vbtable_size_exports();
3352 free_expect_struct();
3353 TlsFree(expect_idx);
3354 FreeLibrary(msvcp);