source: rtems-libbsd/testsuite/thread01/test_main.c @ 6fb003f

5-freebsd-12
Last change on this file since 6fb003f was 6fb003f, checked in by Sebastian Huber <sebastian.huber@…>, on Jul 26, 2018 at 10:03:45 AM

Fix sporadic test failures via uma_timeout()

  • Property mode set to 100644
File size: 6.6 KB
Line 
1/*
2 * Copyright (c) 2013, 2018 embedded brains GmbH.  All rights reserved.
3 *
4 *  embedded brains GmbH
5 *  Dornierstr. 4
6 *  82178 Puchheim
7 *  Germany
8 *  <rtems@embedded-brains.de>
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 *    notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 *    notice, this list of conditions and the following disclaimer in the
17 *    documentation and/or other materials provided with the distribution.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32#include <machine/rtems-bsd-kernel-space.h>
33#include <machine/rtems-bsd-thread.h>
34
35#include <stdlib.h>
36#include <stdio.h>
37#include <string.h>
38#include <assert.h>
39
40#include <sys/types.h>
41#include <sys/param.h>
42#include <sys/proc.h>
43#include <sys/kthread.h>
44#include <sys/errno.h>
45
46#include <vm/uma.h>
47
48#include <rtems/bsd/bsd.h>
49
50#include <rtems.h>
51#include <rtems/libcsupport.h>
52#include <rtems/score/threaddispatch.h>
53#include <rtems/score/wkspace.h>
54
55#define TEST_NAME "LIBBSD THREAD 1"
56
57#define TEST_KTHREAD_ADD ((void *) 0xdeadbeef)
58
59static rtems_id main_task_id;
60
61static char test_kproc_name[] = "kproc";
62
63static struct kproc_desc test_kproc_start_desc;
64
65static char test_kthread_name[] = "kthread";
66
67static struct kthread_desc test_kthread_start_desc;
68
69static void
70test_curthread(const char *name)
71{
72        struct thread *td_0 = rtems_bsd_get_curthread_or_null();
73        struct thread *td_1 = rtems_bsd_get_curthread_or_wait_forever();
74        struct thread *td_2 = curthread;
75
76        assert(td_0 != NULL);
77        assert(td_0 == td_1);
78        assert(td_0 == td_2);
79        assert(strcmp(td_0->td_thread->Join_queue.Queue.name, name) == 0);
80}
81
82static void
83wake_up_main_thread(void)
84{
85        rtems_status_code sc;
86
87        sc = rtems_event_transient_send(main_task_id);
88        assert(sc == RTEMS_SUCCESSFUL);
89}
90
91static void
92wait_for_worker_thread(void)
93{
94        rtems_status_code sc;
95
96        sc = rtems_event_transient_receive(RTEMS_WAIT, RTEMS_NO_TIMEOUT);
97        assert(sc == RTEMS_SUCCESSFUL);
98}
99
100static void
101non_bsd_thread(rtems_task_argument arg)
102{
103        rtems_status_code sc;
104
105        test_curthread("");
106        wake_up_main_thread();
107
108        sc = rtems_task_delete(RTEMS_SELF);
109        assert(sc == RTEMS_SUCCESSFUL);
110}
111
112static void
113test_non_bsd_thread(void)
114{
115        rtems_status_code sc;
116        rtems_id task_id;
117        rtems_resource_snapshot snapshot;
118
119        rtems_resource_snapshot_take(&snapshot);
120
121        sc = rtems_task_create(
122                rtems_build_name('T', 'A', 'S', 'K'),
123                RTEMS_MINIMUM_PRIORITY,
124                RTEMS_MINIMUM_STACK_SIZE,
125                RTEMS_DEFAULT_MODES,
126                RTEMS_FLOATING_POINT,
127                &task_id
128        );
129        assert(sc == RTEMS_SUCCESSFUL);
130
131        sc = rtems_task_start(task_id, non_bsd_thread, 0);
132        assert(sc == RTEMS_SUCCESSFUL);
133
134        wait_for_worker_thread();
135
136        assert(rtems_resource_snapshot_check(&snapshot));
137}
138
139static void
140test_kproc_start_proc(void)
141{
142        test_curthread(&test_kproc_name[0]);
143        wake_up_main_thread();
144        kproc_exit(0);
145}
146
147static void
148test_kproc_start(void)
149{
150        rtems_resource_snapshot snapshot;
151        struct proc *pr = NULL;
152        struct kproc_desc *kpd = &test_kproc_start_desc;
153
154        puts("test kproc_start()");
155
156        rtems_resource_snapshot_take(&snapshot);
157
158        kpd->arg0 = &test_kproc_name[0];
159        kpd->func = test_kproc_start_proc,
160        kpd->global_procpp = &pr;
161
162        kproc_start(kpd);
163        wait_for_worker_thread();
164
165        assert(pr != NULL);
166
167        assert(rtems_resource_snapshot_check(&snapshot));
168}
169
170static void
171test_kthread_start_thread(void)
172{
173        test_curthread(&test_kthread_name[0]);
174        wake_up_main_thread();
175        kthread_exit();
176}
177
178static void
179test_kthread_start(void)
180{
181        rtems_resource_snapshot snapshot;
182        struct thread *td = NULL;
183        struct kthread_desc *ktd = &test_kthread_start_desc;
184
185        puts("test kthread_start()");
186
187        rtems_resource_snapshot_take(&snapshot);
188
189        ktd->arg0 = &test_kthread_name[0];
190        ktd->func = test_kthread_start_thread,
191        ktd->global_threadpp = &td;
192
193        kthread_start(ktd);
194        wait_for_worker_thread();
195
196        assert(td != NULL);
197
198        assert(rtems_resource_snapshot_check(&snapshot));
199}
200
201static void
202test_kthread_add_thread(void *arg)
203{
204        test_curthread(&test_kthread_name[0]);
205
206        assert(arg == TEST_KTHREAD_ADD);
207
208        wake_up_main_thread();
209        kthread_exit();
210}
211
212static void
213test_kthread_add(void)
214{
215        rtems_resource_snapshot snapshot;
216        void *greedy;
217        uintptr_t take_away = 2 * rtems_bsd_get_task_stack_size("");
218
219        puts("test kthread_add()");
220
221        greedy = rtems_workspace_greedy_allocate(&take_away, 1);
222
223        rtems_resource_snapshot_take(&snapshot);
224
225        assert(rtems_configuration_get_unified_work_area());
226
227        while (take_away > 0) {
228                void *away;
229                bool ok;
230
231                ok = rtems_workspace_allocate(take_away, &away);
232                if (ok) {
233                        struct thread *td = NULL;
234                        int eno;
235
236                        eno = kthread_add(
237                                test_kthread_add_thread,
238                                TEST_KTHREAD_ADD,
239                                NULL,
240                                &td,
241                                0,
242                                0,
243                                "%s",
244                                &test_kthread_name[0]
245                        );
246
247                        ok = rtems_workspace_free(away);
248                        assert(ok);
249
250                        if (eno == 0) {
251                                wait_for_worker_thread();
252                                assert(td != NULL);
253
254                                break;
255                        } else {
256                                assert(eno == ENOMEM);
257                                assert(rtems_resource_snapshot_check(&snapshot));
258                        }
259                }
260
261                --take_away;
262        }
263
264        assert(take_away > 0);
265
266        rtems_workspace_greedy_free(greedy);
267}
268
269static void
270test_rtems_bsd_get_curthread_or_null(void)
271{
272        rtems_resource_snapshot snapshot;
273        void *greedy;
274
275        puts("test rtems_bsd_get_curthread_or_null()");
276
277        rtems_resource_snapshot_take(&snapshot);
278
279        greedy = rtems_workspace_greedy_allocate(NULL, 0);
280        assert(rtems_bsd_get_curthread_or_null() == NULL);
281        rtems_workspace_greedy_free(greedy);
282
283        rtems_resource_snapshot_take(&snapshot);
284}
285
286static void
287test_main(void)
288{
289
290        main_task_id = rtems_task_self();
291
292        /*
293         * Stop interferences of uma_timeout() which may need some dynamic
294         * memory.  This could disturb the no memory tests.
295         */
296        rtems_uma_drain_timeout();
297
298        test_non_bsd_thread();
299        test_kproc_start();
300        test_kthread_start();
301        test_kthread_add();
302        test_rtems_bsd_get_curthread_or_null();
303
304        exit(0);
305}
306
307#include <rtems/bsd/test/default-init.h>
Note: See TracBrowser for help on using the repository browser.