Back to home page

LXR

 
 

    


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

0001 /* SPDX-License-Identifier: BSD-2-Clause */
0002 
0003 /*
0004  * Copyright (C) 2014, 2020 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 #include <rtems/test.h>
0034 
0035 #include <rtems/rtems/semimpl.h>
0036 
0037 const char rtems_test_name[] = "SPINTRCRITICAL 22";
0038 
0039 typedef struct {
0040   rtems_id semaphore_id;
0041   Semaphore_Control *semaphore_control;
0042   Thread_Control *main_task_control;
0043 } test_context;
0044 
0045 static Semaphore_Control *get_semaphore_control(rtems_id id)
0046 {
0047   Thread_queue_Context queue_context;
0048   Semaphore_Control *sem;
0049 
0050   sem = _Semaphore_Get(id, &queue_context);
0051   rtems_test_assert(sem != NULL);
0052   _ISR_lock_ISR_enable(&queue_context.Lock_context.Lock_context);
0053 
0054   return sem;
0055 }
0056 
0057 static T_interrupt_test_state release_semaphore(void *arg)
0058 {
0059   test_context *ctx = arg;
0060   rtems_status_code sc;
0061   Thread_Wait_flags flags;
0062   T_interrupt_test_state state;
0063 
0064   flags = _Thread_Wait_flags_get(ctx->main_task_control);
0065 
0066   if (
0067     flags == (THREAD_WAIT_CLASS_OBJECT | THREAD_WAIT_STATE_INTEND_TO_BLOCK)
0068   ) {
0069     CORE_semaphore_Control *sem;
0070 
0071     state = T_INTERRUPT_TEST_DONE;
0072 
0073     sc = rtems_semaphore_release(ctx->semaphore_id);
0074     rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0075 
0076     rtems_test_assert(
0077       _Thread_Wait_flags_get(ctx->main_task_control)
0078         == THREAD_WAIT_STATE_READY
0079     );
0080     sem = &ctx->semaphore_control->Core_control.Semaphore;
0081     rtems_test_assert(sem->count == 0);
0082   } else {
0083     if (flags == (THREAD_WAIT_CLASS_OBJECT | THREAD_WAIT_STATE_BLOCKED)) {
0084       state = T_INTERRUPT_TEST_LATE;
0085     } else {
0086       state = T_INTERRUPT_TEST_EARLY;
0087     }
0088 
0089     sc = rtems_semaphore_release(ctx->semaphore_id);
0090     rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0091   }
0092 
0093   return state;
0094 }
0095 
0096 static void action(void *arg)
0097 {
0098   test_context *ctx = arg;
0099   rtems_status_code sc;
0100 
0101   sc = rtems_semaphore_obtain(
0102     ctx->semaphore_id,
0103     RTEMS_WAIT,
0104     2
0105   );
0106   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0107 }
0108 
0109 static void prepare(void *arg)
0110 {
0111   test_context *ctx = arg;
0112   rtems_status_code sc;
0113 
0114   sc = rtems_semaphore_obtain(
0115     ctx->semaphore_id,
0116     RTEMS_NO_WAIT,
0117     0
0118   );
0119   rtems_test_assert(sc == RTEMS_SUCCESSFUL || sc == RTEMS_UNSATISFIED);
0120 }
0121 
0122 static void blocked(void *arg)
0123 {
0124   test_context *ctx = arg;
0125   rtems_status_code sc;
0126 
0127   T_interrupt_test_change_state(
0128     T_INTERRUPT_TEST_ACTION,
0129     T_INTERRUPT_TEST_LATE
0130   );
0131 
0132   sc = rtems_semaphore_release(ctx->semaphore_id);
0133   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0134 }
0135 
0136 static const T_interrupt_test_config config = {
0137   .prepare = prepare,
0138   .action = action,
0139   .interrupt = release_semaphore,
0140   .blocked = blocked,
0141   .max_iteration_count = 10000
0142 };
0143 
0144 T_TEST_CASE(InterruptSemaphoreObtain)
0145 {
0146   test_context ctx;
0147   rtems_status_code sc;
0148   T_interrupt_test_state state;
0149 
0150   ctx.main_task_control = _Thread_Get_executing();
0151 
0152   sc = rtems_semaphore_create(
0153     rtems_build_name('S', 'E', 'M', 'A'),
0154     1,
0155     RTEMS_SIMPLE_BINARY_SEMAPHORE,
0156     0,
0157     &ctx.semaphore_id
0158   );
0159   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0160 
0161   ctx.semaphore_control = get_semaphore_control(ctx.semaphore_id);
0162 
0163   state = T_interrupt_test(&config, &ctx);
0164   T_eq_int(state, T_INTERRUPT_TEST_DONE);
0165 
0166   sc = rtems_semaphore_delete(ctx.semaphore_id);
0167   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0168 }
0169 
0170 static void Init(rtems_task_argument argument)
0171 {
0172   rtems_test_run(argument, TEST_STATE);
0173 }
0174 
0175 #define CONFIGURE_APPLICATION_NEEDS_SIMPLE_CONSOLE_DRIVER
0176 #define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
0177 
0178 #define CONFIGURE_MICROSECONDS_PER_TICK 1000
0179 
0180 #define CONFIGURE_MAXIMUM_SEMAPHORES 1
0181 #define CONFIGURE_MAXIMUM_TASKS 1
0182 
0183 #define CONFIGURE_INITIAL_EXTENSIONS RTEMS_TEST_INITIAL_EXTENSION
0184 
0185 #define CONFIGURE_RTEMS_INIT_TASKS_TABLE
0186 
0187 #define CONFIGURE_INIT
0188 
0189 #include <rtems/confdefs.h>