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) 2016 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 <errno.h>
0033 #include <pthread.h>
0034 
0035 #include <rtems.h>
0036 #include <rtems/libcsupport.h>
0037 
0038 #include "tmacros.h"
0039 
0040 const char rtems_test_name[] = "SMPPSXMUTEX 1";
0041 
0042 #define SCHED_A rtems_build_name(' ', ' ', ' ', 'A')
0043 
0044 #define SCHED_B rtems_build_name(' ', ' ', ' ', 'B')
0045 
0046 typedef struct {
0047   pthread_t thread_b;
0048   pthread_mutexattr_t mtx_attr;
0049   pthread_mutex_t mtx_a;
0050   pthread_mutex_t mtx_b;
0051 } test_context;
0052 
0053 static test_context test_instance;
0054 
0055 static void *thread_b(void *arg)
0056 {
0057   test_context *ctx;
0058   int prio_ceiling;
0059   int eno;
0060 
0061   ctx = arg;
0062 
0063   rtems_test_assert(rtems_scheduler_get_processor() == 1);
0064 
0065   eno = pthread_mutex_init(&ctx->mtx_b, &ctx->mtx_attr);
0066   rtems_test_assert(eno == 0);
0067 
0068   eno = pthread_mutex_getprioceiling(&ctx->mtx_b, &prio_ceiling);
0069   rtems_test_assert(eno == 0);
0070   rtems_test_assert(prio_ceiling == 254);
0071 
0072   eno = pthread_mutex_lock(&ctx->mtx_b);
0073   rtems_test_assert(eno == 0);
0074 
0075   eno = pthread_mutex_unlock(&ctx->mtx_b);
0076   rtems_test_assert(eno == 0);
0077 
0078   eno = pthread_mutex_destroy(&ctx->mtx_b);
0079   rtems_test_assert(eno == 0);
0080 
0081   eno = pthread_mutex_getprioceiling(&ctx->mtx_a, &prio_ceiling);
0082   rtems_test_assert(eno == 0);
0083   rtems_test_assert(prio_ceiling == 126);
0084 
0085   eno = pthread_mutex_lock(&ctx->mtx_a);
0086   rtems_test_assert(eno == EINVAL);
0087 
0088   return ctx;
0089 }
0090 
0091 static void test(test_context *ctx)
0092 {
0093   uint32_t cpu_count;
0094   int prio_ceiling;
0095   int eno;
0096 
0097   cpu_count = rtems_scheduler_get_processor_maximum();
0098 
0099   rtems_test_assert(rtems_scheduler_get_processor() == 0);
0100 
0101   eno = pthread_mutexattr_init(&ctx->mtx_attr);
0102   rtems_test_assert(eno == 0);
0103 
0104   eno = pthread_mutexattr_setprotocol(&ctx->mtx_attr, PTHREAD_PRIO_PROTECT);
0105   rtems_test_assert(eno == 0);
0106 
0107   eno = pthread_mutex_init(&ctx->mtx_a, &ctx->mtx_attr);
0108   rtems_test_assert(eno == 0);
0109 
0110   eno = pthread_mutex_getprioceiling(&ctx->mtx_a, &prio_ceiling);
0111   rtems_test_assert(eno == 0);
0112   rtems_test_assert(prio_ceiling == 126);
0113 
0114   eno = pthread_mutex_lock(&ctx->mtx_a);
0115   rtems_test_assert(eno == 0);
0116 
0117   eno = pthread_mutex_unlock(&ctx->mtx_a);
0118   rtems_test_assert(eno == 0);
0119 
0120   if (cpu_count > 1) {
0121     rtems_id scheduler_a_id;
0122     rtems_id scheduler_b_id;
0123     rtems_status_code sc;
0124     rtems_task_priority prio;
0125     void *exit_code;
0126 
0127     sc = rtems_scheduler_ident(SCHED_A, &scheduler_a_id);
0128     rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0129 
0130     sc = rtems_scheduler_ident(SCHED_B, &scheduler_b_id);
0131     rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0132 
0133     sc = rtems_task_set_priority(pthread_self(), RTEMS_CURRENT_PRIORITY, &prio);
0134     rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0135 
0136     sc = rtems_task_set_scheduler(pthread_self(), scheduler_b_id, prio);
0137     rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0138 
0139     eno = pthread_create(&ctx->thread_b, NULL, thread_b, ctx);
0140     rtems_test_assert(eno == 0);
0141 
0142     exit_code = NULL;
0143     eno = pthread_join(ctx->thread_b, &exit_code);
0144     rtems_test_assert(eno == 0);
0145     rtems_test_assert(exit_code == ctx);
0146 
0147     sc = rtems_task_set_scheduler(pthread_self(), scheduler_a_id, prio);
0148     rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0149   }
0150 
0151   eno = pthread_mutex_destroy(&ctx->mtx_a);
0152   rtems_test_assert(eno == 0);
0153 
0154   eno = pthread_mutexattr_destroy(&ctx->mtx_attr);
0155   rtems_test_assert(eno == 0);
0156 }
0157 
0158 static void *POSIX_Init(void *arg)
0159 {
0160   rtems_resource_snapshot snapshot;
0161 
0162   TEST_BEGIN();
0163 
0164   rtems_resource_snapshot_take(&snapshot);
0165 
0166   test(&test_instance);
0167 
0168   rtems_test_assert(rtems_resource_snapshot_check(&snapshot));
0169 
0170   TEST_END();
0171   rtems_test_exit(0);
0172 }
0173 
0174 #define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
0175 #define CONFIGURE_APPLICATION_NEEDS_SIMPLE_CONSOLE_DRIVER
0176 
0177 #define CONFIGURE_MAXIMUM_POSIX_THREADS 2
0178 
0179 #define CONFIGURE_MAXIMUM_PROCESSORS 2
0180 
0181 #define CONFIGURE_SCHEDULER_PRIORITY_SMP
0182 
0183 #include <rtems/scheduler.h>
0184 
0185 RTEMS_SCHEDULER_PRIORITY_SMP(a, 128);
0186 
0187 RTEMS_SCHEDULER_PRIORITY_SMP(b, 256);
0188 
0189 #define CONFIGURE_SCHEDULER_TABLE_ENTRIES \
0190   RTEMS_SCHEDULER_TABLE_PRIORITY_SMP(a, SCHED_A), \
0191   RTEMS_SCHEDULER_TABLE_PRIORITY_SMP(b, SCHED_B)  \
0192 
0193 #define CONFIGURE_SCHEDULER_ASSIGNMENTS \
0194   RTEMS_SCHEDULER_ASSIGN(0, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_MANDATORY), \
0195   RTEMS_SCHEDULER_ASSIGN(1, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_OPTIONAL)
0196 
0197 #define CONFIGURE_INITIAL_EXTENSIONS RTEMS_TEST_INITIAL_EXTENSION
0198 
0199 #define CONFIGURE_POSIX_INIT_THREAD_TABLE
0200 
0201 #define CONFIGURE_INIT
0202 
0203 #include <rtems/confdefs.h>