source: rtems/testsuites/support/include/tmacros.h @ fc0756e

4.115
Last change on this file since fc0756e was fc0756e, checked in by Joel Sherrill <joel.sherrill@…>, on 04/14/15 at 15:01:05

Add test assertion for allocator mutex being unlocked

The Allocator Mutex should not be locked outside a tested
service call. In an SMP test or heavily multithreaded test,
this is possible since another thread could have the lock
for an extended period of time but this is not the norm
for the tests.

updates 2319.

  • Property mode set to 100644
File size: 10.8 KB
Line 
1/**
2 * @file
3 *
4 * This include file contains macros which are useful in the RTEMS
5 * test suites.
6 */
7
8/*
9 *  COPYRIGHT (c) 1989-2014.
10 *  On-Line Applications Research Corporation (OAR).
11 *
12 *  The license and distribution terms for this file may be
13 *  found in the file LICENSE in this distribution or at
14 *  http://www.rtems.org/license/LICENSE.
15 */
16
17#ifndef __TMACROS_h
18#define __TMACROS_h
19
20#include <inttypes.h>
21#include <bsp.h>    /* includes <rtems.h> */
22
23#include <ctype.h>
24#include <stdio.h>
25#include <stdlib.h>
26#include <string.h>
27#include <rtems/error.h>
28#include <rtems/test.h>
29#include <rtems/score/threaddispatch.h>
30
31#include <buffer_test_io.h>
32
33#ifdef __cplusplus
34extern "C" {
35#endif
36
37#define FOREVER 1                  /* infinite loop */
38
39#ifdef CONFIGURE_INIT
40#define TEST_EXTERN
41#else
42#define TEST_EXTERN extern
43#endif
44
45/*
46 *  Check that that the dispatch disable level is proper for the
47 *  mode/state of the test.  Normally it should be 0 when in task space.
48 *
49 *  This test is only valid when in a non-SMP system.  In an smp system
50 *  another cpu may be accessing the core at any point when this core
51 *  does not have it locked.
52 */
53#if defined SMPTEST
54 #define check_dispatch_disable_level( _expect )
55#else
56 #define check_dispatch_disable_level( _expect ) \
57  do { \
58    if ( (_expect) != -1 \
59           && (((!_Thread_Dispatch_is_enabled()) == false && (_expect) != 0) \
60             || ((!_Thread_Dispatch_is_enabled()) && (_expect) == 0)) \
61    ) { \
62      printk( \
63        "\n_Thread_Dispatch_disable_level is (%" PRId32 \
64           ") not %d detected at %s:%d\n", \
65         !_Thread_Dispatch_is_enabled(), (_expect), __FILE__, __LINE__ ); \
66      FLUSH_OUTPUT(); \
67      rtems_test_exit( 1 ); \
68    } \
69  } while ( 0 )
70#endif
71
72/*
73 *  Check that that the allocator mutex is not locked. It should never
74 *  be locked unless inside a service which is allocating a resource.
75 *
76 *  This test is only valid when in a non-SMP system.  In an SMP system
77 *  another cpu may be allocating a resource while we are computing.
78 */
79#if defined SMPTEST
80  #define check_if_allocator_mutex_is_unlocked()
81#else
82  #include <rtems/score/apimutex.h>
83  #define check_if_allocator_mutex_is_unlocked() \
84    do { \
85      if ( _RTEMS_Check_if_allocator_is_locked() ) { \
86        printk( \
87          "\nRTEMS Allocator Mutex is locked and should not be.\n" \
88          "Detected at %s:%d\n", \
89          __FILE__, \
90          __LINE__ \
91        ); \
92        FLUSH_OUTPUT(); \
93        rtems_test_exit( 1 ); \
94      } \
95    } while ( 0 )
96#endif
97
98/*
99 *  These macros properly report errors within the Classic API
100 */
101#define directive_failed( _dirstat, _failmsg )  \
102 fatal_directive_status( _dirstat, RTEMS_SUCCESSFUL, _failmsg )
103
104#define directive_failed_with_level( _dirstat, _failmsg, _level )  \
105 fatal_directive_status_with_level( \
106      _dirstat, RTEMS_SUCCESSFUL, _failmsg, _level )
107
108#define fatal_directive_status( _stat, _desired, _msg ) \
109  fatal_directive_status_with_level( _stat, _desired, _msg, 0 )
110
111#define fatal_directive_check_status_only( _stat, _desired, _msg ) \
112  do { \
113    if ( (_stat) != (_desired) ) { \
114      printf( "\n%s FAILED -- expected (%s) got (%s)\n", \
115              (_msg), rtems_status_text(_desired), rtems_status_text(_stat) ); \
116      FLUSH_OUTPUT(); \
117      rtems_test_exit( _stat ); \
118    } \
119  } while ( 0 )
120
121#define fatal_directive_status_with_level( _stat, _desired, _msg, _level ) \
122  do { \
123    check_dispatch_disable_level( _level ); \
124    check_if_allocator_mutex_is_unlocked(); \
125    fatal_directive_check_status_only( _stat, _desired, _msg ); \
126  } while ( 0 )
127
128/*
129 *  These macros properly report errors from the POSIX API
130 */
131
132#define posix_service_failed( _dirstat, _failmsg )  \
133 fatal_posix_service_status( _dirstat, 0, _failmsg )
134
135#define posix_service_failed_with_level( _dirstat, _failmsg, _level )  \
136 fatal_posix_service_status_with_level( _dirstat, 0, _failmsg, _level )
137
138#define fatal_posix_service_status_errno( _stat, _desired, _msg ) \
139  if ( (_stat != -1) && (errno) != (_desired) ) { \
140    long statx = _stat; \
141    check_dispatch_disable_level( 0 ); \
142    check_if_allocator_mutex_is_unlocked(); \
143    printf( "\n%s FAILED -- expected (%d - %s) got (%ld %d - %s)\n", \
144            (_msg), _desired, strerror(_desired), \
145            statx, errno, strerror(errno) ); \
146    FLUSH_OUTPUT(); \
147    rtems_test_exit( _stat ); \
148  }
149
150#define fatal_posix_service_status( _stat, _desired, _msg ) \
151  fatal_posix_service_status_with_level( _stat, _desired, _msg, 0 )
152
153#define fatal_posix_service_status_with_level( _stat, _desired, _msg, _level ) \
154  do { \
155    check_dispatch_disable_level( _level ); \
156    check_if_allocator_mutex_is_unlocked(); \
157    if ( (_stat) != (_desired) ) { \
158      printf( "\n%s FAILED -- expected (%d - %s) got (%d - %s)\n", \
159              (_msg), _desired, strerror(_desired), _stat, strerror(_stat) ); \
160      printf( "\n FAILED -- errno (%d - %s)\n", \
161              errno, strerror(errno) ); \
162      FLUSH_OUTPUT(); \
163      rtems_test_exit( _stat ); \
164    } \
165  } while ( 0 )
166
167/*
168 * This macro evaluates the semaphore id returned.
169 */
170#define fatal_posix_sem( _ptr, _msg ) \
171  if ( (_ptr != SEM_FAILED) ) { \
172    check_dispatch_disable_level( 0 ); \
173    printf( "\n%s FAILED -- expected (-1) got (%p - %d/%s)\n", \
174            (_msg), _ptr, errno, strerror(errno) ); \
175    FLUSH_OUTPUT(); \
176    rtems_test_exit( -1 ); \
177  }
178
179/*
180 * This macro evaluates the message queue id returned.
181 */
182#define fatal_posix_mqd( _ptr, _msg ) \
183  if ( (_ptr != (mqd_t) -1) ) { \
184    check_dispatch_disable_level( 0 ); \
185    printf( "\n%s FAILED -- expected (-1) got (%" PRId32 " - %d/%s)\n", \
186            (_msg), _ptr, errno, strerror(errno) ); \
187    FLUSH_OUTPUT(); \
188    rtems_test_exit( -1 ); \
189  }
190
191/*
192 *  Generic integer version of the error reporting
193 */
194
195#define int_service_failed( _dirstat, _failmsg )  \
196 fatal_int_service_status( _dirstat, RTEMS_SUCCESSFUL, _failmsg )
197
198#define int_service_failed_with_level( _dirstat, _failmsg, _level )  \
199 fatal_int_service_status_with_level( \
200      _dirstat, RTEMS_SUCCESSFUL, _failmsg, _level )
201
202#define fatal_int_service_status( _stat, _desired, _msg ) \
203  fatal_int_service_status_with_level( _stat, _desired, _msg, 0 )
204
205#define fatal_int_service_status_with_level( _stat, _desired, _msg, _level ) \
206  do { \
207    check_dispatch_disable_level( _level ); \
208    if ( (_stat) != (_desired) ) { \
209      printf( "\n%s FAILED -- expected (%d) got (%d)\n", \
210              (_msg), (_desired), (_stat) ); \
211      FLUSH_OUTPUT(); \
212      rtems_test_exit( _stat ); \
213    } \
214  } while ( 0 )
215
216
217/*
218 *  Print the time
219 */
220
221#define sprint_time(_str, _s1, _tb, _s2) \
222  do { \
223    sprintf( (_str), "%s%02d:%02d:%02d   %02d/%02d/%04d%s", \
224       _s1, (_tb)->hour, (_tb)->minute, (_tb)->second, \
225       (_tb)->month, (_tb)->day, (_tb)->year, _s2 ); \
226  } while ( 0 )
227
228#define print_time(_s1, _tb, _s2) \
229  do { \
230    printf( "%s%02" PRIu32 ":%02" PRIu32 ":%02" PRIu32 "   %02" PRIu32 "/%02" PRIu32 "/%04" PRIu32 "%s", \
231       _s1, (_tb)->hour, (_tb)->minute, (_tb)->second, \
232       (_tb)->month, (_tb)->day, (_tb)->year, _s2 ); \
233  } while ( 0 )
234
235#define put_dot( _c ) \
236  do { \
237    putchar( _c ); \
238    FLUSH_OUTPUT(); \
239  } while ( 0 )
240
241#define new_line  puts( "" )
242
243#define puts_nocr printf
244
245#ifdef RTEMS_TEST_NO_PAUSE
246#define rtems_test_pause() \
247    do { \
248      printf( "<pause>\n" ); \
249      FLUSH_OUTPUT(); \
250  } while ( 0 )
251
252#define rtems_test_pause_and_screen_number( _screen ) \
253  do { \
254    printf( "<pause - screen %d>\n", (_screen) ); \
255    FLUSH_OUTPUT(); \
256  } while ( 0 )
257#else
258#define rtems_test_pause() \
259  do { \
260    char buffer[ 80 ]; \
261    printf( "<pause>" ); \
262    FLUSH_OUTPUT(); \
263    gets( buffer ); \
264    puts( "" ); \
265  } while ( 0 )
266
267#define rtems_test_pause_and_screen_number( _screen ) \
268  do { \
269    char buffer[ 80 ]; \
270    printf( "<pause - screen %d>", (_screen) ); \
271    FLUSH_OUTPUT(); \
272    gets( buffer ); \
273    puts( "" ); \
274  } while ( 0 )
275#endif
276
277#define put_name( name, crlf ) \
278{ int c0, c1, c2, c3; \
279  c0 = (name >> 24) & 0xff; \
280  c1 = (name >> 16) & 0xff; \
281  c2 = (name >> 8) & 0xff; \
282  c3 = name & 0xff; \
283  putchar( (isprint(c0)) ? c0 : '*' ); \
284  if ( c1 ) putchar( (isprint(c1)) ? c1 : '*' ); \
285  if ( c2 ) putchar( (isprint(c2)) ? c2 : '*' ); \
286  if ( c3 ) putchar( (isprint(c3)) ? c3 : '*' ); \
287  if ( crlf ) \
288    putchar( '\n' ); \
289}
290
291#ifndef build_time
292#define build_time( TB, MON, DAY, YR, HR, MIN, SEC, TK ) \
293  { (TB)->year   = YR;  \
294    (TB)->month  = MON; \
295    (TB)->day    = DAY; \
296    (TB)->hour   = HR;  \
297    (TB)->minute = MIN; \
298    (TB)->second = SEC; \
299    (TB)->ticks  = TK; }
300#endif
301
302#define task_number( tid ) \
303  ( rtems_object_id_get_index( tid ) - \
304      rtems_configuration_get_rtems_api_configuration()-> \
305        number_of_initialization_tasks )
306
307#define rtems_test_assert(__exp) \
308  do { \
309    if (!(__exp)) { \
310      printf( "%s: %d %s\n", __FILE__, __LINE__, #__exp ); \
311      rtems_test_exit(0); \
312    } \
313  } while (0)
314
315/*
316 * Various inttypes.h-stype macros to assist printing
317 * certain system types on different targets.
318 */
319
320#if defined(RTEMS_USE_16_BIT_OBJECT)
321#define PRIxrtems_id PRIx16
322#else
323#define PRIxrtems_id PRIx32
324#endif
325
326/* c.f. cpukit/score/include/rtems/score/priority.h */
327#define PRIdPriority_Control PRId32
328#define PRIxPriority_Control PRIx32
329/* rtems_task_priority is a typedef to Priority_Control */
330#define PRIdrtems_task_priority PRIdPriority_Control
331#define PRIxrtems_task_priority PRIxPriority_Control
332
333/* c.f. cpukit/score/include/rtems/score/watchdog.h */
334#define PRIdWatchdog_Interval PRIu32
335/* rtems_interval is a typedef to Watchdog_Interval */
336#define PRIdrtems_interval    PRIdWatchdog_Interval
337
338/* c.f. cpukit/score/include/rtems/score/thread.h */
339#define PRIdThread_Entry_numeric_type PRIuPTR
340/* rtems_task_argument is a typedef to Thread_Entry_numeric_type */
341#define PRIdrtems_task_argument PRIdThread_Entry_numeric_type
342
343/* rtems_event_set is a typedef to unit32_t */
344#define PRIxrtems_event_set PRIx32
345
346/* HACK: newlib defines pthread_t as a typedef to __uint32_t */
347/* HACK: There is no portable way to print pthread_t's */
348#define PRIxpthread_t PRIx32
349
350/* rtems_signal_set is a typedef to uint32_t */
351#define PRIxrtems_signal_set PRIx32
352
353/* newlib's ino_t is a typedef to "unsigned long" */
354#define PRIxino_t "lx"
355
356/**
357 * This assists in clearly disabling warnings on GCC in certain very
358 * specific cases.
359 *
360 * + -Wnon-null - If a method is declared as never having a NULL first
361 *   parameter. We need to explicitly disable this compiler warning to make
362 *   the code warning free.
363 */
364#ifdef __GNUC__
365  #define COMPILER_DIAGNOSTIC_SETTINGS_PUSH _Pragma("GCC diagnostic push")
366  #define COMPILER_DIAGNOSTIC_SETTINGS_POP _Pragma("GCC diagnostic pop")
367  #define COMPILER_DIAGNOSTIC_SETTINGS_DISABLE_NONNULL \
368    _Pragma("GCC diagnostic ignored \"-Wnonnull\"")
369#else
370  #define COMPILER_DIAGNOSTIC_SETTINGS_PUSH
371  #define COMPILER_DIAGNOSTIC_SETTINGS_POP
372  #define COMPILER_DIAGNOSTIC_SETTINGS_DISABLE_NONNULL
373#endif
374
375#ifdef __cplusplus
376}
377#endif
378
379#endif
Note: See TracBrowser for help on using the repository browser.