mirror of
https://gitlab.rtems.org/rtems/rtos/rtems.git
synced 2026-09-20 16:18:12 +08:00
smptests/smppsxsignal01: New test
This commit is contained in:
@@ -22,6 +22,9 @@ SUBDIRS += smplock01
|
||||
SUBDIRS += smpschedule01
|
||||
SUBDIRS += smpsignal01
|
||||
SUBDIRS += smpunsupported01
|
||||
if HAS_POSIX
|
||||
SUBDIRS += smppsxsignal01
|
||||
endif
|
||||
endif
|
||||
|
||||
include $(top_srcdir)/../automake/subdirs.am
|
||||
|
||||
@@ -23,6 +23,7 @@ RTEMS_PROG_CXX_FOR_TARGET
|
||||
RTEMS_CANONICALIZE_TOOLS
|
||||
|
||||
RTEMS_CHECK_CPUOPTS([RTEMS_ATOMIC])
|
||||
RTEMS_CHECK_CPUOPTS([RTEMS_POSIX_API])
|
||||
|
||||
RTEMS_CHECK_CUSTOM_BSP(RTEMS_BSP)
|
||||
RTEMS_CHECK_CPUOPTS([RTEMS_MULTIPROCESSING])
|
||||
@@ -33,6 +34,7 @@ RTEMS_CHECK_CPUOPTS([RTEMS_SMP])
|
||||
AM_CONDITIONAL(SMPTESTS,test "$rtems_cv_RTEMS_SMP" = "yes")
|
||||
|
||||
AM_CONDITIONAL([ATOMIC],[test x"$rtems_cv_RTEMS_ATOMIC" = xyes])
|
||||
AM_CONDITIONAL([HAS_POSIX],[test x"${rtems_cv_RTEMS_POSIX_API}" = xyes])
|
||||
|
||||
# Explicitly list all Makefiles here
|
||||
AC_CONFIG_FILES([Makefile
|
||||
@@ -52,6 +54,7 @@ smpatomic05/Makefile
|
||||
smpatomic06/Makefile
|
||||
smpatomic07/Makefile
|
||||
smplock01/Makefile
|
||||
smppsxsignal01/Makefile
|
||||
smpschedule01/Makefile
|
||||
smpsignal01/Makefile
|
||||
smpunsupported01/Makefile
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
rtems_tests_PROGRAMS = smppsxsignal01
|
||||
smppsxsignal01_SOURCES = init.c
|
||||
|
||||
dist_rtems_tests_DATA = smppsxsignal01.scn smppsxsignal01.doc
|
||||
|
||||
include $(RTEMS_ROOT)/make/custom/@RTEMS_BSP@.cfg
|
||||
include $(top_srcdir)/../automake/compile.am
|
||||
include $(top_srcdir)/../automake/leaf.am
|
||||
|
||||
AM_CPPFLAGS += -I$(top_srcdir)/../support/include
|
||||
|
||||
LINK_OBJS = $(smppsxsignal01_OBJECTS)
|
||||
LINK_LIBS = $(smppsxsignal01_LDLIBS)
|
||||
|
||||
smppsxsignal01$(EXEEXT): $(smppsxsignal01_OBJECTS) $(smppsxsignal01_DEPENDENCIES)
|
||||
@rm -f smppsxsignal01$(EXEEXT)
|
||||
$(make-exe)
|
||||
|
||||
include $(top_srcdir)/../automake/local.am
|
||||
@@ -0,0 +1,188 @@
|
||||
/*
|
||||
* Copyright (c) 2013 embedded brains GmbH. All rights reserved.
|
||||
*
|
||||
* embedded brains GmbH
|
||||
* Dornierstr. 4
|
||||
* 82178 Puchheim
|
||||
* Germany
|
||||
* <rtems@embedded-brains.de>
|
||||
*
|
||||
* The license and distribution terms for this file may be
|
||||
* found in the file LICENSE in this distribution or at
|
||||
* http://www.rtems.com/license/LICENSE.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "tmacros.h"
|
||||
|
||||
#include <pthread.h>
|
||||
#include <signal.h>
|
||||
|
||||
#define TEST_SIGNAL SIGUSR1
|
||||
|
||||
typedef enum {
|
||||
SIG_READY,
|
||||
SIG_SENT,
|
||||
SIG_PROCESSED
|
||||
} test_state;
|
||||
|
||||
typedef struct {
|
||||
test_state state;
|
||||
pthread_t consumer;
|
||||
pthread_t producer;
|
||||
uint32_t consumer_processor;
|
||||
uint32_t producer_processor;
|
||||
} test_context;
|
||||
|
||||
static void change_state(test_context *ctx, test_state new_state)
|
||||
{
|
||||
ctx->state = new_state;
|
||||
_CPU_SMP_Processor_event_broadcast();
|
||||
}
|
||||
|
||||
static void wait_for_state(const test_context *ctx, test_state desired_state)
|
||||
{
|
||||
while ( ctx->state != desired_state ) {
|
||||
_CPU_SMP_Processor_event_receive();
|
||||
}
|
||||
}
|
||||
|
||||
static test_context ctx_instance = {
|
||||
.state = SIG_READY
|
||||
};
|
||||
|
||||
static void signal_handler(int signum)
|
||||
{
|
||||
test_context *ctx = &ctx_instance;
|
||||
|
||||
switch (ctx->state) {
|
||||
case SIG_SENT:
|
||||
change_state(ctx, SIG_PROCESSED);
|
||||
break;
|
||||
default:
|
||||
rtems_test_assert(0);
|
||||
}
|
||||
}
|
||||
|
||||
static void signal_send(test_context *ctx, test_state new_state)
|
||||
{
|
||||
int eno;
|
||||
|
||||
eno = pthread_kill(ctx->consumer, TEST_SIGNAL);
|
||||
rtems_test_assert(eno == 0);
|
||||
|
||||
change_state(ctx, new_state);
|
||||
}
|
||||
|
||||
static void check_consumer_processor(const test_context *ctx)
|
||||
{
|
||||
rtems_test_assert(
|
||||
ctx->consumer_processor == rtems_smp_get_current_processor()
|
||||
);
|
||||
}
|
||||
|
||||
static void check_producer_processor(const test_context *ctx)
|
||||
{
|
||||
rtems_test_assert(
|
||||
ctx->producer_processor == rtems_smp_get_current_processor()
|
||||
);
|
||||
}
|
||||
|
||||
static void *producer(void *arg)
|
||||
{
|
||||
test_context *ctx = arg;
|
||||
|
||||
ctx->producer_processor = rtems_smp_get_current_processor();
|
||||
|
||||
rtems_test_assert(ctx->consumer_processor != ctx->producer_processor);
|
||||
|
||||
wait_for_state(ctx, SIG_READY);
|
||||
signal_send(ctx, SIG_SENT);
|
||||
|
||||
check_producer_processor(ctx);
|
||||
|
||||
return ctx;
|
||||
}
|
||||
|
||||
static void test(void)
|
||||
{
|
||||
test_context *ctx = &ctx_instance;
|
||||
struct sigaction new_action;
|
||||
sigset_t test_signal_set;
|
||||
int rv;
|
||||
pthread_attr_t attr;
|
||||
int eno;
|
||||
void *producer_status;
|
||||
|
||||
ctx->consumer = pthread_self();
|
||||
ctx->consumer_processor = rtems_smp_get_current_processor();
|
||||
|
||||
memset(&new_action, 0, sizeof(new_action));
|
||||
new_action.sa_handler = signal_handler;
|
||||
|
||||
rv = sigaction(TEST_SIGNAL, &new_action, NULL);
|
||||
rtems_test_assert(rv == 0);
|
||||
|
||||
rv = sigemptyset(&test_signal_set);
|
||||
rtems_test_assert(rv == 0);
|
||||
|
||||
rv = sigaddset(&test_signal_set, TEST_SIGNAL);
|
||||
rtems_test_assert(rv == 0);
|
||||
|
||||
eno = pthread_sigmask(SIG_UNBLOCK, &test_signal_set, NULL);
|
||||
rtems_test_assert(eno == 0);
|
||||
|
||||
eno = pthread_attr_init(&attr);
|
||||
rtems_test_assert(eno == 0);
|
||||
|
||||
eno = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
|
||||
rtems_test_assert(eno == 0);
|
||||
|
||||
eno = pthread_create(&ctx->producer, &attr, producer, ctx);
|
||||
rtems_test_assert(eno == 0);
|
||||
|
||||
eno = pthread_attr_destroy(&attr);
|
||||
rtems_test_assert(eno == 0);
|
||||
|
||||
check_consumer_processor(ctx);
|
||||
|
||||
wait_for_state(ctx, SIG_PROCESSED);
|
||||
|
||||
check_consumer_processor(ctx);
|
||||
|
||||
producer_status = NULL;
|
||||
pthread_join(ctx->producer, &producer_status);
|
||||
rtems_test_assert(eno == 0);
|
||||
rtems_test_assert(producer_status == ctx);
|
||||
}
|
||||
|
||||
static void *POSIX_Init(void *arg)
|
||||
{
|
||||
puts("\n\n*** TEST SMPPSXSIGNAL 1 ***");
|
||||
|
||||
if (rtems_smp_get_processor_count() >= 2) {
|
||||
test();
|
||||
}
|
||||
|
||||
puts("*** END OF TEST SMPPSXSIGNAL 1 ***");
|
||||
|
||||
rtems_test_exit(0);
|
||||
}
|
||||
|
||||
#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
|
||||
#define CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER
|
||||
|
||||
#define CONFIGURE_SMP_APPLICATION
|
||||
|
||||
#define CONFIGURE_SMP_MAXIMUM_PROCESSORS 2
|
||||
|
||||
#define CONFIGURE_MAXIMUM_POSIX_THREADS 2
|
||||
|
||||
#define CONFIGURE_POSIX_INIT_THREAD_TABLE
|
||||
|
||||
#define CONFIGURE_INIT
|
||||
|
||||
#include <rtems/confdefs.h>
|
||||
@@ -0,0 +1,12 @@
|
||||
This file describes the directives and concepts tested by this test set.
|
||||
|
||||
test set name: smppsxsignal01
|
||||
|
||||
directives:
|
||||
|
||||
- _POSIX_signals_Unblock_thread()
|
||||
- pthread_kill()
|
||||
|
||||
concepts:
|
||||
|
||||
- Ensure that POSIX signal delivery works on SMP.
|
||||
@@ -0,0 +1,2 @@
|
||||
*** TEST SMPPSXSIGNAL 1 ***
|
||||
*** END OF TEST SMPPSXSIGNAL 1 ***
|
||||
Reference in New Issue
Block a user