source: rtems-libbsd/testsuite/rwlock01/test_main.c @ fafa9e2

4.115-freebsd-12freebsd-9.3
Last change on this file since fafa9e2 was fafa9e2, checked in by Sebastian Huber <sebastian.huber@…>, on Nov 13, 2013 at 4:20:01 PM

testsuite: Simplify tests

  • Property mode set to 100644
File size: 10.1 KB
Line 
1/*
2 * Copyright (c) 2013 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
34#include <rtems/bsd/sys/param.h>
35#include <rtems/bsd/sys/types.h>
36#include <sys/systm.h>
37#include <rtems/bsd/sys/lock.h>
38#include <sys/rwlock.h>
39
40#include <assert.h>
41#include <stdio.h>
42#include <stdlib.h>
43#include <string.h>
44
45#include <rtems/libcsupport.h>
46#include <rtems.h>
47
48#define TEST_NAME "LIBBSD RWLOCK 1"
49
50#define PRIO_MASTER 2
51
52#define PRIO_WORKER 1
53
54#define EVENT_RLOCK RTEMS_EVENT_0
55
56#define EVENT_WLOCK RTEMS_EVENT_1
57
58#define EVENT_TRY_RLOCK RTEMS_EVENT_2
59
60#define EVENT_TRY_WLOCK RTEMS_EVENT_3
61
62#define EVENT_UNLOCK RTEMS_EVENT_4
63
64#define EVENT_SLEEP RTEMS_EVENT_5
65
66typedef struct {
67        struct rwlock rw;
68        bool done;
69        int rv;
70        int timo;
71        rtems_id worker_task;
72} test_context;
73
74static test_context test_instance;
75
76static void
77set_self_prio(rtems_task_priority prio)
78{
79        rtems_status_code sc;
80
81        sc = rtems_task_set_priority(RTEMS_SELF, prio, &prio);
82        assert(sc == RTEMS_SUCCESSFUL);
83}
84
85static void
86worker_task(rtems_task_argument arg)
87{
88        test_context *ctx = (test_context *) arg;
89        struct rwlock *rw = &ctx->rw;
90
91        puts("worker ready");
92
93        while (true) {
94                rtems_status_code sc;
95                rtems_event_set events;
96
97                sc = rtems_event_receive(
98                        RTEMS_ALL_EVENTS,
99                        RTEMS_EVENT_ANY | RTEMS_WAIT,
100                        RTEMS_NO_TIMEOUT,
101                        &events
102                );
103                assert(sc == RTEMS_SUCCESSFUL);
104
105                if ((events & EVENT_RLOCK) != 0) {
106                        puts("worker: rw_rlock");
107
108                        rw_rlock(rw);
109                        ctx->done = true;
110                }
111
112                if ((events & EVENT_WLOCK) != 0) {
113                        puts("worker: rw_wlock");
114
115                        rw_wlock(rw);
116                        ctx->done = true;
117                }
118
119                if ((events & EVENT_TRY_RLOCK) != 0) {
120                        puts("worker: rw_try_rlock");
121
122                        ctx->rv = rw_try_rlock(rw);
123                        ctx->done = true;
124                }
125
126                if ((events & EVENT_TRY_WLOCK) != 0) {
127                        puts("worker: rw_try_wlock");
128
129                        ctx->rv = rw_try_wlock(rw);
130                        ctx->done = true;
131                }
132
133                if ((events & EVENT_UNLOCK) != 0) {
134                        puts("worker: rw_unlock");
135
136                        rw_unlock(rw);
137                        ctx->done = true;
138                }
139
140                if ((events & EVENT_SLEEP) != 0) {
141                        puts("worker: rw_sleep");
142
143                        ctx->rv = rw_sleep(ctx, rw, 0, "worker", ctx->timo);
144                        ctx->done = true;
145                }
146        }
147}
148
149static void
150send_events(test_context *ctx, rtems_event_set events)
151{
152        rtems_status_code sc;
153
154        sc = rtems_event_send(ctx->worker_task, events);
155        assert(sc == RTEMS_SUCCESSFUL);
156}
157
158static void
159start_worker(test_context *ctx)
160{
161        rtems_status_code sc;
162
163        sc = rtems_task_create(
164                rtems_build_name('W', 'O', 'R', 'K'),
165                PRIO_WORKER,
166                RTEMS_MINIMUM_STACK_SIZE,
167                RTEMS_DEFAULT_MODES,
168                RTEMS_DEFAULT_ATTRIBUTES,
169                &ctx->worker_task
170        );
171        assert(sc == RTEMS_SUCCESSFUL);
172
173        sc = rtems_task_start(
174                ctx->worker_task,
175                worker_task,
176                (rtems_task_argument) ctx
177        );
178        assert(sc == RTEMS_SUCCESSFUL);
179}
180
181static void
182delete_worker(test_context *ctx)
183{
184        rtems_status_code sc;
185
186        sc = rtems_task_delete(ctx->worker_task);
187        assert(sc == RTEMS_SUCCESSFUL);
188}
189
190static void
191test_rw_non_recursive(test_context *ctx)
192{
193        struct rwlock *rw = &ctx->rw;
194        int ok;
195
196        puts("test rw non-recursive");
197
198        assert(!rw_initialized(rw));
199        rw_init(rw, "test");
200        assert(rw_initialized(rw));
201
202        rw_rlock(rw);
203        /* FIXME: We use a mutex implementation */
204        assert(rw_wowned(rw));
205        /* FIXME: We always allow recursion */
206        rw_rlock(rw);
207        rw_runlock(rw);
208        rw_runlock(rw);
209
210        rw_rlock(rw);
211        rw_unlock(rw);
212
213        rw_rlock(rw);
214        ok = rw_try_upgrade(rw);
215        assert(ok != 0);
216        assert(rw_wowned(rw));
217        rw_wunlock(rw);
218
219        rw_rlock(rw);
220        ok = rw_try_upgrade(rw);
221        assert(ok != 0);
222        assert(rw_wowned(rw));
223        rw_unlock(rw);
224
225        rw_rlock(rw);
226        ok = rw_try_upgrade(rw);
227        assert(ok != 0);
228        assert(rw_wowned(rw));
229        rw_downgrade(rw);
230        /* FIXME: We use a mutex implementation */
231        assert(rw_wowned(rw));
232        rw_runlock(rw);
233
234        rw_rlock(rw);
235        ok = rw_try_upgrade(rw);
236        assert(ok != 0);
237        assert(rw_wowned(rw));
238        rw_downgrade(rw);
239        /* FIXME: We use a mutex implementation */
240        assert(rw_wowned(rw));
241        rw_unlock(rw);
242
243        rw_wlock(rw);
244        assert(rw_wowned(rw));
245        /* FIXME: We always allow recursion */
246        rw_wlock(rw);
247        rw_wunlock(rw);
248        rw_wunlock(rw);
249
250        rw_wlock(rw);
251        rw_unlock(rw);
252
253        ok = rw_try_rlock(rw);
254        assert(ok != 0);
255        rw_unlock(rw);
256
257        ok = rw_try_wlock(rw);
258        assert(ok != 0);
259        rw_unlock(rw);
260
261        rw_destroy(rw);
262}
263
264static void
265test_rw_recursive(test_context *ctx)
266{
267        struct rwlock *rw = &ctx->rw;
268
269        puts("test rw recursive");
270
271        assert(!rw_initialized(rw));
272        rw_init_flags(rw, "test", RW_RECURSE);
273        assert(rw_initialized(rw));
274
275        rw_rlock(rw);
276        rw_rlock(rw);
277        rw_runlock(rw);
278        rw_runlock(rw);
279
280        rw_wlock(rw);
281        rw_wlock(rw);
282        rw_wunlock(rw);
283        rw_wunlock(rw);
284
285        rw_destroy(rw);
286}
287
288static void
289test_rw_try_rlock(test_context *ctx)
290{
291        struct rwlock *rw = &ctx->rw;
292
293        puts("test rw try rlock");
294
295        rw_init(rw, "test");
296
297        rw_rlock(rw);
298        /* FIXME: We use a mutex implementation */
299        ctx->done = false;
300        ctx->rv = 1;
301        send_events(ctx, EVENT_TRY_RLOCK);
302        assert(ctx->done);
303        assert(ctx->rv == 0);
304        rw_unlock(rw);
305
306        rw_wlock(rw);
307        ctx->done = false;
308        ctx->rv = 1;
309        send_events(ctx, EVENT_TRY_RLOCK);
310        assert(ctx->done);
311        assert(ctx->rv == 0);
312        rw_unlock(rw);
313
314        rw_destroy(rw);
315}
316
317static void
318test_rw_try_wlock(test_context *ctx)
319{
320        struct rwlock *rw = &ctx->rw;
321
322        puts("test rw try wlock");
323
324        rw_init(rw, "test");
325
326        rw_rlock(rw);
327        ctx->done = false;
328        ctx->rv = 1;
329        send_events(ctx, EVENT_TRY_WLOCK);
330        assert(ctx->done);
331        assert(ctx->rv == 0);
332        rw_unlock(rw);
333
334        rw_wlock(rw);
335        ctx->done = false;
336        ctx->rv = 1;
337        send_events(ctx, EVENT_TRY_WLOCK);
338        assert(ctx->done);
339        assert(ctx->rv == 0);
340        rw_unlock(rw);
341
342        rw_destroy(rw);
343}
344
345static void
346test_rw_rlock(test_context *ctx)
347{
348        struct rwlock *rw = &ctx->rw;
349
350        puts("test rw rlock");
351
352        rw_init(rw, "test");
353
354        rw_rlock(rw);
355        /* FIXME: We use a mutex implementation */
356        ctx->done = false;
357        send_events(ctx, EVENT_RLOCK);
358        assert(!ctx->done);
359        rw_unlock(rw);
360        assert(ctx->done);
361        ctx->done = false;
362        send_events(ctx, EVENT_UNLOCK);
363        assert(ctx->done);
364
365        rw_wlock(rw);
366        ctx->done = false;
367        send_events(ctx, EVENT_RLOCK);
368        assert(!ctx->done);
369        rw_unlock(rw);
370        assert(ctx->done);
371        ctx->done = false;
372        send_events(ctx, EVENT_UNLOCK);
373        assert(ctx->done);
374
375        rw_destroy(rw);
376}
377
378static void
379test_rw_wlock(test_context *ctx)
380{
381        struct rwlock *rw = &ctx->rw;
382
383        puts("test rw rlock");
384
385        rw_init(rw, "test");
386
387        rw_rlock(rw);
388        ctx->done = false;
389        send_events(ctx, EVENT_WLOCK);
390        assert(!ctx->done);
391        rw_unlock(rw);
392        assert(ctx->done);
393        ctx->done = false;
394        send_events(ctx, EVENT_UNLOCK);
395        assert(ctx->done);
396
397        rw_wlock(rw);
398        ctx->done = false;
399        send_events(ctx, EVENT_WLOCK);
400        assert(!ctx->done);
401        rw_unlock(rw);
402        assert(ctx->done);
403        ctx->done = false;
404        send_events(ctx, EVENT_UNLOCK);
405        assert(ctx->done);
406
407        rw_destroy(rw);
408}
409
410static void
411test_rw_sleep_with_rlock(test_context *ctx)
412{
413        struct rwlock *rw = &ctx->rw;
414
415        puts("test rw sleep with rlock");
416
417        rw_init(rw, "test");
418
419        ctx->done = false;
420        send_events(ctx, EVENT_RLOCK);
421        assert(ctx->done);
422
423        ctx->done = false;
424        ctx->timo = 0;
425        send_events(ctx, EVENT_SLEEP);
426        assert(!ctx->done);
427
428        rw_rlock(rw);
429        wakeup(ctx);
430        /* FIXME: We use a mutex implementation */
431        assert(!ctx->done);
432        rw_unlock(rw);
433        /* FIXME: We use a mutex implementation */
434        assert(ctx->done);
435
436        ctx->done = false;
437        send_events(ctx, EVENT_UNLOCK);
438        assert(ctx->done);
439
440        rw_destroy(rw);
441}
442
443static void
444test_rw_sleep_with_wlock(test_context *ctx)
445{
446        struct rwlock *rw = &ctx->rw;
447
448        puts("test rw sleep with wlock");
449
450        rw_init(rw, "test");
451
452        ctx->done = false;
453        send_events(ctx, EVENT_WLOCK);
454        assert(ctx->done);
455
456        ctx->done = false;
457        ctx->timo = 0;
458        send_events(ctx, EVENT_SLEEP);
459        assert(!ctx->done);
460
461        rw_rlock(rw);
462        wakeup(ctx);
463        assert(!ctx->done);
464        rw_unlock(rw);
465        assert(ctx->done);
466
467        ctx->done = false;
468        send_events(ctx, EVENT_UNLOCK);
469        assert(ctx->done);
470
471        rw_destroy(rw);
472}
473
474static void
475test_rw_sleep_timeout(test_context *ctx)
476{
477        struct rwlock *rw = &ctx->rw;
478        rtems_status_code sc;
479
480        puts("test rw sleep timeout");
481
482        rw_init(rw, "test");
483
484        ctx->done = false;
485        send_events(ctx, EVENT_RLOCK);
486        assert(ctx->done);
487
488        ctx->done = false;
489        ctx->timo = 2;
490        send_events(ctx, EVENT_SLEEP);
491        assert(!ctx->done);
492
493        sc = rtems_task_wake_after(ctx->timo);
494        assert(sc == RTEMS_SUCCESSFUL);
495
496        assert(ctx->done);
497
498        ctx->done = false;
499        send_events(ctx, EVENT_UNLOCK);
500        assert(ctx->done);
501
502        rw_destroy(rw);
503}
504
505static void
506alloc_basic_resources(void)
507{
508        curthread;
509}
510
511static void
512test_main(void)
513{
514        rtems_resource_snapshot snapshot_0;
515        rtems_resource_snapshot snapshot_1;
516
517        test_context *ctx = &test_instance;
518
519        alloc_basic_resources();
520
521        rtems_resource_snapshot_take(&snapshot_0);
522
523        set_self_prio(PRIO_MASTER);
524        start_worker(ctx);
525
526        rtems_resource_snapshot_take(&snapshot_1);
527
528        test_rw_non_recursive(ctx);
529        test_rw_recursive(ctx);
530        test_rw_try_rlock(ctx);
531        test_rw_try_wlock(ctx);
532        test_rw_rlock(ctx);
533        test_rw_wlock(ctx);
534
535        assert(rtems_resource_snapshot_check(&snapshot_1));
536
537        test_rw_sleep_with_rlock(ctx);
538        test_rw_sleep_with_wlock(ctx);
539        test_rw_sleep_timeout(ctx);
540
541        delete_worker(ctx);
542
543        assert(rtems_resource_snapshot_check(&snapshot_0));
544
545        exit(0);
546}
547
548#include <rtems/bsd/test/default-init.h>
Note: See TracBrowser for help on using the repository browser.