source: rtems/testsuites/sptests/spthreadq01/init.c @ de59c065

5
Last change on this file since de59c065 was de59c065, checked in by Sebastian Huber <sebastian.huber@…>, on 09/27/17 at 13:08:33

posix: Implement self-contained POSIX mutex

POSIX mutexes are now available in all configurations and no longer
depend on --enable-posix.

Update #2514.
Update #3112.

  • Property mode set to 100644
File size: 7.0 KB
Line 
1/*
2 *  COPYRIGHT (c) 1989-2009.
3 *  On-Line Applications Research Corporation (OAR).
4 *
5 *  Copyright (c) 2016 embedded brains GmbH.
6 *
7 *  The license and distribution terms for this file may be
8 *  found in the file LICENSE in this distribution or at
9 *  http://www.rtems.org/license/LICENSE.
10 */
11
12#ifdef HAVE_CONFIG_H
13#include "config.h"
14#endif
15
16#include <tmacros.h>
17
18#include <rtems.h>
19
20#include <rtems/score/threadimpl.h>
21
22#if defined(RTEMS_POSIX_API)
23  #include <fcntl.h>
24  #include <mqueue.h>
25  #include <semaphore.h>
26  #include <string.h>
27  #include <pthread.h>
28#endif
29
30const char rtems_test_name[] = "SPTHREADQ 1";
31
32static Thread_queue_Control queue = THREAD_QUEUE_INITIALIZER( "Queue" );
33
34typedef struct {
35  Thread_Control *master;
36  rtems_id master_id;
37  rtems_id worker_id;
38  rtems_id sem;
39  rtems_id mtx;
40  rtems_id mq;
41  rtems_id br;
42#if defined(RTEMS_POSIX_API)
43  mqd_t pmq;
44#endif
45} test_context;
46
47static test_context test_instance;
48
49static void wait_for_worker(test_context *ctx)
50{
51  rtems_status_code sc;
52
53  sc = rtems_event_transient_receive(RTEMS_WAIT, RTEMS_NO_TIMEOUT);
54  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
55}
56
57static void wake_up_master(test_context *ctx)
58{
59  rtems_status_code sc;
60
61  sc = rtems_event_transient_send(ctx->master_id);
62  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
63}
64
65static rtems_id get_wait_id(test_context *ctx)
66{
67  Thread_queue_Context queue_context;
68  rtems_id id;
69
70  _Thread_queue_Context_initialize(&queue_context);
71  _Thread_Wait_acquire(ctx->master, &queue_context);
72  id = _Thread_Wait_get_id(ctx->master);
73  _Thread_Wait_release(ctx->master, &queue_context);
74
75  return id;
76}
77
78static void classic_worker(test_context *ctx)
79{
80  rtems_status_code sc;
81  char buf[1];
82
83  wake_up_master(ctx);
84  rtems_test_assert(get_wait_id(ctx) == ctx->sem);
85
86  sc = rtems_semaphore_release(ctx->sem);
87  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
88
89  sc = rtems_semaphore_obtain(ctx->mtx, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
90  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
91
92  wake_up_master(ctx);
93  rtems_test_assert(get_wait_id(ctx) == ctx->mtx);
94
95  sc = rtems_semaphore_release(ctx->mtx);
96  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
97
98  wake_up_master(ctx);
99  rtems_test_assert(get_wait_id(ctx) == ctx->mq);
100
101  buf[0] = 'X';
102  sc = rtems_message_queue_send(ctx->mq, &buf[0], sizeof(buf));
103  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
104
105  wake_up_master(ctx);
106  rtems_test_assert(get_wait_id(ctx) == ctx->br);
107
108  sc = rtems_barrier_wait(ctx->br, RTEMS_NO_TIMEOUT);
109  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
110}
111
112static void posix_worker(test_context *ctx)
113{
114#if defined(RTEMS_POSIX_API)
115  int rv;
116  int eno;
117  char buf[1];
118
119  wake_up_master(ctx);
120  rtems_test_assert(get_wait_id(ctx) == ctx->pmq);
121
122  buf[0] = 'x';
123  rv = mq_send(ctx->pmq, &buf[0], sizeof(buf), 0);
124  rtems_test_assert(rv == 0);
125#endif
126}
127
128static rtems_task worker(rtems_task_argument arg)
129{
130  test_context *ctx = (test_context *) arg;
131
132  rtems_test_assert(get_wait_id(ctx) == 0);
133
134  classic_worker(ctx);
135  posix_worker(ctx);
136}
137
138static void test_classic_init(test_context *ctx)
139{
140  rtems_status_code sc;
141
142  sc = rtems_semaphore_create(
143    rtems_build_name('S', 'E', 'M', ' '),
144    0,
145    RTEMS_COUNTING_SEMAPHORE,
146    0,
147    &ctx->sem
148  );
149  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
150
151  sc = rtems_semaphore_create(
152    rtems_build_name('M', 'T', 'X', ' '),
153    1,
154    RTEMS_BINARY_SEMAPHORE | RTEMS_PRIORITY | RTEMS_INHERIT_PRIORITY,
155    0,
156    &ctx->mtx
157  );
158  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
159
160  sc = rtems_message_queue_create(
161    rtems_build_name('M', 'Q', ' ', ' '),
162    1,
163    1,
164    RTEMS_DEFAULT_ATTRIBUTES,
165    &ctx->mq
166  );
167  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
168
169  sc = rtems_barrier_create(
170    rtems_build_name('B', 'R', ' ', ' '),
171    RTEMS_BARRIER_AUTOMATIC_RELEASE,
172    2,
173    &ctx->br
174  );
175  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
176}
177
178static void test_posix_init(test_context *ctx)
179{
180#if defined(RTEMS_POSIX_API)
181  int eno;
182  struct mq_attr attr;
183
184  memset(&attr, 0, sizeof(attr));
185  attr.mq_maxmsg = 1;
186  attr.mq_msgsize = sizeof(char);
187
188  ctx->pmq = mq_open("mq", O_CREAT | O_RDWR, 0x777, &attr);
189  rtems_test_assert(ctx->mq != -1);
190#endif
191}
192
193static void test_context_init(test_context *ctx)
194{
195  rtems_status_code sc;
196
197  ctx->master = _Thread_Get_executing();
198  ctx->master_id = rtems_task_self();
199
200  test_classic_init(ctx);
201  test_posix_init(ctx);
202
203  sc = rtems_task_create(
204    rtems_build_name('W', 'O', 'R', 'K'),
205    2,
206    RTEMS_MINIMUM_STACK_SIZE,
207    RTEMS_DEFAULT_MODES,
208    RTEMS_DEFAULT_ATTRIBUTES,
209    &ctx->worker_id
210  );
211  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
212
213  sc = rtems_task_start(ctx->worker_id, worker, (rtems_task_argument) ctx);
214  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
215}
216
217static void test_classic_obj(test_context *ctx)
218{
219  rtems_status_code sc;
220  char buf[1];
221  size_t n;
222
223  wait_for_worker(ctx);
224
225  sc = rtems_semaphore_obtain(ctx->sem, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
226  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
227
228  wait_for_worker(ctx);
229
230  sc = rtems_semaphore_obtain(ctx->mtx, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
231  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
232
233  wait_for_worker(ctx);
234
235  buf[0] = 'Y';
236  n = 123;
237  sc = rtems_message_queue_receive(
238    ctx->mq,
239    &buf[0],
240    &n,
241    RTEMS_WAIT,
242    RTEMS_NO_TIMEOUT
243  );
244  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
245  rtems_test_assert(buf[0] == 'X');
246  rtems_test_assert(n == sizeof(buf));
247
248  wait_for_worker(ctx);
249
250  sc = rtems_barrier_wait(ctx->br, RTEMS_NO_TIMEOUT);
251  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
252}
253
254static void test_posix_obj(test_context *ctx)
255{
256#if defined(RTEMS_POSIX_API)
257  int eno;
258  char buf[1];
259  unsigned prio;
260  ssize_t n;
261
262  wait_for_worker(ctx);
263
264  buf[0] = 'y';
265  prio = 1;
266  n = mq_receive(ctx->pmq, &buf[0], sizeof(buf), &prio);
267  rtems_test_assert(n == (ssize_t) sizeof(buf));
268  rtems_test_assert(buf[0] == 'x');
269  rtems_test_assert(prio == 0);
270#endif
271}
272
273static rtems_task Init(
274  rtems_task_argument ignored
275)
276{
277  test_context *ctx = &test_instance;
278
279  TEST_BEGIN();
280
281  puts( "Init - _Thread_queue_Extract - thread not blocked on a thread queue" );
282  _Thread_queue_Extract( _Thread_Get_executing() );
283  /* is there more to check? */
284
285  test_context_init(ctx);
286  test_classic_obj(ctx);
287  test_posix_obj(ctx);
288
289  rtems_test_assert( _Thread_queue_Is_empty( &queue.Queue ) );
290
291  TEST_END();
292  rtems_test_exit(0);
293}
294
295/* configuration information */
296
297#define CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER
298#define CONFIGURE_APPLICATION_DOES_NOT_NEED_CLOCK_DRIVER
299
300#define CONFIGURE_MAXIMUM_TASKS  2
301#define CONFIGURE_MAXIMUM_SEMAPHORES  2
302#define CONFIGURE_MAXIMUM_MESSAGE_QUEUES  1
303#define CONFIGURE_MAXIMUM_BARRIERS  1
304
305#if defined(RTEMS_POSIX_API)
306  #define CONFIGURE_MAXIMUM_POSIX_MESSAGE_QUEUES 1
307  #define CONFIGURE_MESSAGE_BUFFER_MEMORY \
308    (2 * CONFIGURE_MESSAGE_BUFFERS_FOR_QUEUE(1, 1))
309#else
310  #define CONFIGURE_MESSAGE_BUFFER_MEMORY \
311    CONFIGURE_MESSAGE_BUFFERS_FOR_QUEUE(1, 1)
312#endif
313
314#define CONFIGURE_INITIAL_EXTENSIONS RTEMS_TEST_INITIAL_EXTENSION
315
316#define CONFIGURE_RTEMS_INIT_TASKS_TABLE
317
318#define CONFIGURE_INIT
319#include <rtems/confdefs.h>
320
321/* global variables */
Note: See TracBrowser for help on using the repository browser.