sink, source: Really set the fixed latency in set_fixed_latency_within_thread(),...
[platform/upstream/pulseaudio.git] / src / tests / thread-test.c
1 /***
2   This file is part of PulseAudio.
3
4   PulseAudio is free software; you can redistribute it and/or modify
5   it under the terms of the GNU Lesser General Public License as published
6   by the Free Software Foundation; either version 2.1 of the License,
7   or (at your option) any later version.
8
9   PulseAudio is distributed in the hope that it will be useful, but
10   WITHOUT ANY WARRANTY; without even the implied warranty of
11   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12   General Public License for more details.
13
14   You should have received a copy of the GNU Lesser General Public License
15   along with PulseAudio; if not, write to the Free Software
16   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
17   USA.
18 ***/
19
20 #ifdef HAVE_CONFIG_H
21 #include <config.h>
22 #endif
23
24 #include <check.h>
25
26 #include <pulse/xmalloc.h>
27 #include <pulsecore/thread.h>
28 #include <pulsecore/macro.h>
29 #include <pulsecore/mutex.h>
30 #include <pulsecore/once.h>
31 #include <pulsecore/log.h>
32 #include <pulsecore/core-util.h>
33
34 static pa_mutex *mutex = NULL;
35 static pa_cond *cond1 = NULL, *cond2 = NULL;
36 static pa_tls *tls = NULL;
37
38 static int magic_number = 0;
39
40 #define THREADS_MAX 20
41
42 static void once_func(void) {
43     pa_log("once!");
44 }
45
46 static pa_once once = PA_ONCE_INIT;
47
48 static void thread_func(void *data) {
49     pa_tls_set(tls, data);
50
51     pa_log_info("thread_func() for %s starting...", (char*) pa_tls_get(tls));
52
53     pa_mutex_lock(mutex);
54
55     for (;;) {
56         int k, n;
57
58         pa_log_info("%s waiting ...", (char*) pa_tls_get(tls));
59
60         for (;;) {
61
62             if (magic_number < 0)
63                 goto quit;
64
65             if (magic_number != 0)
66                 break;
67
68             pa_cond_wait(cond1, mutex);
69         }
70
71         k = magic_number;
72         magic_number = 0;
73
74         pa_mutex_unlock(mutex);
75
76         pa_run_once(&once, once_func);
77
78         pa_cond_signal(cond2, 0);
79
80         pa_log_info("%s got number %i", (char*) pa_tls_get(tls), k);
81
82         /* Spin! */
83         for (n = 0; n < k; n++)
84             pa_thread_yield();
85
86         pa_mutex_lock(mutex);
87     }
88
89 quit:
90
91     pa_mutex_unlock(mutex);
92
93     pa_log_info("thread_func() for %s done...", (char*) pa_tls_get(tls));
94 }
95
96 START_TEST (thread_test) {
97     int i, k;
98     pa_thread* t[THREADS_MAX];
99
100     if (!getenv("MAKE_CHECK"))
101         pa_log_set_level(PA_LOG_DEBUG);
102
103     mutex = pa_mutex_new(FALSE, FALSE);
104     cond1 = pa_cond_new();
105     cond2 = pa_cond_new();
106     tls = pa_tls_new(pa_xfree);
107
108     for (i = 0; i < THREADS_MAX; i++) {
109         t[i] = pa_thread_new("test", thread_func, pa_sprintf_malloc("Thread #%i", i+1));
110         fail_unless(t[i] != 0);
111     }
112
113     pa_mutex_lock(mutex);
114
115     pa_log("loop-init");
116
117     for (k = 0; k < 100; k++) {
118         pa_assert(magic_number == 0);
119
120         magic_number = (int) rand() % 0x10000;
121
122         pa_log_info("iteration %i (%i)", k, magic_number);
123
124         pa_cond_signal(cond1, 0);
125
126         pa_cond_wait(cond2, mutex);
127     }
128
129     pa_log("loop-exit");
130
131     magic_number = -1;
132     pa_cond_signal(cond1, 1);
133
134     pa_mutex_unlock(mutex);
135
136     for (i = 0; i < THREADS_MAX; i++)
137         pa_thread_free(t[i]);
138
139     pa_mutex_free(mutex);
140     pa_cond_free(cond1);
141     pa_cond_free(cond2);
142     pa_tls_free(tls);
143 }
144 END_TEST
145
146 int main(int argc, char *argv[]) {
147     int failed = 0;
148     Suite *s;
149     TCase *tc;
150     SRunner *sr;
151
152     s = suite_create("Thread");
153     tc = tcase_create("thread");
154     tcase_add_test(tc, thread_test);
155     suite_add_tcase(s, tc);
156
157     sr = srunner_create(s);
158     srunner_run_all(sr, CK_NORMAL);
159     failed = srunner_ntests_failed(sr);
160     srunner_free(sr);
161
162     return (failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
163 }