Changeset 32f1f747 in rtems


Ignore:
Timestamp:
Aug 6, 2020, 5:12:55 PM (3 months ago)
Author:
Sebastian Huber <sebastian.huber@…>
Branches:
master
Children:
6894e2f4
Parents:
6c4ca83
git-author:
Sebastian Huber <sebastian.huber@…> (08/06/20 17:12:55)
git-committer:
Sebastian Huber <sebastian.huber@…> (08/06/20 17:15:57)
Message:

libtest: Fix T_interrupt_test() in SMP configs

Update #3199.

Files:
2 edited

Legend:

Unmodified
Added
Removed
  • cpukit/libtest/t-test-interrupt.c

    r6c4ca83 r32f1f747  
    4848#include <rtems/score/watchdogimpl.h>
    4949
     50#ifdef RTEMS_SMP
     51#include <rtems/score/smpimpl.h>
     52#endif
     53
    5054typedef T_interrupt_test_state (*T_interrupt_test_handler)(void *);
    5155
     
    6266        void (*blocked)(void *);
    6367        void *arg;
     68#ifdef RTEMS_SMP
     69        Per_CPU_Job job;
     70        Per_CPU_Job_context job_context;
     71#endif
    6472        Watchdog_Control wdg;
    6573        User_extensions_Control ext;
     
    200208}
    201209
     210#ifdef RTEMS_SMP
     211static void
     212T_interrupt_blocked(void *arg)
     213{
     214        T_interrupt_context *ctx;
     215
     216        ctx = arg;
     217        (*ctx->blocked)(ctx->arg);
     218}
     219#endif
     220
    202221static void T_interrupt_thread_switch(Thread_Control *, Thread_Control *);
    203222
     
    205224        .interrupt = T_interrupt_continue,
    206225        .blocked = T_interrupt_do_nothing,
     226#ifdef RTEMS_SMP
     227        .job = {
     228                .context = &T_interrupt_instance.job_context
     229        },
     230        .job_context = {
     231                .handler = T_interrupt_blocked,
     232                .arg = &T_interrupt_instance
     233        },
     234#endif
    207235        .wdg = WATCHDOG_INITIALIZER(T_interrupt_watchdog),
    208236        .ext = {
     
    264292
    265293                if (state != T_INTERRUPT_TEST_INITIAL) {
     294#ifdef RTEMS_SMP
     295                        Per_CPU_Control *cpu_self;
     296
     297                        /*
     298                         * In SMP configurations, the thread switch extension
     299                         * runs in a very restricted environment.  Interrupts
     300                         * are disabled and the caller owns the per-CPU lock.
     301                         * In order to avoid deadlocks at SMP lock level, we
     302                         * have to use an SMP job which runs later in the
     303                         * context of the inter-processor interrupt.
     304                         */
     305                        cpu_self = _Per_CPU_Get();
     306                        _Per_CPU_Add_job(cpu_self, &ctx->job);
     307                        _SMP_Send_message(_Per_CPU_Get_index(cpu_self),
     308                            SMP_MESSAGE_PERFORM_JOBS);
     309#else
    266310                        (*ctx->blocked)(ctx->arg);
     311#endif
    267312                }
    268313        }
  • testsuites/libtests/ttest02/init.c

    r6c4ca83 r32f1f747  
    153153}
    154154
     155static void
     156suspend(void *arg)
     157{
     158        rtems_status_code sc;
     159        rtems_id *id;
     160
     161        id = arg;
     162        sc = rtems_task_suspend(*id);
     163        T_step_rsc_success(1, sc);
     164}
     165
     166static T_interrupt_test_state
     167do_nothing(void *arg)
     168{
     169        (void)arg;
     170        return T_INTERRUPT_TEST_ACTION;
     171}
     172
     173static void
     174resume(void *arg)
     175{
     176        T_interrupt_test_state state;
     177
     178        state = T_interrupt_test_change_state(T_INTERRUPT_TEST_ACTION,
     179            T_INTERRUPT_TEST_DONE);
     180
     181        if (state == T_INTERRUPT_TEST_ACTION) {
     182                rtems_status_code sc;
     183                rtems_id *id;
     184
     185                id = arg;
     186                sc = rtems_task_resume(*id);
     187                T_step_rsc_success(0, sc);
     188        }
     189}
     190
     191static const T_interrupt_test_config blocked_config = {
     192        .action = suspend,
     193        .interrupt = do_nothing,
     194        .blocked = resume,
     195        .max_iteration_count = 10000
     196};
     197
     198T_TEST_CASE(TestInterruptBlocked)
     199{
     200        T_interrupt_test_state state;
     201        rtems_id id;
     202
     203        T_plan(3);
     204        id = rtems_task_self();
     205        state = T_interrupt_test(&blocked_config, &id);
     206        T_step_eq_int(2, state, T_INTERRUPT_TEST_DONE);
     207}
     208
    155209const char rtems_test_name[] = "TTEST 2";
    156210
Note: See TracChangeset for help on using the changeset viewer.