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

5
Last change on this file since dab902d5 was dab902d5, checked in by Sebastian Huber <sebastian.huber@…>, on 05/17/16 at 13:43:31

testsuites: Avoid Giant lock

Replace _Thread_Disable_dispatch() with _Thread_Dispatch_disable().
Replace _Thread_Enable_dispatch() with _Thread_Dispatch_enable().

This is a preparation to remove the Giant lock.

Update #2555.

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