Back to home page

LXR

 
 

    


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

0001 /* SPDX-License-Identifier: BSD-2-Clause */
0002 
0003 /**
0004  * @file
0005  *
0006  * This include file contains macros which are useful in the RTEMS
0007  * test suites.
0008  */
0009 
0010 /*
0011  *  COPYRIGHT (c) 1989-2014.
0012  *  On-Line Applications Research Corporation (OAR).
0013  *
0014  * Redistribution and use in source and binary forms, with or without
0015  * modification, are permitted provided that the following conditions
0016  * are met:
0017  * 1. Redistributions of source code must retain the above copyright
0018  *    notice, this list of conditions and the following disclaimer.
0019  * 2. Redistributions in binary form must reproduce the above copyright
0020  *    notice, this list of conditions and the following disclaimer in the
0021  *    documentation and/or other materials provided with the distribution.
0022  *
0023  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
0024  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
0025  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
0026  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
0027  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
0028  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
0029  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
0030  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
0031  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
0032  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
0033  * POSSIBILITY OF SUCH DAMAGE.
0034  */
0035 
0036 #ifndef __TMACROS_h
0037 #define __TMACROS_h
0038 
0039 #include <inttypes.h>
0040 #include <rtems/inttypes.h>
0041 #include <bsp.h>    /* includes <rtems.h> */
0042 
0043 #include <ctype.h>
0044 #include <stdio.h>
0045 #include <stdlib.h>
0046 #include <string.h>
0047 #include <rtems/error.h>
0048 #include <rtems/test-info.h>
0049 #include <rtems/test-printer.h>
0050 #include <rtems/score/threaddispatch.h>
0051 
0052 #include <buffer_test_io.h>
0053 
0054 #ifdef __cplusplus
0055 extern "C" {
0056 #endif
0057 
0058 #define FOREVER 1                  /* infinite loop */
0059 
0060 #ifdef CONFIGURE_INIT
0061 #define TEST_EXTERN
0062 #else
0063 #define TEST_EXTERN extern
0064 #endif
0065 
0066 /*
0067  *  Check that that the dispatch disable level is proper for the
0068  *  mode/state of the test.  Normally it should be 0 when in task space.
0069  */
0070 #define check_dispatch_disable_level( _expect ) \
0071   do { \
0072     if ( (_expect) != -1 \
0073            && (((!_Thread_Dispatch_is_enabled()) == false && (_expect) != 0) \
0074              || ((!_Thread_Dispatch_is_enabled()) && (_expect) == 0)) \
0075     ) { \
0076       printf( \
0077         "\n_Thread_Dispatch_disable_level is (%i)" \
0078            " not %d detected at %s:%d\n", \
0079          !_Thread_Dispatch_is_enabled(), (_expect), __FILE__, __LINE__ ); \
0080       rtems_test_exit( 1 ); \
0081     } \
0082   } while ( 0 )
0083 
0084 /*
0085  *  Check that that the allocator mutex is not owned by the executing thread.
0086  */
0087 #include <rtems/score/apimutex.h>
0088 #define check_if_allocator_mutex_is_not_owned() \
0089   do { \
0090     if ( _RTEMS_Allocator_is_owner() ) { \
0091       printf( \
0092         "\nRTEMS Allocator Mutex is owned by executing thread " \
0093           "and should not be.\n" \
0094         "Detected at %s:%d\n", \
0095         __FILE__, \
0096         __LINE__ \
0097       ); \
0098       rtems_test_exit( 1 ); \
0099     } \
0100   } while ( 0 )
0101 
0102 /*
0103  *  These macros properly report errors within the Classic API
0104  */
0105 #define directive_failed( _dirstat, _failmsg )  \
0106  fatal_directive_status( _dirstat, RTEMS_SUCCESSFUL, _failmsg )
0107 
0108 #define directive_failed_with_level( _dirstat, _failmsg, _level )  \
0109  fatal_directive_status_with_level( \
0110       _dirstat, RTEMS_SUCCESSFUL, _failmsg, _level )
0111 
0112 #define fatal_directive_status( _stat, _desired, _msg ) \
0113   fatal_directive_status_with_level( _stat, _desired, _msg, 0 )
0114 
0115 #define fatal_directive_check_status_only( _stat, _desired, _msg ) \
0116   do { \
0117     if ( (_stat) != (_desired) ) { \
0118       printf( "\n%s FAILED -- expected (%s) got (%s)\n", \
0119               (_msg), rtems_status_text(_desired), rtems_status_text(_stat) ); \
0120       rtems_test_exit( _stat ); \
0121     } \
0122   } while ( 0 )
0123 
0124 #define fatal_directive_status_with_level( _stat, _desired, _msg, _level ) \
0125   do { \
0126     check_dispatch_disable_level( _level ); \
0127     check_if_allocator_mutex_is_not_owned(); \
0128     fatal_directive_check_status_only( _stat, _desired, _msg ); \
0129   } while ( 0 )
0130 
0131 /*
0132  *  These macros properly report errors from the POSIX API
0133  */
0134 
0135 #define posix_service_failed( _dirstat, _failmsg )  \
0136  fatal_posix_service_status( _dirstat, 0, _failmsg )
0137 
0138 #define posix_service_failed_with_level( _dirstat, _failmsg, _level )  \
0139  fatal_posix_service_status_with_level( _dirstat, 0, _failmsg, _level )
0140 
0141 #define fatal_posix_service_status_errno( _stat, _desired, _msg ) \
0142   if ( (_stat != -1) && (errno) != (_desired) ) { \
0143     long statx = _stat; \
0144     check_dispatch_disable_level( 0 ); \
0145     check_if_allocator_mutex_is_not_owned(); \
0146     printf( "\n%s FAILED -- expected (%d - %s) got (%ld %d - %s)\n", \
0147         (_msg), _desired, strerror(_desired), \
0148             statx, errno, strerror(errno) ); \
0149     rtems_test_exit( _stat ); \
0150   }
0151 
0152 #define fatal_posix_service_status( _stat, _desired, _msg ) \
0153   fatal_posix_service_status_with_level( _stat, _desired, _msg, 0 )
0154 
0155 #define fatal_posix_service_status_with_level( _stat, _desired, _msg, _level ) \
0156   do { \
0157     check_dispatch_disable_level( _level ); \
0158     check_if_allocator_mutex_is_not_owned(); \
0159     if ( (_stat) != (_desired) ) { \
0160       printf( "\n%s FAILED -- expected (%d - %s) got (%d - %s)\n", \
0161               (_msg), _desired, strerror(_desired), _stat, strerror(_stat) ); \
0162       printf( "\n FAILED -- errno (%d - %s)\n", \
0163               errno, strerror(errno) ); \
0164       rtems_test_exit( _stat ); \
0165     } \
0166   } while ( 0 )
0167 
0168 /*
0169  * This macro evaluates the semaphore id returned.
0170  */
0171 #define fatal_posix_sem( _ptr, _msg ) \
0172   if ( (_ptr != SEM_FAILED) ) { \
0173     check_dispatch_disable_level( 0 ); \
0174     printf( "\n%s FAILED -- expected (-1) got (%p - %d/%s)\n", \
0175         (_msg), _ptr, errno, strerror(errno) ); \
0176     rtems_test_exit( -1 ); \
0177   }
0178 
0179 /*
0180  * This macro evaluates the message queue id returned.
0181  */
0182 #define fatal_posix_mqd( _ptr, _msg ) \
0183   if ( (_ptr != (mqd_t) -1) ) { \
0184     check_dispatch_disable_level( 0 ); \
0185     printf( "\n%s FAILED -- expected (-1) got (%" PRId32 " - %d/%s)\n", \
0186         (_msg), _ptr, errno, strerror(errno) ); \
0187     rtems_test_exit( -1 ); \
0188   }
0189 
0190 /*
0191  *  Generic integer version of the error reporting
0192  */
0193 
0194 #define int_service_failed( _dirstat, _failmsg )  \
0195  fatal_int_service_status( _dirstat, RTEMS_SUCCESSFUL, _failmsg )
0196 
0197 #define int_service_failed_with_level( _dirstat, _failmsg, _level )  \
0198  fatal_int_service_status_with_level( \
0199       _dirstat, RTEMS_SUCCESSFUL, _failmsg, _level )
0200 
0201 #define fatal_int_service_status( _stat, _desired, _msg ) \
0202   fatal_int_service_status_with_level( _stat, _desired, _msg, 0 )
0203 
0204 #define fatal_int_service_status_with_level( _stat, _desired, _msg, _level ) \
0205   do { \
0206     check_dispatch_disable_level( _level ); \
0207     if ( (_stat) != (_desired) ) { \
0208       printf( "\n%s FAILED -- expected (%d) got (%d)\n", \
0209               (_msg), (_desired), (_stat) ); \
0210       rtems_test_exit( _stat ); \
0211     } \
0212   } while ( 0 )
0213 
0214 
0215 /*
0216  *  Print the time
0217  */
0218 
0219 #define sprint_time(_str, _s1, _tb, _s2) \
0220   do { \
0221     sprintf( (_str), "%s%02d:%02d:%02d   %02d/%02d/%04d%s", \
0222        _s1, (_tb)->hour, (_tb)->minute, (_tb)->second, \
0223        (_tb)->month, (_tb)->day, (_tb)->year, _s2 ); \
0224   } while ( 0 )
0225 
0226 #define print_time(_s1, _tb, _s2) \
0227   do { \
0228     printf( "%s%02" PRIu32 ":%02" PRIu32 ":%02" PRIu32 "   %02" PRIu32 "/%02" PRIu32 "/%04" PRIu32 "%s", \
0229        _s1, (_tb)->hour, (_tb)->minute, (_tb)->second, \
0230        (_tb)->month, (_tb)->day, (_tb)->year, _s2 ); \
0231   } while ( 0 )
0232 
0233 #define put_dot( _c ) \
0234   do { \
0235     putchar( _c ); \
0236   } while ( 0 )
0237 
0238 #define new_line  puts( "" )
0239 
0240 #define puts_nocr printf
0241 
0242 #define put_name( name, crlf ) \
0243 { int c0, c1, c2, c3; \
0244   c0 = (name >> 24) & 0xff; \
0245   c1 = (name >> 16) & 0xff; \
0246   c2 = (name >> 8) & 0xff; \
0247   c3 = name & 0xff; \
0248   putchar( (isprint(c0)) ? c0 : '*' ); \
0249   if ( c1 ) putchar( (isprint(c1)) ? c1 : '*' ); \
0250   if ( c2 ) putchar( (isprint(c2)) ? c2 : '*' ); \
0251   if ( c3 ) putchar( (isprint(c3)) ? c3 : '*' ); \
0252   if ( crlf ) \
0253     putchar( '\n' ); \
0254 }
0255 
0256 #ifndef build_time
0257 #define build_time( TB, MON, DAY, YR, HR, MIN, SEC, TK ) \
0258   { (TB)->year   = YR;  \
0259     (TB)->month  = MON; \
0260     (TB)->day    = DAY; \
0261     (TB)->hour   = HR;  \
0262     (TB)->minute = MIN; \
0263     (TB)->second = SEC; \
0264     (TB)->ticks  = TK; }
0265 #endif
0266 
0267 #define task_number( tid ) \
0268   ( rtems_object_id_get_index( tid ) - \
0269       rtems_configuration_get_rtems_api_configuration()-> \
0270         number_of_initialization_tasks )
0271 
0272 #define rtems_test_assert(__exp) \
0273   do { \
0274     if (!(__exp)) { \
0275       printf( "%s: %d %s\n", __FILE__, __LINE__, #__exp ); \
0276       rtems_test_exit(0); \
0277     } \
0278   } while (0)
0279 
0280 /**
0281  * This assists in clearly disabling warnings on GCC in certain very
0282  * specific cases.
0283  *
0284  * + -Wnon-null - If a method is declared as never having a NULL first
0285  *   parameter. We need to explicitly disable this compiler warning to make
0286  *   the code warning free.
0287  */
0288 #ifdef __GNUC__
0289   #define COMPILER_DIAGNOSTIC_SETTINGS_PUSH _Pragma("GCC diagnostic push")
0290   #define COMPILER_DIAGNOSTIC_SETTINGS_POP _Pragma("GCC diagnostic pop")
0291   #define COMPILER_DIAGNOSTIC_SETTINGS_DISABLE_NONNULL \
0292     _Pragma("GCC diagnostic ignored \"-Wnonnull\"")
0293 #else
0294   #define COMPILER_DIAGNOSTIC_SETTINGS_PUSH
0295   #define COMPILER_DIAGNOSTIC_SETTINGS_POP
0296   #define COMPILER_DIAGNOSTIC_SETTINGS_DISABLE_NONNULL
0297 #endif
0298 
0299 #ifdef __cplusplus
0300 }
0301 #endif
0302 
0303 #endif