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

5
Last change on this file since b466226 was b466226, checked in by Sebastian Huber <sebastian.huber@…>, on 04/20/16 at 04:57:47

score: Add _Thread_queue_Is_empty()

  • Property mode set to 100644
File size: 9.3 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
29  #include <rtems/posix/mqueueimpl.h>
30#endif
31
32const char rtems_test_name[] = "SPTHREADQ 1";
33
34static Thread_queue_Control queue = THREAD_QUEUE_INITIALIZER( "Queue" );
35
36typedef struct {
37  Thread_Control *master;
38  rtems_id master_id;
39  rtems_id worker_id;
40  rtems_id sem;
41  rtems_id mtx;
42  rtems_id mq;
43  rtems_id br;
44#if defined(RTEMS_POSIX_API)
45  sem_t psem;
46  pthread_mutex_t pmtx;
47  pthread_cond_t pcv;
48  pthread_rwlock_t prw;
49  mqd_t pmq;
50#endif
51} test_context;
52
53static test_context test_instance;
54
55static void wait_for_worker(test_context *ctx)
56{
57  rtems_status_code sc;
58
59  sc = rtems_event_transient_receive(RTEMS_WAIT, RTEMS_NO_TIMEOUT);
60  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
61}
62
63static void wake_up_master(test_context *ctx)
64{
65  rtems_status_code sc;
66
67  sc = rtems_event_transient_send(ctx->master_id);
68  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
69}
70
71static rtems_id get_wait_id(test_context *ctx)
72{
73  ISR_lock_Context lock_context;
74  void *lock;
75  rtems_id id;
76
77  lock = _Thread_Lock_acquire(ctx->master, &lock_context);
78  id = _Thread_Wait_get_id(ctx->master);
79  _Thread_Lock_release(lock, &lock_context);
80
81  return id;
82}
83
84static void classic_worker(test_context *ctx)
85{
86  rtems_status_code sc;
87  char buf[1];
88
89  wake_up_master(ctx);
90  rtems_test_assert(get_wait_id(ctx) == ctx->sem);
91
92  sc = rtems_semaphore_release(ctx->sem);
93  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
94
95  sc = rtems_semaphore_obtain(ctx->mtx, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
96  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
97
98  wake_up_master(ctx);
99  rtems_test_assert(get_wait_id(ctx) == ctx->mtx);
100
101  sc = rtems_semaphore_release(ctx->mtx);
102  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
103
104  wake_up_master(ctx);
105  rtems_test_assert(get_wait_id(ctx) == ctx->mq);
106
107  buf[0] = 'X';
108  sc = rtems_message_queue_send(ctx->mq, &buf[0], sizeof(buf));
109  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
110
111  wake_up_master(ctx);
112  rtems_test_assert(get_wait_id(ctx) == ctx->br);
113
114  sc = rtems_barrier_wait(ctx->br, RTEMS_NO_TIMEOUT);
115  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
116}
117
118static void posix_worker(test_context *ctx)
119{
120#if defined(RTEMS_POSIX_API)
121  int rv;
122  int eno;
123  char buf[1];
124  POSIX_Message_queue_Control_fd *the_mq_fd;
125  Objects_Locations location;
126  ISR_lock_Context lock_context;
127
128  wake_up_master(ctx);
129  rtems_test_assert(get_wait_id(ctx) == ctx->psem);
130
131  rv = sem_post(&ctx->psem);
132  rtems_test_assert(rv == 0);
133
134  eno = pthread_mutex_lock(&ctx->pmtx);
135  rtems_test_assert(eno == 0);
136
137  wake_up_master(ctx);
138  rtems_test_assert(get_wait_id(ctx) == ctx->pmtx);
139
140  eno = pthread_mutex_unlock(&ctx->pmtx);
141  rtems_test_assert(eno == 0);
142
143  eno = pthread_mutex_lock(&ctx->pmtx);
144  rtems_test_assert(eno == 0);
145
146  rtems_test_assert(get_wait_id(ctx) == ctx->pcv);
147
148  eno = pthread_cond_signal(&ctx->pcv);
149  rtems_test_assert(eno == 0);
150
151  eno = pthread_mutex_unlock(&ctx->pmtx);
152  rtems_test_assert(eno == 0);
153
154  eno = pthread_rwlock_wrlock(&ctx->prw);
155  rtems_test_assert(eno == 0);
156
157  wake_up_master(ctx);
158  rtems_test_assert(get_wait_id(ctx) == ctx->prw);
159
160  eno = pthread_rwlock_unlock(&ctx->prw);
161  rtems_test_assert(eno == 0);
162
163  wake_up_master(ctx);
164  the_mq_fd = _POSIX_Message_queue_Get_fd_interrupt_disable(
165    ctx->pmq,
166    &location,
167    &lock_context
168  );
169  _ISR_lock_ISR_enable(&lock_context);
170  rtems_test_assert(the_mq_fd != NULL);
171  rtems_test_assert(location == OBJECTS_LOCAL);
172  rtems_test_assert(get_wait_id(ctx) == the_mq_fd->Queue->Object.id);
173
174  buf[0] = 'x';
175  rv = mq_send(ctx->pmq, &buf[0], sizeof(buf), 0);
176  rtems_test_assert(rv == 0);
177#endif
178}
179
180static rtems_task worker(rtems_task_argument arg)
181{
182  test_context *ctx = (test_context *) arg;
183
184  rtems_test_assert(get_wait_id(ctx) == 0);
185
186  classic_worker(ctx);
187  posix_worker(ctx);
188}
189
190static void test_classic_init(test_context *ctx)
191{
192  rtems_status_code sc;
193
194  sc = rtems_semaphore_create(
195    rtems_build_name('S', 'E', 'M', ' '),
196    0,
197    RTEMS_COUNTING_SEMAPHORE,
198    0,
199    &ctx->sem
200  );
201  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
202
203  sc = rtems_semaphore_create(
204    rtems_build_name('M', 'T', 'X', ' '),
205    1,
206    RTEMS_BINARY_SEMAPHORE | RTEMS_PRIORITY | RTEMS_INHERIT_PRIORITY,
207    0,
208    &ctx->mtx
209  );
210  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
211
212  sc = rtems_message_queue_create(
213    rtems_build_name('M', 'Q', ' ', ' '),
214    1,
215    1,
216    RTEMS_DEFAULT_ATTRIBUTES,
217    &ctx->mq
218  );
219  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
220
221  sc = rtems_barrier_create(
222    rtems_build_name('B', 'R', ' ', ' '),
223    RTEMS_BARRIER_AUTOMATIC_RELEASE,
224    2,
225    &ctx->br
226  );
227  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
228}
229
230static void test_posix_init(test_context *ctx)
231{
232#if defined(RTEMS_POSIX_API)
233  int rv;
234  int eno;
235  struct mq_attr attr;
236
237  rv = sem_init(&ctx->psem, 0, 0);
238  rtems_test_assert(rv == 0);
239
240  eno = pthread_mutex_init(&ctx->pmtx, NULL);
241  rtems_test_assert(eno == 0);
242
243  eno = pthread_cond_init(&ctx->pcv, NULL);
244  rtems_test_assert(eno == 0);
245
246  eno = pthread_rwlock_init(&ctx->prw, NULL);
247  rtems_test_assert(eno == 0);
248
249  memset(&attr, 0, sizeof(attr));
250  attr.mq_maxmsg = 1;
251  attr.mq_msgsize = sizeof(char);
252
253  ctx->pmq = mq_open("mq", O_CREAT | O_RDWR, 0x777, &attr);
254  rtems_test_assert(ctx->mq != -1);
255#endif
256}
257
258static void test_context_init(test_context *ctx)
259{
260  rtems_status_code sc;
261
262  ctx->master = _Thread_Get_executing();
263  ctx->master_id = rtems_task_self();
264
265  test_classic_init(ctx);
266  test_posix_init(ctx);
267
268  sc = rtems_task_create(
269    rtems_build_name('W', 'O', 'R', 'K'),
270    2,
271    RTEMS_MINIMUM_STACK_SIZE,
272    RTEMS_DEFAULT_MODES,
273    RTEMS_DEFAULT_ATTRIBUTES,
274    &ctx->worker_id
275  );
276  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
277
278  sc = rtems_task_start(ctx->worker_id, worker, (rtems_task_argument) ctx);
279  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
280}
281
282static void test_classic_obj(test_context *ctx)
283{
284  rtems_status_code sc;
285  char buf[1];
286  size_t n;
287
288  wait_for_worker(ctx);
289
290  sc = rtems_semaphore_obtain(ctx->sem, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
291  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
292
293  wait_for_worker(ctx);
294
295  sc = rtems_semaphore_obtain(ctx->mtx, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
296  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
297
298  wait_for_worker(ctx);
299
300  buf[0] = 'Y';
301  n = 123;
302  sc = rtems_message_queue_receive(
303    ctx->mq,
304    &buf[0],
305    &n,
306    RTEMS_WAIT,
307    RTEMS_NO_TIMEOUT
308  );
309  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
310  rtems_test_assert(buf[0] == 'X');
311  rtems_test_assert(n == sizeof(buf));
312
313  wait_for_worker(ctx);
314
315  sc = rtems_barrier_wait(ctx->br, RTEMS_NO_TIMEOUT);
316  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
317}
318
319static void test_posix_obj(test_context *ctx)
320{
321#if defined(RTEMS_POSIX_API)
322  int rv;
323  int eno;
324  char buf[1];
325  unsigned prio;
326  ssize_t n;
327
328  wait_for_worker(ctx);
329
330  rv = sem_wait(&ctx->psem);
331  rtems_test_assert(rv == 0);
332
333  wait_for_worker(ctx);
334
335  eno = pthread_mutex_lock(&ctx->pmtx);
336  rtems_test_assert(eno == 0);
337
338  eno = pthread_cond_wait(&ctx->pcv, &ctx->pmtx);
339  rtems_test_assert(eno == 0);
340
341  eno = pthread_mutex_unlock(&ctx->pmtx);
342  rtems_test_assert(eno == 0);
343
344  wait_for_worker(ctx);
345
346  eno = pthread_rwlock_wrlock(&ctx->prw);
347  rtems_test_assert(eno == 0);
348
349  wait_for_worker(ctx);
350
351  buf[0] = 'y';
352  prio = 1;
353  n = mq_receive(ctx->pmq, &buf[0], sizeof(buf), &prio);
354  rtems_test_assert(n == (ssize_t) sizeof(buf));
355  rtems_test_assert(buf[0] == 'x');
356  rtems_test_assert(prio == 0);
357#endif
358}
359
360static rtems_task Init(
361  rtems_task_argument ignored
362)
363{
364  test_context *ctx = &test_instance;
365
366  TEST_BEGIN();
367
368  puts( "Init - _Thread_queue_Extract - thread not blocked on a thread queue" );
369  _Thread_Disable_dispatch();
370  _Thread_queue_Extract( _Thread_Executing );
371  _Thread_Enable_dispatch();
372  /* is there more to check? */
373
374  test_context_init(ctx);
375  test_classic_obj(ctx);
376  test_posix_obj(ctx);
377
378  rtems_test_assert( _Thread_queue_Is_empty( &queue.Queue ) );
379
380  TEST_END();
381  rtems_test_exit(0);
382}
383
384/* configuration information */
385
386#define CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER
387#define CONFIGURE_APPLICATION_DOES_NOT_NEED_CLOCK_DRIVER
388
389#define CONFIGURE_MAXIMUM_TASKS  2
390#define CONFIGURE_MAXIMUM_SEMAPHORES  2
391#define CONFIGURE_MAXIMUM_MESSAGE_QUEUES  1
392#define CONFIGURE_MAXIMUM_BARRIERS  1
393
394#if defined(RTEMS_POSIX_API)
395  #define CONFIGURE_MAXIMUM_POSIX_SEMAPHORES 1
396  #define CONFIGURE_MAXIMUM_POSIX_MUTEXES 1
397  #define CONFIGURE_MAXIMUM_POSIX_CONDITION_VARIABLES 1
398  #define CONFIGURE_MAXIMUM_POSIX_RWLOCKS 1
399  #define CONFIGURE_MAXIMUM_POSIX_MESSAGE_QUEUES 1
400  #define CONFIGURE_MAXIMUM_POSIX_MESSAGE_QUEUE_DESCRIPTORS 1
401  #define CONFIGURE_MESSAGE_BUFFER_MEMORY \
402    (2 * CONFIGURE_MESSAGE_BUFFERS_FOR_QUEUE(1, 1))
403#else
404  #define CONFIGURE_MESSAGE_BUFFER_MEMORY \
405    CONFIGURE_MESSAGE_BUFFERS_FOR_QUEUE(1, 1)
406#endif
407
408#define CONFIGURE_INITIAL_EXTENSIONS RTEMS_TEST_INITIAL_EXTENSION
409
410#define CONFIGURE_RTEMS_INIT_TASKS_TABLE
411
412#define CONFIGURE_INIT
413#include <rtems/confdefs.h>
414
415/* global variables */
Note: See TracBrowser for help on using the repository browser.