1 /* check-sources:disable-copyright-check */
2 #include <pthread.h>
3 #include <check.h>
4 #include <droplet.h>
5 #include <droplet/task.h>
6 #include <unistd.h>
7 
8 #include "utest_main.h"
9 
10 
11 //
12 // Retrieve a fake ctx for task pool initialization
13 //
get_ctx(void)14 static dpl_ctx_t* get_ctx(void)
15 {
16   static pthread_once_t once = PTHREAD_ONCE_INIT;
17   static dpl_ctx_t t;
18 
19   void init(void)
20   {
21     bzero(&t, sizeof(t));
22     pthread_mutex_init(&t.lock, NULL);
23     return;
24   }
25   (void)pthread_once(&once, init);
26   return &t;
27 }
28 
29 
START_TEST(taskpool_test)30 START_TEST(taskpool_test)
31 {
32   return;
33   dpl_task_pool_t* p;
34   p = dpl_task_pool_create(get_ctx(), "taskpool_test", 100);
35   dpl_assert_ptr_not_null(p);
36   dpl_task_pool_destroy(p);
37 
38   p = dpl_task_pool_create(get_ctx(), "taskpool_test", 100);
39   dpl_assert_ptr_not_null(p);
40   dpl_task_pool_cancel(p);
41   dpl_task_pool_destroy(p);
42 
43   p = dpl_task_pool_create(get_ctx(), "taskpool_test", 100);
44   dpl_assert_ptr_not_null(p);
45   //
46   // Increase and decrease the number of workers
47   //
48   int wn[] = {1, 100, 50, 200, 100};
49   for (unsigned int i = 0; i < sizeof(wn) / sizeof(wn[0]); i++) {
50     int ret;
51     ret = dpl_task_pool_set_workers(p, wn[i]);
52     dpl_assert_int_eq(0, ret);
53 
54     // give a chance to the threads to stop themselves
55     // note we rely on the per-test timeout to catch
56     // bugs where it never converges
57     while (dpl_task_pool_get_workers(p) != wn[i]) usleep(100);
58   }
59 
60   //
61   // Start thread, wait, and cancel combo
62   //
63   static int incr = 0;
64   static pthread_mutex_t mtx = PTHREAD_MUTEX_INITIALIZER;
65   void tf(void* arg)
66   {
67     unsigned int i = 0;
68     for (i = 0; i < 10000; i++) {
69       pthread_mutex_lock(&mtx);
70       incr++;
71       pthread_mutex_unlock(&mtx);
72     }
73   }
74 
75   dpl_task_t* tasks = calloc(1000, sizeof(*tasks));
76   dpl_assert_ptr_not_null(tasks);
77   for (unsigned int i = 0; i < 100; i++) {
78     tasks[i].func = tf;
79     dpl_task_pool_put(p, &tasks[i]);
80   }
81   dpl_task_pool_wait_idle(p);
82   dpl_assert_int_eq(100 * 10000, incr);
83 
84   incr = 0;
85   for (unsigned int i = 0; i < 100; i++) {
86     tasks[i].func = tf;
87     dpl_task_pool_put(p, &tasks[i]);
88   }
89   dpl_task_pool_cancel(p);
90   dpl_assert_int_eq(100 * 10000, incr);
91   dpl_task_pool_destroy(p);
92   free(tasks);
93 }
94 END_TEST
95 
96 
taskpool_suite()97 Suite* taskpool_suite()
98 {
99   Suite* s = suite_create("taskpool");
100   TCase* t = tcase_create("base");
101   tcase_add_test(t, taskpool_test);
102   suite_add_tcase(s, t);
103   return s;
104 }
105