]> git.saurik.com Git - apple/libpthread.git/blobdiff - tests/join.c
libpthread-218.1.3.tar.gz
[apple/libpthread.git] / tests / join.c
index 3f9bf4091275e0a36936f08860e300968fbb9431..921c136a990269467e73c4e1a668b3307a9ec857 100644 (file)
@@ -5,13 +5,14 @@
 #include <unistd.h>
 #include <mach/mach.h>
 
+#include <darwintest.h>
+
 #define WAITTIME (100 * 1000)
 
 static inline void*
 test(void)
 {
        static uintptr_t idx;
-       printf("Join %lu\n", ++idx);
        return (void*)idx;
 }
 
@@ -22,6 +23,7 @@ thread(void *param)
        return param;
 }
 
+/*
 static void *
 thread1(void *param)
 {
@@ -31,13 +33,12 @@ thread1(void *param)
        usleep(WAITTIME);
        res = pthread_join(p, NULL);
        assert(res == 0);
-       printf("Done\n");
        return 0;
 }
+*/
 
-__attribute((noreturn))
-int
-main(void)
+T_DECL(join, "pthread_join",
+               T_META_ALL_VALID_ARCHS(YES))
 {
        int res;
        kern_return_t kr;
@@ -46,50 +47,73 @@ main(void)
 
        param = test();
        res = pthread_create(&p, NULL, thread, param);
-       assert(res == 0);
+       T_ASSERT_POSIX_ZERO(res, "pthread_create");
        value = NULL;
        res = pthread_join(p, &value);
-       assert(res == 0);
-       assert(param == value);
+       T_ASSERT_POSIX_ZERO(res, "pthread_join");
+       T_ASSERT_EQ_PTR(param, value, "early join value");
 
        param = test();
        res = pthread_create(&p, NULL, thread, param);
-       assert(res == 0);
+       T_ASSERT_POSIX_ZERO(res, "pthread_create");
        usleep(3 * WAITTIME);
        value = NULL;
        res = pthread_join(p, &value);
-       assert(res == 0);
-       assert(param == value);
+       T_ASSERT_POSIX_ZERO(res, "pthread_join");
+       T_ASSERT_EQ_PTR(param, value, "late join value");
 
        param = test();
        res = pthread_create_suspended_np(&p, NULL, thread, param);
-       assert(res == 0);
+       T_ASSERT_POSIX_ZERO(res, "pthread_create_suspended_np");
        kr = thread_resume(pthread_mach_thread_np(p));
-       assert(kr == 0);
+       T_ASSERT_EQ_INT(kr, 0, "thread_resume");
        value = NULL;
        res = pthread_join(p, &value);
-       assert(res == 0);
-       assert(param == value);
+       T_ASSERT_POSIX_ZERO(res, "pthread_join");
+       T_ASSERT_EQ_PTR(param, value, "suspended early join value");
 
        param = test();
        res = pthread_create_suspended_np(&p, NULL, thread, param);
-       assert(res == 0);
+       T_ASSERT_POSIX_ZERO(res, "pthread_create_suspended_np");
        kr = thread_resume(pthread_mach_thread_np(p));
-       assert(kr == 0);
+       T_ASSERT_EQ_INT(kr, 0, "thread_resume");
        usleep(3 * WAITTIME);
        value = NULL;
        res = pthread_join(p, &value);
-       assert(res == 0);
-       assert(param == value);
+       T_ASSERT_POSIX_ZERO(res, "pthread_join");
+       T_ASSERT_EQ_PTR(param, value, "suspended late join value");
 
+       // This test is supposed to test joining on the main thread.  It's not
+       // clear how to express this with libdarwintest for now.
+       /*
        test();
        param = pthread_self();
        res = pthread_create_suspended_np(&p, NULL, thread1, param);
-       assert(res == 0);
+       T_ASSERT_POSIX_ZERO(res, "pthread_create_suspended_np");
        res = pthread_detach(p);
-       assert(res == 0);
+       T_ASSERT_POSIX_ZERO(res, "pthread_detach");
        kr = thread_resume(pthread_mach_thread_np(p));
-       assert(kr == 0);
+       T_ASSERT_EQ_INT(kr, 0, "thread_resume");
        pthread_exit(0);
+       */
+}
+
+static void *
+thread_stub(__unused void *arg)
+{
+       return NULL;
 }
 
+T_DECL(pthread_join_stress, "pthread_join in a loop")
+{
+       for (int i = 0; i < 1000; i++) {
+               pthread_t th[16];
+               for (int j = 0; j < i%16; j++){
+                       T_QUIET; T_ASSERT_POSIX_SUCCESS(pthread_create(&th[j], NULL, thread_stub, NULL), NULL);
+               }
+               for (int j = i%16; j >= 0; j--){
+                       T_QUIET; T_ASSERT_POSIX_SUCCESS(pthread_join(th[j], NULL), NULL);
+               }
+       }
+       T_PASS("Success!");
+}