Back to home page

LXR

 
 

    


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

0001 /* SPDX-License-Identifier: BSD-2-Clause */
0002 
0003 /*
0004  * Copyright (C) 2013, 2017 embedded brains GmbH & Co. KG
0005  *
0006  * Redistribution and use in source and binary forms, with or without
0007  * modification, are permitted provided that the following conditions
0008  * are met:
0009  * 1. Redistributions of source code must retain the above copyright
0010  *    notice, this list of conditions and the following disclaimer.
0011  * 2. Redistributions in binary form must reproduce the above copyright
0012  *    notice, this list of conditions and the following disclaimer in the
0013  *    documentation and/or other materials provided with the distribution.
0014  *
0015  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
0016  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
0017  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
0018  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
0019  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
0020  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
0021  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
0022  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
0023  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
0024  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
0025  * POSSIBILITY OF SUCH DAMAGE.
0026  */
0027 
0028 #ifdef HAVE_CONFIG_H
0029 #include "config.h"
0030 #endif
0031 
0032 #include "tmacros.h"
0033 
0034 const char rtems_test_name[] = "SMPSIGNAL 1";
0035 
0036 #define TEST_SIGNAL RTEMS_SIGNAL_0
0037 
0038 typedef enum {
0039   SIG_0_READY,
0040   SIG_0_SENT,
0041   SIG_0_ENABLE,
0042   SIG_0_PROCESSED,
0043   SIG_1_READY,
0044   SIG_1_SENT,
0045   SIG_1_PROCESSED
0046 } test_state;
0047 
0048 typedef struct {
0049   volatile test_state state;
0050   rtems_id consumer;
0051   rtems_id producer;
0052   uint32_t consumer_processor;
0053   uint32_t producer_processor;
0054   rtems_id timer;
0055   volatile bool done;
0056 } test_context;
0057 
0058 static void change_state(test_context *ctx, test_state new_state)
0059 {
0060   ctx->state = new_state;
0061 }
0062 
0063 static void wait_for_state(const test_context *ctx, test_state desired_state)
0064 {
0065   while ( ctx->state != desired_state ) {
0066     /* Wait */
0067   }
0068 }
0069 
0070 static test_context ctx_instance = {
0071   .state = SIG_0_READY
0072 };
0073 
0074 static void signal_handler(rtems_signal_set signal)
0075 {
0076   test_context *ctx = &ctx_instance;
0077 
0078   rtems_test_assert(_ISR_Get_level() == 0);
0079 
0080   switch (ctx->state) {
0081     case SIG_0_ENABLE:
0082       change_state(ctx, SIG_0_PROCESSED);
0083       break;
0084     case SIG_1_SENT:
0085       change_state(ctx, SIG_1_PROCESSED);
0086       break;
0087     default:
0088       rtems_test_assert(0);
0089   }
0090 }
0091 
0092 static void signal_send(test_context *ctx, test_state new_state)
0093 {
0094   rtems_status_code sc;
0095 
0096   change_state(ctx, new_state);
0097   sc = rtems_signal_send(ctx->consumer, TEST_SIGNAL);
0098   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0099 
0100 }
0101 
0102 static void check_consumer_processor(const test_context *ctx)
0103 {
0104   rtems_test_assert(
0105     ctx->consumer_processor == rtems_scheduler_get_processor()
0106   );
0107 }
0108 
0109 static void check_producer_processor(const test_context *ctx)
0110 {
0111   rtems_test_assert(
0112     ctx->producer_processor == rtems_scheduler_get_processor()
0113   );
0114 }
0115 
0116 static void producer(rtems_task_argument arg)
0117 {
0118   test_context *ctx = (test_context *) arg;
0119 
0120   ctx->producer_processor = rtems_scheduler_get_processor();
0121 
0122   rtems_test_assert(ctx->consumer_processor != ctx->producer_processor);
0123 
0124   wait_for_state(ctx, SIG_0_READY);
0125   signal_send(ctx, SIG_0_SENT);
0126 
0127   check_producer_processor(ctx);
0128 
0129   wait_for_state(ctx, SIG_1_READY);
0130   signal_send(ctx, SIG_1_SENT);
0131 
0132   check_producer_processor(ctx);
0133 
0134   rtems_task_suspend(RTEMS_SELF);
0135   rtems_test_assert(0);
0136 }
0137 
0138 static void test_two_processors(test_context *ctx)
0139 {
0140   rtems_status_code sc;
0141   rtems_mode mode;
0142 
0143   sc = rtems_signal_catch(signal_handler, RTEMS_DEFAULT_MODES);
0144   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0145 
0146   sc = rtems_task_create(
0147     rtems_build_name('P', 'R', 'O', 'D'),
0148     RTEMS_MINIMUM_PRIORITY,
0149     RTEMS_MINIMUM_STACK_SIZE,
0150     RTEMS_DEFAULT_MODES,
0151     RTEMS_DEFAULT_ATTRIBUTES,
0152     &ctx->producer
0153   );
0154   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0155 
0156   sc = rtems_task_start(ctx->producer, producer, (rtems_task_argument) ctx);
0157   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0158 
0159   check_consumer_processor(ctx);
0160 
0161   wait_for_state(ctx, SIG_0_SENT);
0162   change_state(ctx, SIG_0_ENABLE);
0163 
0164   sc = rtems_task_mode(RTEMS_ASR, RTEMS_ASR_MASK, &mode);
0165   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0166   rtems_test_assert(mode == RTEMS_NO_ASR);
0167 
0168   wait_for_state(ctx, SIG_0_PROCESSED);
0169 
0170   check_consumer_processor(ctx);
0171 
0172   change_state(ctx, SIG_1_READY);
0173   wait_for_state(ctx, SIG_1_PROCESSED);
0174 
0175   check_consumer_processor(ctx);
0176 }
0177 
0178 static void isr_level_timer(rtems_id timer, void *arg)
0179 {
0180   test_context *ctx = arg;
0181   rtems_status_code sc;
0182 
0183   sc = rtems_signal_send(ctx->consumer, TEST_SIGNAL);
0184   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0185 }
0186 
0187 static void isr_level_handler(rtems_signal_set signal)
0188 {
0189   test_context *ctx = &ctx_instance;
0190 
0191   rtems_test_assert(_ISR_Get_level() == 0);
0192 
0193   ctx->done = true;
0194 }
0195 
0196 static void test_isr_level(test_context *ctx)
0197 {
0198   rtems_status_code sc;
0199   rtems_mode mode;
0200 
0201   sc = rtems_task_mode(RTEMS_ASR, RTEMS_ASR_MASK, &mode);
0202   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0203   rtems_test_assert(mode == RTEMS_NO_ASR);
0204 
0205   sc = rtems_timer_create(rtems_build_name('T', 'I', 'M', 'R'), &ctx->timer);
0206   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0207 
0208   rtems_test_assert(!ctx->done);
0209 
0210   sc = rtems_signal_catch(isr_level_handler, RTEMS_DEFAULT_MODES);
0211   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0212 
0213   sc = rtems_timer_fire_after(ctx->timer, 1, isr_level_timer, ctx);
0214   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0215 
0216   while (!ctx->done) {
0217     /* Wait for timer */
0218   }
0219 
0220   sc = rtems_timer_delete(ctx->timer);
0221   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0222 
0223   sc = rtems_task_mode(RTEMS_NO_ASR, RTEMS_ASR_MASK, &mode);
0224   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0225   rtems_test_assert(mode == RTEMS_ASR);
0226 }
0227 
0228 static void Init(rtems_task_argument arg)
0229 {
0230   test_context *ctx = &ctx_instance;
0231 
0232   TEST_BEGIN();
0233 
0234   ctx->consumer = rtems_task_self();
0235   ctx->consumer_processor = rtems_scheduler_get_processor();
0236 
0237   test_isr_level(ctx);
0238 
0239   if (rtems_scheduler_get_processor_maximum() >= 2) {
0240     test_two_processors(ctx);
0241   }
0242 
0243   TEST_END();
0244   rtems_test_exit(0);
0245 }
0246 
0247 #define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
0248 #define CONFIGURE_APPLICATION_NEEDS_SIMPLE_CONSOLE_DRIVER
0249 
0250 #define CONFIGURE_MAXIMUM_PROCESSORS 2
0251 
0252 #define CONFIGURE_MAXIMUM_TASKS 2
0253 
0254 #define CONFIGURE_MAXIMUM_TIMERS 1
0255 
0256 #define CONFIGURE_INITIAL_EXTENSIONS RTEMS_TEST_INITIAL_EXTENSION
0257 
0258 #define CONFIGURE_RTEMS_INIT_TASKS_TABLE
0259 
0260 #define CONFIGURE_INIT_TASK_INITIAL_MODES RTEMS_NO_ASR
0261 
0262 #define CONFIGURE_INIT
0263 
0264 #include <rtems/confdefs.h>