File indexing completed on 2025-05-11 08:24:49
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
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
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
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