Back to home page

LXR

 
 

    


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

0001 /*
0002  * Copyright (c) 2017 embedded brains GmbH & Co. KG
0003  *
0004  * The license and distribution terms for this file may be
0005  * found in the file LICENSE in this distribution or at
0006  * http://www.rtems.com/license/LICENSE.
0007  */
0008 
0009 #ifdef HAVE_CONFIG_H
0010 #include "config.h"
0011 #endif
0012 
0013 #include <rtems/thread.h>
0014 #include <rtems.h>
0015 
0016 #include <string.h>
0017 
0018 #include <tmacros.h>
0019 
0020 const char rtems_test_name[] = "SPTHREAD 1";
0021 
0022 #define WAKEUP_EVENT RTEMS_EVENT_0
0023 
0024 typedef struct {
0025   rtems_mutex *mtx;
0026   rtems_recursive_mutex *rmtx;
0027   rtems_id calling_task;
0028 } mutex_context;
0029 
0030 static void mutex_task(rtems_task_argument arg)
0031 {
0032   mutex_context *m;
0033   int rv;
0034 
0035   m = (mutex_context *) arg;
0036 
0037   rtems_test_assert(m->mtx != NULL || m->rmtx != NULL);
0038 
0039   if (m->mtx) {
0040     rv = rtems_mutex_try_lock(m->mtx);
0041     rtems_test_assert(rv == EBUSY);
0042   }
0043 
0044   if (m->rmtx) {
0045     rv = rtems_recursive_mutex_try_lock(m->rmtx);
0046     rtems_test_assert(rv == EBUSY);
0047   }
0048 
0049   rtems_event_send(m->calling_task, WAKEUP_EVENT);
0050 }
0051 
0052 static void test_try_lock_from_different_task(
0053   rtems_mutex *m,
0054   rtems_recursive_mutex *r
0055 )
0056 {
0057   mutex_context ctx;
0058   rtems_status_code sc;
0059   rtems_event_set e;
0060   rtems_id id;
0061 
0062   ctx.mtx = m;
0063   ctx.rmtx = r;
0064   ctx.calling_task = rtems_task_self();
0065 
0066   sc = rtems_task_create(
0067     rtems_build_name('M', 'T', 'X', ' '),
0068     2,
0069     RTEMS_MINIMUM_STACK_SIZE,
0070     RTEMS_DEFAULT_MODES,
0071     RTEMS_DEFAULT_ATTRIBUTES,
0072     &id
0073   );
0074   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0075 
0076   sc = rtems_task_start(id, mutex_task, (rtems_task_argument) &ctx);
0077   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0078 
0079   sc = rtems_event_receive(WAKEUP_EVENT, RTEMS_EVENT_ANY | RTEMS_WAIT, 10, &e);
0080   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0081 
0082   rtems_task_delete(id);
0083 }
0084 
0085 static void test_mutex(void)
0086 {
0087   rtems_mutex a = RTEMS_MUTEX_INITIALIZER("a");
0088   const char *name;
0089   int rv;
0090 
0091   name = rtems_mutex_get_name(&a);
0092   rtems_test_assert(strcmp(name, "a") == 0);
0093 
0094   rtems_mutex_set_name(&a, "b");
0095 
0096   name = rtems_mutex_get_name(&a);
0097   rtems_test_assert(strcmp(name, "b") == 0);
0098 
0099   rtems_mutex_destroy(&a);
0100 
0101   rtems_mutex_init(&a, "c");
0102 
0103   name = rtems_mutex_get_name(&a);
0104   rtems_test_assert(strcmp(name, "c") == 0);
0105 
0106   rtems_mutex_lock(&a);
0107 
0108   test_try_lock_from_different_task(&a, NULL);
0109 
0110   rtems_mutex_unlock(&a);
0111 
0112   rv = rtems_mutex_try_lock(&a);
0113   rtems_test_assert(rv == 0);
0114 
0115   rtems_mutex_unlock(&a);
0116 
0117   rtems_mutex_destroy(&a);
0118 }
0119 
0120 static void test_recursive_mutex(void)
0121 {
0122   rtems_recursive_mutex a = RTEMS_RECURSIVE_MUTEX_INITIALIZER("a");
0123   const char *name;
0124   int rv;
0125 
0126   name = rtems_recursive_mutex_get_name(&a);
0127   rtems_test_assert(strcmp(name, "a") == 0);
0128 
0129   rtems_recursive_mutex_set_name(&a, "b");
0130 
0131   name = rtems_recursive_mutex_get_name(&a);
0132   rtems_test_assert(strcmp(name, "b") == 0);
0133 
0134   rtems_recursive_mutex_destroy(&a);
0135 
0136   rtems_recursive_mutex_init(&a, "c");
0137 
0138   name = rtems_recursive_mutex_get_name(&a);
0139   rtems_test_assert(strcmp(name, "c") == 0);
0140 
0141   rtems_recursive_mutex_lock(&a);
0142 
0143   rtems_recursive_mutex_lock(&a);
0144 
0145   rv = rtems_recursive_mutex_try_lock(&a);
0146   rtems_test_assert(rv == 0);
0147 
0148   test_try_lock_from_different_task(NULL, &a);
0149 
0150   rtems_recursive_mutex_unlock(&a);
0151 
0152   rtems_recursive_mutex_unlock(&a);
0153 
0154   rtems_recursive_mutex_unlock(&a);
0155 
0156   rtems_recursive_mutex_destroy(&a);
0157 }
0158 
0159 typedef struct {
0160   rtems_mutex mtx;
0161   rtems_condition_variable cnd;
0162 } signal_context;
0163 
0164 static void signal_task(rtems_task_argument arg)
0165 {
0166   signal_context *s;
0167 
0168   s = (signal_context *) arg;
0169   rtems_mutex_lock(&s->mtx);
0170   rtems_condition_variable_signal(&s->cnd);
0171   rtems_mutex_unlock(&s->mtx);
0172 }
0173 
0174 static void test_condition_variable(void)
0175 {
0176   rtems_condition_variable a = RTEMS_CONDITION_VARIABLE_INITIALIZER("a");
0177   signal_context s;
0178   const char *name;
0179   rtems_status_code sc;
0180   rtems_id id;
0181 
0182   name = rtems_condition_variable_get_name(&a);
0183   rtems_test_assert(strcmp(name, "a") == 0);
0184 
0185   rtems_condition_variable_set_name(&a, "b");
0186 
0187   name = rtems_condition_variable_get_name(&a);
0188   rtems_test_assert(strcmp(name, "b") == 0);
0189 
0190   rtems_condition_variable_destroy(&a);
0191 
0192   rtems_mutex_init(&s.mtx, "d");
0193   rtems_condition_variable_init(&s.cnd, "c");
0194 
0195   name = rtems_condition_variable_get_name(&s.cnd);
0196   rtems_test_assert(strcmp(name, "c") == 0);
0197 
0198   rtems_condition_variable_signal(&s.cnd);
0199 
0200   rtems_condition_variable_broadcast(&s.cnd);
0201 
0202   rtems_mutex_lock(&s.mtx);
0203 
0204   sc = rtems_task_create(
0205     rtems_build_name('C', 'O', 'N', 'D'),
0206     2,
0207     RTEMS_MINIMUM_STACK_SIZE,
0208     RTEMS_DEFAULT_MODES,
0209     RTEMS_DEFAULT_ATTRIBUTES,
0210     &id
0211   );
0212   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0213 
0214   sc = rtems_task_start(id, signal_task, (rtems_task_argument) &s);
0215   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0216 
0217   rtems_condition_variable_wait(&s.cnd, &s.mtx);
0218 
0219   sc = rtems_task_delete(id);
0220   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0221 
0222   rtems_mutex_unlock(&s.mtx);
0223 
0224   rtems_condition_variable_destroy(&s.cnd);
0225   rtems_mutex_destroy(&s.mtx);
0226 }
0227 
0228 static void test_counting_semaphore(void)
0229 {
0230   rtems_counting_semaphore a = RTEMS_COUNTING_SEMAPHORE_INITIALIZER("a", 1);
0231   const char *name;
0232   int eno;
0233 
0234   name = rtems_counting_semaphore_get_name(&a);
0235   rtems_test_assert(strcmp(name, "a") == 0);
0236 
0237   rtems_counting_semaphore_set_name(&a, "b");
0238 
0239   name = rtems_counting_semaphore_get_name(&a);
0240   rtems_test_assert(strcmp(name, "b") == 0);
0241 
0242   rtems_counting_semaphore_destroy(&a);
0243 
0244   rtems_counting_semaphore_init(&a, "c", 0);
0245 
0246   name = rtems_counting_semaphore_get_name(&a);
0247   rtems_test_assert(strcmp(name, "c") == 0);
0248 
0249   eno = rtems_counting_semaphore_try_wait(&a);
0250   rtems_test_assert(eno == EAGAIN);
0251 
0252   eno = rtems_counting_semaphore_wait_timed_ticks(&a, 1);
0253   rtems_test_assert(eno == ETIMEDOUT);
0254 
0255   rtems_counting_semaphore_post(&a);
0256 
0257   rtems_counting_semaphore_wait(&a);
0258 
0259   rtems_counting_semaphore_post(&a);
0260 
0261   eno = rtems_counting_semaphore_try_wait(&a);
0262   rtems_test_assert(eno == 0);
0263 
0264   rtems_counting_semaphore_post(&a);
0265 
0266   eno = rtems_counting_semaphore_wait_timed_ticks(&a, 1);
0267   rtems_test_assert(eno == 0);
0268 
0269   rtems_counting_semaphore_destroy(&a);
0270 }
0271 
0272 static void test_binary_semaphore(void)
0273 {
0274   rtems_binary_semaphore a = RTEMS_BINARY_SEMAPHORE_INITIALIZER("a");
0275   const char *name;
0276   int eno;
0277 
0278   name = rtems_binary_semaphore_get_name(&a);
0279   rtems_test_assert(strcmp(name, "a") == 0);
0280 
0281   rtems_binary_semaphore_set_name(&a, "b");
0282 
0283   name = rtems_binary_semaphore_get_name(&a);
0284   rtems_test_assert(strcmp(name, "b") == 0);
0285 
0286   rtems_binary_semaphore_destroy(&a);
0287 
0288   rtems_binary_semaphore_init(&a, "c");
0289 
0290   name = rtems_binary_semaphore_get_name(&a);
0291   rtems_test_assert(strcmp(name, "c") == 0);
0292 
0293   eno = rtems_binary_semaphore_try_wait(&a);
0294   rtems_test_assert(eno == EAGAIN);
0295 
0296   eno = rtems_binary_semaphore_wait_timed_ticks(&a, 1);
0297   rtems_test_assert(eno == ETIMEDOUT);
0298 
0299   rtems_binary_semaphore_post(&a);
0300 
0301   rtems_binary_semaphore_wait(&a);
0302 
0303   rtems_binary_semaphore_post(&a);
0304 
0305   eno = rtems_binary_semaphore_try_wait(&a);
0306   rtems_test_assert(eno == 0);
0307 
0308   rtems_binary_semaphore_post(&a);
0309 
0310   eno = rtems_binary_semaphore_wait_timed_ticks(&a, 1);
0311   rtems_test_assert(eno == 0);
0312 
0313   rtems_binary_semaphore_destroy(&a);
0314 }
0315 
0316 static void Init(rtems_task_argument arg)
0317 {
0318   TEST_BEGIN();
0319 
0320   test_mutex();
0321   test_recursive_mutex();
0322   test_condition_variable();
0323   test_counting_semaphore();
0324   test_binary_semaphore();
0325 
0326   TEST_END();
0327   rtems_test_exit(0);
0328 }
0329 
0330 #define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
0331 #define CONFIGURE_APPLICATION_NEEDS_SIMPLE_CONSOLE_DRIVER
0332 
0333 #define CONFIGURE_MAXIMUM_TASKS 2
0334 
0335 #define CONFIGURE_RTEMS_INIT_TASKS_TABLE
0336 
0337 #define CONFIGURE_INIT
0338 
0339 #include <rtems/confdefs.h>