Back to home page

LXR

 
 

    


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

0001 /* SPDX-License-Identifier: BSD-2-Clause */
0002 
0003 /**
0004  * @file
0005  *
0006  * @ingroup RTEMSTestFrameworkImpl
0007  *
0008  * @brief This source file contains the implementation of the RTEMS objects
0009  *   test support.
0010  */
0011 
0012 /*
0013  * Copyright (C) 2018 embedded brains GmbH & Co. KG
0014  *
0015  * Redistribution and use in source and binary forms, with or without
0016  * modification, are permitted provided that the following conditions
0017  * are met:
0018  * 1. Redistributions of source code must retain the above copyright
0019  *    notice, this list of conditions and the following disclaimer.
0020  * 2. Redistributions in binary form must reproduce the above copyright
0021  *    notice, this list of conditions and the following disclaimer in the
0022  *    documentation and/or other materials provided with the distribution.
0023  *
0024  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
0025  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
0026  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
0027  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
0028  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
0029  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
0030  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
0031  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
0032  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
0033  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
0034  * POSSIBILITY OF SUCH DAMAGE.
0035  */
0036 
0037 #undef __STRICT_ANSI__
0038 
0039 #include "t-test-rtems.h"
0040 
0041 #include <rtems/test.h>
0042 
0043 #include <inttypes.h>
0044 
0045 #include <rtems/score/threadimpl.h>
0046 
0047 T_thread_timer_state
0048 T_get_thread_timer_state(uint32_t id)
0049 {
0050     Thread_Control *the_thread;
0051     ISR_lock_Context lock_context;
0052     T_thread_timer_state state;
0053 
0054     the_thread = _Thread_Get(id, &lock_context);
0055     if (the_thread == NULL) {
0056         return T_THREAD_TIMER_NO_THREAD;
0057     }
0058 
0059     switch (_Watchdog_Get_state(&the_thread->Timer.Watchdog)) {
0060         case WATCHDOG_SCHEDULED_BLACK:
0061         case WATCHDOG_SCHEDULED_RED:
0062             state = T_THREAD_TIMER_SCHEDULED;
0063             break;
0064         case WATCHDOG_PENDING:
0065             state = T_THREAD_TIMER_PENDING;
0066             break;
0067         default:
0068             state = T_THREAD_TIMER_INACTIVE;
0069             break;
0070     }
0071 
0072     _ISR_lock_ISR_enable(&lock_context);
0073     return state;
0074 }
0075 
0076 Objects_Maximum
0077 T_objects_count(Objects_APIs api, uint16_t cls)
0078 {
0079     const Objects_Information *information;
0080     Objects_Maximum count;
0081 
0082     information = _Objects_Get_information(api, cls);
0083 
0084     _RTEMS_Lock_allocator();
0085 
0086     if (information != NULL) {
0087         count = _Objects_Active_count(information);
0088     } else {
0089         count = 0;
0090     }
0091 
0092     _RTEMS_Unlock_allocator();
0093 
0094     return count;
0095 }
0096 
0097 void
0098 T_objects_check(Objects_APIs api, uint16_t cls,
0099     Objects_Maximum *expected, const char *name)
0100 {
0101     Objects_Maximum count;
0102     int32_t delta;
0103 
0104     count = T_objects_count(api, cls);
0105     delta = (int32_t)count - (int32_t)*expected;
0106 
0107     if (delta != 0) {
0108         *expected = count;
0109         T_check(&T_special, false, "%s leak (%" PRIi32 ")", name,
0110             delta);
0111     }
0112 }
0113 
0114 static Objects_Maximum T_barrier_count;
0115 
0116 static void
0117 T_rtems_barriers_run_initialize(void)
0118 {
0119     T_barrier_count = T_objects_count(OBJECTS_CLASSIC_API,
0120         OBJECTS_RTEMS_BARRIERS);
0121 }
0122 
0123 static void
0124 T_rtems_barriers_case_end(void)
0125 {
0126     T_objects_check(OBJECTS_CLASSIC_API, OBJECTS_RTEMS_BARRIERS,
0127         &T_barrier_count, "RTEMS barrier");
0128 }
0129 
0130 void
0131 T_check_rtems_barriers(T_event event, const char *name)
0132 {
0133     (void)name;
0134 
0135     switch (event) {
0136     case T_EVENT_RUN_INITIALIZE_EARLY:
0137         T_rtems_barriers_run_initialize();
0138         break;
0139     case T_EVENT_CASE_END:
0140         T_rtems_barriers_case_end();
0141         break;
0142     default:
0143         break;
0144     };
0145 }
0146 
0147 static Objects_Maximum T_extension_count;
0148 
0149 static void
0150 T_rtems_extensions_run_initialize(void)
0151 {
0152     T_extension_count = T_objects_count(OBJECTS_CLASSIC_API,
0153         OBJECTS_RTEMS_EXTENSIONS);
0154 }
0155 
0156 static void
0157 T_rtems_extensions_case_end(void)
0158 {
0159     T_objects_check(OBJECTS_CLASSIC_API, OBJECTS_RTEMS_EXTENSIONS,
0160         &T_extension_count, "RTEMS extension");
0161 }
0162 
0163 void
0164 T_check_rtems_extensions(T_event event, const char *name)
0165 {
0166     (void)name;
0167 
0168     switch (event) {
0169     case T_EVENT_RUN_INITIALIZE_EARLY:
0170         T_rtems_extensions_run_initialize();
0171         break;
0172     case T_EVENT_CASE_END:
0173         T_rtems_extensions_case_end();
0174         break;
0175     default:
0176         break;
0177     };
0178 }
0179 
0180 static Objects_Maximum T_mq_count;
0181 
0182 static void
0183 T_rtems_message_queues_run_initialize(void)
0184 {
0185     T_mq_count = T_objects_count(OBJECTS_CLASSIC_API,
0186         OBJECTS_RTEMS_MESSAGE_QUEUES);
0187 }
0188 
0189 static void
0190 T_rtems_message_queues_case_end(void)
0191 {
0192     T_objects_check(OBJECTS_CLASSIC_API, OBJECTS_RTEMS_MESSAGE_QUEUES,
0193         &T_mq_count, "RTEMS message queue");
0194 }
0195 
0196 void
0197 T_check_rtems_message_queues(T_event event, const char *name)
0198 {
0199     (void)name;
0200 
0201     switch (event) {
0202     case T_EVENT_RUN_INITIALIZE_EARLY:
0203         T_rtems_message_queues_run_initialize();
0204         break;
0205     case T_EVENT_CASE_END:
0206         T_rtems_message_queues_case_end();
0207         break;
0208     default:
0209         break;
0210     };
0211 }
0212 
0213 static Objects_Maximum T_part_count;
0214 
0215 static void
0216 T_rtems_partitions_run_initialize(void)
0217 {
0218     T_part_count = T_objects_count(OBJECTS_CLASSIC_API,
0219         OBJECTS_RTEMS_PARTITIONS);
0220 }
0221 
0222 static void
0223 T_rtems_partitions_case_end(void)
0224 {
0225     T_objects_check(OBJECTS_CLASSIC_API, OBJECTS_RTEMS_PARTITIONS,
0226         &T_part_count, "RTEMS partition");
0227 }
0228 
0229 void
0230 T_check_rtems_partitions(T_event event, const char *name)
0231 {
0232     (void)name;
0233 
0234     switch (event) {
0235     case T_EVENT_RUN_INITIALIZE_EARLY:
0236         T_rtems_partitions_run_initialize();
0237         break;
0238     case T_EVENT_CASE_END:
0239         T_rtems_partitions_case_end();
0240         break;
0241     default:
0242         break;
0243     };
0244 }
0245 
0246 static Objects_Maximum T_period_count;
0247 
0248 static void
0249 T_rtems_periods_run_initialize(void)
0250 {
0251     T_period_count = T_objects_count(OBJECTS_CLASSIC_API,
0252         OBJECTS_RTEMS_PERIODS);
0253 }
0254 
0255 static void
0256 T_rtems_periods_case_end(void)
0257 {
0258     T_objects_check(OBJECTS_CLASSIC_API, OBJECTS_RTEMS_PERIODS,
0259         &T_period_count, "RTEMS period");
0260 }
0261 
0262 void
0263 T_check_rtems_periods(T_event event, const char *name)
0264 {
0265     (void)name;
0266 
0267     switch (event) {
0268     case T_EVENT_RUN_INITIALIZE_EARLY:
0269         T_rtems_periods_run_initialize();
0270         break;
0271     case T_EVENT_CASE_END:
0272         T_rtems_periods_case_end();
0273         break;
0274     default:
0275         break;
0276     };
0277 }
0278 
0279 static Objects_Maximum T_region_count;
0280 
0281 static void
0282 T_rtems_regions_run_initialize(void)
0283 {
0284     T_region_count = T_objects_count(OBJECTS_CLASSIC_API,
0285         OBJECTS_RTEMS_REGIONS);
0286 }
0287 
0288 static void
0289 T_rtems_regions_case_end(void)
0290 {
0291     T_objects_check(OBJECTS_CLASSIC_API, OBJECTS_RTEMS_REGIONS,
0292         &T_region_count, "RTEMS region");
0293 }
0294 
0295 void
0296 T_check_rtems_regions(T_event event, const char *name)
0297 {
0298     (void)name;
0299 
0300     switch (event) {
0301     case T_EVENT_RUN_INITIALIZE_EARLY:
0302         T_rtems_regions_run_initialize();
0303         break;
0304     case T_EVENT_CASE_END:
0305         T_rtems_regions_case_end();
0306         break;
0307     default:
0308         break;
0309     };
0310 }
0311 
0312 static Objects_Maximum T_sema_count;
0313 
0314 static void
0315 T_rtems_semaphores_run_initialize(void)
0316 {
0317     T_sema_count = T_objects_count(OBJECTS_CLASSIC_API,
0318         OBJECTS_RTEMS_SEMAPHORES);
0319 }
0320 
0321 static void
0322 T_rtems_semaphores_case_end(void)
0323 {
0324     T_objects_check(OBJECTS_CLASSIC_API, OBJECTS_RTEMS_SEMAPHORES,
0325         &T_sema_count, "RTEMS semaphore");
0326 }
0327 
0328 void
0329 T_check_rtems_semaphores(T_event event, const char *name)
0330 {
0331     (void)name;
0332 
0333     switch (event) {
0334     case T_EVENT_RUN_INITIALIZE_EARLY:
0335         T_rtems_semaphores_run_initialize();
0336         break;
0337     case T_EVENT_CASE_END:
0338         T_rtems_semaphores_case_end();
0339         break;
0340     default:
0341         break;
0342     };
0343 }
0344 
0345 static Objects_Maximum T_task_count;
0346 
0347 static void
0348 T_rtems_tasks_run_initialize(void)
0349 {
0350     T_task_count = T_objects_count(OBJECTS_CLASSIC_API,
0351         OBJECTS_RTEMS_TASKS);
0352 }
0353 
0354 static void
0355 T_rtems_tasks_case_end(void)
0356 {
0357     _RTEMS_Lock_allocator();
0358     _Thread_Kill_zombies();
0359     _RTEMS_Unlock_allocator();
0360 
0361     T_objects_check(OBJECTS_CLASSIC_API, OBJECTS_RTEMS_TASKS,
0362         &T_task_count, "RTEMS task");
0363 }
0364 
0365 void
0366 T_check_rtems_tasks(T_event event, const char *name)
0367 {
0368     (void)name;
0369 
0370     switch (event) {
0371     case T_EVENT_RUN_INITIALIZE_EARLY:
0372         T_rtems_tasks_run_initialize();
0373         break;
0374     case T_EVENT_CASE_END:
0375         T_rtems_tasks_case_end();
0376         break;
0377     default:
0378         break;
0379     };
0380 }
0381 
0382 static Objects_Maximum T_timer_count;
0383 
0384 static void
0385 T_rtems_timers_run_initialize(void)
0386 {
0387     T_timer_count = T_objects_count(OBJECTS_CLASSIC_API,
0388         OBJECTS_RTEMS_TIMERS);
0389 }
0390 
0391 static void
0392 T_rtems_timers_case_end(void)
0393 {
0394     T_objects_check(OBJECTS_CLASSIC_API, OBJECTS_RTEMS_TIMERS,
0395         &T_timer_count, "RTEMS timer");
0396 }
0397 
0398 void
0399 T_check_rtems_timers(T_event event, const char *name)
0400 {
0401     (void)name;
0402 
0403     switch (event) {
0404     case T_EVENT_RUN_INITIALIZE_EARLY:
0405         T_rtems_timers_run_initialize();
0406         break;
0407     case T_EVENT_CASE_END:
0408         T_rtems_timers_case_end();
0409         break;
0410     default:
0411         break;
0412     };
0413 }
0414 
0415 void *
0416 T_seize_objects(rtems_status_code (*create)(void *, uint32_t *), void *arg)
0417 {
0418     void *objects;
0419 
0420     objects = NULL;
0421 
0422     while (true) {
0423         rtems_status_code sc;
0424         rtems_id id;
0425 
0426         id = 0;
0427         sc = (*create)(arg, &id);
0428 
0429         if (sc == RTEMS_SUCCESSFUL) {
0430             const Objects_Information *info;
0431             Objects_Control *obj;
0432 
0433             info = _Objects_Get_information_id(id);
0434             T_quiet_assert_not_null(info);
0435             obj = _Objects_Get_no_protection(id, info);
0436             T_quiet_assert_not_null(obj);
0437             obj->Node.next = objects;
0438             objects = obj;
0439         } else {
0440             T_quiet_rsc(sc, RTEMS_TOO_MANY);
0441             break;
0442         }
0443     }
0444 
0445     return objects;
0446 }
0447 
0448 void
0449 T_surrender_objects(void **objects_p, rtems_status_code (*delete)(uint32_t))
0450 {
0451     void *objects;
0452 
0453     objects = *objects_p;
0454     *objects_p = NULL;
0455 
0456     while (objects != NULL) {
0457         Objects_Control *obj;
0458         rtems_status_code sc;
0459 
0460         obj = objects;
0461         objects = _Chain_Next(&obj->Node);
0462         _Chain_Set_off_chain(&obj->Node);
0463 
0464         sc = (*delete)(obj->id);
0465         T_quiet_rsc_success(sc);
0466     }
0467 }