Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:24:49

0001 /* SPDX-License-Identifier: BSD-2-Clause */
0002 
0003 /*
0004  *  COPYRIGHT (c) 1989-2009.
0005  *  On-Line Applications Research Corporation (OAR).
0006  *
0007  *  Copyright (c) 2016 embedded brains GmbH & Co. KG
0008  *
0009  * Redistribution and use in source and binary forms, with or without
0010  * modification, are permitted provided that the following conditions
0011  * are met:
0012  * 1. Redistributions of source code must retain the above copyright
0013  *    notice, this list of conditions and the following disclaimer.
0014  * 2. Redistributions in binary form must reproduce the above copyright
0015  *    notice, this list of conditions and the following disclaimer in the
0016  *    documentation and/or other materials provided with the distribution.
0017  *
0018  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
0019  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
0020  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
0021  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
0022  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
0023  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
0024  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
0025  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
0026  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
0027  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
0028  * POSSIBILITY OF SUCH DAMAGE.
0029  */
0030 
0031 #ifdef HAVE_CONFIG_H
0032 #include "config.h"
0033 #endif
0034 
0035 #include <tmacros.h>
0036 
0037 #include <rtems.h>
0038 
0039 #include <rtems/score/threadimpl.h>
0040 
0041 #include <fcntl.h>
0042 #include <mqueue.h>
0043 #include <semaphore.h>
0044 #include <string.h>
0045 #include <pthread.h>
0046 
0047 const char rtems_test_name[] = "SPTHREADQ 1";
0048 
0049 static Thread_queue_Control queue = THREAD_QUEUE_INITIALIZER( "Queue" );
0050 
0051 typedef struct {
0052   Thread_Control *master;
0053   rtems_id master_id;
0054   rtems_id worker_id;
0055   rtems_id sem;
0056   rtems_id mtx;
0057   rtems_id mq;
0058   rtems_id br;
0059   mqd_t pmq;
0060 } test_context;
0061 
0062 static test_context test_instance;
0063 
0064 static void wait_for_worker(test_context *ctx)
0065 {
0066   rtems_status_code sc;
0067 
0068   sc = rtems_event_transient_receive(RTEMS_WAIT, RTEMS_NO_TIMEOUT);
0069   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0070 }
0071 
0072 static void wake_up_master(test_context *ctx)
0073 {
0074   rtems_status_code sc;
0075 
0076   sc = rtems_event_transient_send(ctx->master_id);
0077   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0078 }
0079 
0080 static rtems_id get_wait_id(test_context *ctx)
0081 {
0082   Thread_queue_Context queue_context;
0083   rtems_id id;
0084 
0085   _Thread_queue_Context_initialize(&queue_context);
0086   _Thread_Wait_acquire(ctx->master, &queue_context);
0087   id = _Thread_Wait_get_id(ctx->master);
0088   _Thread_Wait_release(ctx->master, &queue_context);
0089 
0090   return id;
0091 }
0092 
0093 static void classic_worker(test_context *ctx)
0094 {
0095   rtems_status_code sc;
0096   char buf[1];
0097 
0098   wake_up_master(ctx);
0099   rtems_test_assert(get_wait_id(ctx) == ctx->sem);
0100 
0101   sc = rtems_semaphore_release(ctx->sem);
0102   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0103 
0104   sc = rtems_semaphore_obtain(ctx->mtx, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
0105   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0106 
0107   wake_up_master(ctx);
0108   rtems_test_assert(get_wait_id(ctx) == ctx->mtx);
0109 
0110   sc = rtems_semaphore_release(ctx->mtx);
0111   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0112 
0113   wake_up_master(ctx);
0114   rtems_test_assert(get_wait_id(ctx) == ctx->mq);
0115 
0116   buf[0] = 'X';
0117   sc = rtems_message_queue_send(ctx->mq, &buf[0], sizeof(buf));
0118   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0119 
0120   wake_up_master(ctx);
0121   rtems_test_assert(get_wait_id(ctx) == ctx->br);
0122 
0123   sc = rtems_barrier_wait(ctx->br, RTEMS_NO_TIMEOUT);
0124   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0125 }
0126 
0127 static void posix_worker(test_context *ctx)
0128 {
0129   int rv;
0130   char buf[1];
0131 
0132   wake_up_master(ctx);
0133   rtems_test_assert(get_wait_id(ctx) == ctx->pmq);
0134 
0135   buf[0] = 'x';
0136   rv = mq_send(ctx->pmq, &buf[0], sizeof(buf), 0);
0137   rtems_test_assert(rv == 0);
0138 }
0139 
0140 static rtems_task worker(rtems_task_argument arg)
0141 {
0142   test_context *ctx = (test_context *) arg;
0143 
0144   rtems_test_assert(get_wait_id(ctx) == 0);
0145 
0146   classic_worker(ctx);
0147   posix_worker(ctx);
0148 }
0149 
0150 static void test_classic_init(test_context *ctx)
0151 {
0152   rtems_status_code sc;
0153 
0154   sc = rtems_semaphore_create(
0155     rtems_build_name('S', 'E', 'M', ' '),
0156     0,
0157     RTEMS_COUNTING_SEMAPHORE,
0158     0,
0159     &ctx->sem
0160   );
0161   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0162 
0163   sc = rtems_semaphore_create(
0164     rtems_build_name('M', 'T', 'X', ' '),
0165     1,
0166     RTEMS_BINARY_SEMAPHORE | RTEMS_PRIORITY | RTEMS_INHERIT_PRIORITY,
0167     0,
0168     &ctx->mtx
0169   );
0170   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0171 
0172   sc = rtems_message_queue_create(
0173     rtems_build_name('M', 'Q', ' ', ' '),
0174     1,
0175     1,
0176     RTEMS_DEFAULT_ATTRIBUTES,
0177     &ctx->mq
0178   );
0179   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0180 
0181   sc = rtems_barrier_create(
0182     rtems_build_name('B', 'R', ' ', ' '),
0183     RTEMS_BARRIER_AUTOMATIC_RELEASE,
0184     2,
0185     &ctx->br
0186   );
0187   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0188 }
0189 
0190 static void test_posix_init(test_context *ctx)
0191 {
0192   struct mq_attr attr;
0193 
0194   memset(&attr, 0, sizeof(attr));
0195   attr.mq_maxmsg = 1;
0196   attr.mq_msgsize = sizeof(char);
0197 
0198   ctx->pmq = mq_open("mq", O_CREAT | O_RDWR, 0x777, &attr);
0199   rtems_test_assert(ctx->mq != -1);
0200 }
0201 
0202 static void test_context_init(test_context *ctx)
0203 {
0204   rtems_status_code sc;
0205 
0206   ctx->master = _Thread_Get_executing();
0207   ctx->master_id = rtems_task_self();
0208 
0209   test_classic_init(ctx);
0210   test_posix_init(ctx);
0211 
0212   sc = rtems_task_create(
0213     rtems_build_name('W', 'O', 'R', 'K'),
0214     2,
0215     RTEMS_MINIMUM_STACK_SIZE,
0216     RTEMS_DEFAULT_MODES,
0217     RTEMS_DEFAULT_ATTRIBUTES,
0218     &ctx->worker_id
0219   );
0220   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0221 
0222   sc = rtems_task_start(ctx->worker_id, worker, (rtems_task_argument) ctx);
0223   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0224 }
0225 
0226 static void test_classic_obj(test_context *ctx)
0227 {
0228   rtems_status_code sc;
0229   char buf[1];
0230   size_t n;
0231 
0232   wait_for_worker(ctx);
0233 
0234   sc = rtems_semaphore_obtain(ctx->sem, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
0235   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0236 
0237   wait_for_worker(ctx);
0238 
0239   sc = rtems_semaphore_obtain(ctx->mtx, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
0240   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0241 
0242   wait_for_worker(ctx);
0243 
0244   buf[0] = 'Y';
0245   n = 123;
0246   sc = rtems_message_queue_receive(
0247     ctx->mq,
0248     &buf[0],
0249     &n,
0250     RTEMS_WAIT,
0251     RTEMS_NO_TIMEOUT
0252   );
0253   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0254   rtems_test_assert(buf[0] == 'X');
0255   rtems_test_assert(n == sizeof(buf));
0256 
0257   wait_for_worker(ctx);
0258 
0259   sc = rtems_barrier_wait(ctx->br, RTEMS_NO_TIMEOUT);
0260   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0261 }
0262 
0263 static void test_posix_obj(test_context *ctx)
0264 {
0265   char buf[1];
0266   unsigned prio;
0267   ssize_t n;
0268 
0269   wait_for_worker(ctx);
0270 
0271   buf[0] = 'y';
0272   prio = 1;
0273   n = mq_receive(ctx->pmq, &buf[0], sizeof(buf), &prio);
0274   rtems_test_assert(n == (ssize_t) sizeof(buf));
0275   rtems_test_assert(buf[0] == 'x');
0276   rtems_test_assert(prio == 0);
0277 }
0278 
0279 static rtems_task Init(
0280   rtems_task_argument ignored
0281 )
0282 {
0283   test_context *ctx = &test_instance;
0284 
0285   TEST_BEGIN();
0286 
0287   puts( "Init - _Thread_queue_Extract - thread not blocked on a thread queue" );
0288   _Thread_queue_Extract( _Thread_Get_executing() );
0289   /* is there more to check? */
0290 
0291   test_context_init(ctx);
0292   test_classic_obj(ctx);
0293   test_posix_obj(ctx);
0294 
0295   rtems_test_assert( _Thread_queue_Is_empty( &queue.Queue ) );
0296 
0297   TEST_END();
0298   rtems_test_exit(0);
0299 }
0300 
0301 /* configuration information */
0302 
0303 #define CONFIGURE_APPLICATION_NEEDS_SIMPLE_CONSOLE_DRIVER
0304 #define CONFIGURE_APPLICATION_DOES_NOT_NEED_CLOCK_DRIVER
0305 
0306 #define CONFIGURE_MAXIMUM_TASKS  2
0307 #define CONFIGURE_MAXIMUM_SEMAPHORES  2
0308 #define CONFIGURE_MAXIMUM_MESSAGE_QUEUES  1
0309 #define CONFIGURE_MAXIMUM_BARRIERS  1
0310 
0311 #define CONFIGURE_MAXIMUM_POSIX_MESSAGE_QUEUES 1
0312 #define CONFIGURE_MESSAGE_BUFFER_MEMORY \
0313   (2 * CONFIGURE_MESSAGE_BUFFERS_FOR_QUEUE(1, 1))
0314 
0315 #define CONFIGURE_INITIAL_EXTENSIONS RTEMS_TEST_INITIAL_EXTENSION
0316 
0317 #define CONFIGURE_RTEMS_INIT_TASKS_TABLE
0318 
0319 #define CONFIGURE_INIT
0320 #include <rtems/confdefs.h>
0321 
0322 /* global variables */