@@ -2455,14 +2455,40 @@ static int test_mp_pack_unpack(void)
24552455#define ONLY_PUBLIC_API_C
24562456#endif
24572457
2458- #if !defined(LTM_TEST_MULTITHREAD ) || !defined( MP_SMALL_STACK_SIZE )
2458+ #if !defined(LTM_TEST_MULTITHREAD )
24592459#define SINGLE_THREADED_C
2460- typedef unsigned long int pthread_t ;
2461- extern int pthread_create (pthread_t * , const void * , void * (* )(void * ), void * );
2462- extern int pthread_join (pthread_t , void * * );
2460+ typedef uintptr_t thread_id_t ;
24632461#else
24642462#define MULTI_THREADED_C
2463+ #if !defined(_WIN32 )
2464+ #define MULTI_THREADED_PTHREAD_C
24652465#include <pthread.h>
2466+ typedef pthread_t thread_id_t ;
2467+ #else
2468+ #define MULTI_THREADED_MSVC_C
2469+
2470+ #ifndef _WIN32_WINNT
2471+ #define _WIN32_WINNT 0x0501
2472+ #endif
2473+ #ifndef WINVER
2474+ #define WINVER 0x0501
2475+ #endif
2476+
2477+ #define WIN32_LEAN_AND_MEAN
2478+ #include <windows.h>
2479+ typedef HANDLE thread_id_t ;
2480+ #endif
2481+ #endif
2482+
2483+ #if !defined(MULTI_THREADED_PTHREAD_C )
2484+ extern int pthread_create (thread_id_t * , const void * , void * (* )(void * ), void * );
2485+ extern int pthread_join (thread_id_t , void * * );
2486+ #endif
2487+
2488+ #if !defined(MULTI_THREADED_MSVC_C )
2489+ extern thread_id_t CreateThread (void * , size_t , unsigned long (* )(void * ), void * , unsigned long , void * );
2490+ extern unsigned long WaitForSingleObject (thread_id_t hHandle , unsigned long dwMilliseconds );
2491+ #define INFINITE ((unsigned long)-1)
24662492#endif
24672493
24682494struct test_fn {
@@ -2471,12 +2497,12 @@ struct test_fn {
24712497};
24722498
24732499struct thread_info {
2474- pthread_t thread_id ;
2500+ thread_id_t thread_id ;
24752501 const struct test_fn * t ;
24762502 int ret ;
24772503};
24782504
2479- static void * run (void * arg )
2505+ static void * run_pthread (void * arg )
24802506{
24812507 struct thread_info * tinfo = arg ;
24822508
@@ -2485,6 +2511,38 @@ static void *run(void *arg)
24852511 return arg ;
24862512}
24872513
2514+ static unsigned long run_msvc (void * arg )
2515+ {
2516+ struct thread_info * tinfo = arg ;
2517+
2518+ tinfo -> ret = tinfo -> t -> fn ();
2519+
2520+ return 0 ;
2521+ }
2522+
2523+ static int thread_start (struct thread_info * info )
2524+ {
2525+ if (MP_HAS (MULTI_THREADED_PTHREAD ))
2526+ return pthread_create (& info -> thread_id , NULL , run_pthread , info );
2527+ if (MP_HAS (MULTI_THREADED_MSVC )) {
2528+ info -> thread_id = CreateThread (NULL , 0 , run_msvc , info , 0 , NULL );
2529+ return info -> thread_id == (thread_id_t )NULL ? -1 : 0 ;
2530+ }
2531+ return -1 ;
2532+ }
2533+
2534+ static int thread_join (struct thread_info * info , struct thread_info * * res )
2535+ {
2536+ if (MP_HAS (MULTI_THREADED_PTHREAD ))
2537+ return pthread_join (info -> thread_id , (void * * )res );
2538+ if (MP_HAS (MULTI_THREADED_MSVC )) {
2539+ WaitForSingleObject (info -> thread_id , INFINITE );
2540+ * res = info ;
2541+ return 0 ;
2542+ }
2543+ return -1 ;
2544+ }
2545+
24882546static int unit_tests (int argc , char * * argv )
24892547{
24902548 static const struct test_fn test [] = {
@@ -2551,26 +2609,32 @@ static int unit_tests(int argc, char **argv)
25512609 };
25522610 struct thread_info test_threads [sizeof (test )/sizeof (test [0 ])], * res ;
25532611 unsigned long i , ok , fail , nop ;
2612+ size_t n_threads = MP_HAS (MULTI_THREADED ) ? sizeof (test ) / sizeof (test [0 ]) : 1 ;
25542613 uint64_t t ;
2555- int j = -1 ;
2614+ int j ;
25562615 ok = fail = nop = 0 ;
25572616
25582617 t = (uint64_t )time (NULL );
25592618 printf ("SEED: 0x%" PRIx64 "\n\n" , t );
25602619 s_mp_rand_jenkins_init (t );
25612620 mp_rand_source (s_mp_rand_jenkins );
25622621
2622+ if (MP_HAS (MP_SMALL_STACK_SIZE )) {
2623+ printf ("Small-stack enabled with %zu warray buffers\n\n" , n_threads );
2624+ DO (mp_warray_init (n_threads , 1 ));
2625+ }
2626+
25632627 if (MP_HAS (MULTI_THREADED )) {
25642628 printf ("Multi-threading enabled\n\n" );
2565- DO (mp_warray_init (sizeof (test ) / sizeof (test [0 ]), 1 ));
2566- /* we ignore the fact that jenkings is not thread safe */
2629+ /* we ignore the fact that jenkins is not thread safe */
25672630 for (i = 0 ; i < (sizeof (test ) / sizeof (test [0 ])); ++ i ) {
25682631 test_threads [i ].t = & test [i ];
2569- EXPECT (pthread_create ( & test_threads [ i ]. thread_id , NULL , run , & test_threads [i ]) == 0 );
2632+ EXPECT (thread_start ( & test_threads [i ]) == 0 );
25702633 }
25712634 }
25722635
25732636 for (i = 0 ; i < (sizeof (test ) / sizeof (test [0 ])); ++ i ) {
2637+ j = -1 ;
25742638 if (MP_HAS (SINGLE_THREADED )) {
25752639 if (argc > 1 ) {
25762640 for (j = 1 ; j < argc ; ++ j ) {
@@ -2584,7 +2648,7 @@ static int unit_tests(int argc, char **argv)
25842648 if (test [i ].fn )
25852649 j = test [i ].fn ();
25862650 } else if (MP_HAS (MULTI_THREADED )) {
2587- EXPECT (pthread_join ( test_threads [i ]. thread_id , ( void * * ) & res ) == 0 );
2651+ EXPECT (thread_join ( & test_threads [i ], & res ) == 0 );
25882652 j = res -> ret ;
25892653 }
25902654 printf ("TEST %s\n" , test [i ].name );
0 commit comments