Back to home page

LXR

 
 

    


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

0001 /* SPDX-License-Identifier: BSD-2-Clause */
0002 
0003 /*
0004  * Copyright (c) 2013 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 #include <pthread.h>
0035 #include <signal.h>
0036 
0037 const char rtems_test_name[] = "SMPPSXSIGNAL 1";
0038 
0039 #define TEST_SIGNAL SIGUSR1
0040 
0041 typedef enum {
0042   SIG_READY,
0043   SIG_SENT,
0044   SIG_PROCESSED
0045 } test_state;
0046 
0047 typedef struct {
0048   volatile test_state state;
0049   pthread_t consumer;
0050   pthread_t producer;
0051   uint32_t consumer_processor;
0052   uint32_t producer_processor;
0053 } test_context;
0054 
0055 static void change_state(test_context *ctx, test_state new_state)
0056 {
0057   ctx->state = new_state;
0058 }
0059 
0060 static void wait_for_state(const test_context *ctx, test_state desired_state)
0061 {
0062   while ( ctx->state != desired_state ) {
0063     /* Wait */
0064   }
0065 }
0066 
0067 static test_context ctx_instance = {
0068   .state = SIG_READY
0069 };
0070 
0071 static void signal_handler(int signum)
0072 {
0073   test_context *ctx = &ctx_instance;
0074 
0075   switch (ctx->state) {
0076     case SIG_SENT:
0077       change_state(ctx, SIG_PROCESSED);
0078       break;
0079     default:
0080       rtems_test_assert(0);
0081   }
0082 }
0083 
0084 static void signal_send(test_context *ctx, test_state new_state)
0085 {
0086   int eno;
0087 
0088   eno = pthread_kill(ctx->consumer, TEST_SIGNAL);
0089   rtems_test_assert(eno == 0);
0090 
0091   change_state(ctx, new_state);
0092 }
0093 
0094 static void check_consumer_processor(const test_context *ctx)
0095 {
0096   rtems_test_assert(
0097     ctx->consumer_processor == rtems_scheduler_get_processor()
0098   );
0099 }
0100 
0101 static void check_producer_processor(const test_context *ctx)
0102 {
0103   rtems_test_assert(
0104     ctx->producer_processor == rtems_scheduler_get_processor()
0105   );
0106 }
0107 
0108 static void *producer(void *arg)
0109 {
0110   test_context *ctx = arg;
0111 
0112   ctx->producer_processor = rtems_scheduler_get_processor();
0113 
0114   rtems_test_assert(ctx->consumer_processor != ctx->producer_processor);
0115 
0116   wait_for_state(ctx, SIG_READY);
0117   signal_send(ctx, SIG_SENT);
0118 
0119   check_producer_processor(ctx);
0120 
0121   return ctx;
0122 }
0123 
0124 static void test(void)
0125 {
0126   test_context *ctx = &ctx_instance;
0127   struct sigaction new_action;
0128   sigset_t test_signal_set;
0129   int rv;
0130   pthread_attr_t attr;
0131   int eno;
0132   void *producer_status;
0133 
0134   ctx->consumer = pthread_self();
0135   ctx->consumer_processor = rtems_scheduler_get_processor();
0136 
0137   memset(&new_action, 0, sizeof(new_action));
0138   new_action.sa_handler = signal_handler;
0139 
0140   rv = sigaction(TEST_SIGNAL, &new_action, NULL);
0141   rtems_test_assert(rv == 0);
0142 
0143   rv = sigemptyset(&test_signal_set);
0144   rtems_test_assert(rv == 0);
0145 
0146   rv = sigaddset(&test_signal_set, TEST_SIGNAL);
0147   rtems_test_assert(rv == 0);
0148 
0149   eno = pthread_sigmask(SIG_UNBLOCK, &test_signal_set, NULL);
0150   rtems_test_assert(eno == 0);
0151 
0152   eno = pthread_attr_init(&attr);
0153   rtems_test_assert(eno == 0);
0154 
0155   eno = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
0156   rtems_test_assert(eno == 0);
0157 
0158   eno = pthread_create(&ctx->producer, &attr, producer, ctx);
0159   rtems_test_assert(eno == 0);
0160 
0161   eno = pthread_attr_destroy(&attr);
0162   rtems_test_assert(eno == 0);
0163 
0164   check_consumer_processor(ctx);
0165 
0166   wait_for_state(ctx, SIG_PROCESSED);
0167 
0168   check_consumer_processor(ctx);
0169 
0170   producer_status = NULL;
0171   pthread_join(ctx->producer, &producer_status);
0172   rtems_test_assert(eno == 0);
0173   rtems_test_assert(producer_status == ctx);
0174 }
0175 
0176 static void *POSIX_Init(void *arg)
0177 {
0178   TEST_BEGIN();
0179 
0180   if (rtems_scheduler_get_processor_maximum() >= 2) {
0181     test();
0182   }
0183 
0184   TEST_END();
0185   rtems_test_exit(0);
0186 }
0187 
0188 #define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
0189 #define CONFIGURE_APPLICATION_NEEDS_SIMPLE_CONSOLE_DRIVER
0190 
0191 #define CONFIGURE_MAXIMUM_PROCESSORS 2
0192 
0193 #define CONFIGURE_INITIAL_EXTENSIONS RTEMS_TEST_INITIAL_EXTENSION
0194 
0195 #define CONFIGURE_MAXIMUM_POSIX_THREADS 2
0196 
0197 #define CONFIGURE_POSIX_INIT_THREAD_TABLE
0198 
0199 #define CONFIGURE_INIT
0200 
0201 #include <rtems/confdefs.h>