diff options
Diffstat (limited to 'testsuites/unit')
-rw-r--r-- | testsuites/unit/tc-base64-decode.c | 186 | ||||
-rw-r--r-- | testsuites/unit/tc-compiler-builtins.c | 1141 | ||||
-rw-r--r-- | testsuites/unit/tc-config.c | 171 | ||||
-rw-r--r-- | testsuites/unit/tc-crc.c | 48 | ||||
-rw-r--r-- | testsuites/unit/tc-misaligned-builtin-memcpy.c | 8 | ||||
-rw-r--r-- | testsuites/unit/tc-score-msgq.c | 452 | ||||
-rw-r--r-- | testsuites/unit/tc-score-rbtree.c | 8 | ||||
-rw-r--r-- | testsuites/unit/ts-unit-no-clock-0.c | 11 |
8 files changed, 2014 insertions, 11 deletions
diff --git a/testsuites/unit/tc-base64-decode.c b/testsuites/unit/tc-base64-decode.c new file mode 100644 index 0000000000..4b0672d310 --- /dev/null +++ b/testsuites/unit/tc-base64-decode.c @@ -0,0 +1,186 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ + +/** + * @file + * + * @ingroup TestsuitesUnitNoClock0 + */ + +/* + * Copyright (C) 2023 embedded brains GmbH & Co. KG + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <rtems/base64.h> + +#include <rtems/test.h> + +typedef struct { + Base64_Decode_control base; + uint8_t buf[64]; +} test_control; + +static int test_run(test_control* self, const char* payload) { + size_t len = strlen(payload); + + for (size_t i = 0; i < len; ++i) { + int rv = _Base64_Decode(&self->base, payload[i]); + + if (rv != 0) { + return rv; + } + } + + return 0; +} + +static int test_payload(test_control* self, const char* payload) { + memset(self->buf, 0xff, sizeof(self->buf)); + _Base64_Decode_initialize(&self->base, &self->buf[0], sizeof(self->buf)); + return test_run(self, payload); +} + +T_TEST_CASE(IOBase64Decode) { + int rv; + test_control instance; + test_control* self = &instance; + + rv = test_payload(self, "POOL"); + T_eq_int(rv, BASE64_DECODE_SUCCESS); + T_eq_int(self->base.state, BASE64_DECODE_STATE_0); + T_eq_ptr(self->base.target, &self->buf[3]); + const uint8_t expected1[] = {0x3c, 0xe3, 0x8b, 0xff}; + T_eq_mem(&self->buf[0], expected1, sizeof(expected1)); + + rv = test_payload(self, "ABCDEFGH"); + T_eq_int(rv, BASE64_DECODE_SUCCESS); + T_eq_int(self->base.state, BASE64_DECODE_STATE_0); + T_eq_ptr(self->base.target, &self->buf[6]); + const uint8_t expected2[] = {0x00, 0x10, 0x83, 0x10, 0x51, 0x87, 0xff}; + T_eq_mem(&self->buf[0], expected2, sizeof(expected2)); + + /* Non-base64 character results in an error */ + rv = test_payload(self, "PO*OL"); + T_eq_int(rv, BASE64_DECODE_INVALID_INPUT); + T_eq_int(self->base.state, BASE64_DECODE_STATE_2); + T_eq_ptr(self->base.target, &self->buf[1]); + const uint8_t expected3[] = {0x3c}; + T_eq_mem(&self->buf[0], expected3, sizeof(expected3)); + + /* Other non-base64 character results in an error */ + rv = test_payload(self, "PO\x80OL"); + T_eq_int(rv, BASE64_DECODE_INVALID_INPUT); + T_eq_int(self->base.state, BASE64_DECODE_STATE_2); + T_eq_ptr(self->base.target, &self->buf[1]); + T_eq_mem(&self->buf[0], expected3, sizeof(expected3)); + + /* Space characters should be ignored */ + rv = test_payload(self, "P OOL"); + T_eq_int(rv, BASE64_DECODE_SUCCESS); + T_eq_int(self->base.state, BASE64_DECODE_STATE_0); + T_eq_ptr(self->base.target, &self->buf[3]); + const uint8_t expected4[] = {0x3c, 0xe3, 0x8b, 0xff}; + T_eq_mem(&self->buf[0], expected4, sizeof(expected4)); + + /* Handle pad characters */ + rv = test_payload(self, "POOL=="); + T_eq_int(rv, BASE64_DECODE_SUCCESS); + T_eq_int(self->base.state, BASE64_DECODE_STATE_0); + T_eq_ptr(self->base.target, &self->buf[3]); + T_eq_ptr(self->base.target, self->base.target_end); + const uint8_t expected5[] = {0x3c, 0xe3, 0x8b, 0xff}; + T_eq_mem(&self->buf[0], expected5, sizeof(expected5)); + + /* If characters come after pad characters, an error results */ + rv = test_payload(self, "POOL==xy"); + T_eq_int(rv, BASE64_DECODE_OVERFLOW); + T_eq_int(self->base.state, BASE64_DECODE_SUCCESS); + T_eq_ptr(self->base.target, &self->buf[3]); + T_eq_ptr(self->base.target, self->base.target_end); + const uint8_t expected6[] = {0x3c, 0xe3, 0x8b, 0xff}; + T_eq_mem(&self->buf[0], expected6, sizeof(expected6)); + + rv = test_payload(self, "POOLPOOL"); + T_eq_int(rv, BASE64_DECODE_SUCCESS); + T_eq_int(self->base.state, BASE64_DECODE_STATE_0); + T_eq_ptr(self->base.target, &self->buf[6]); + const uint8_t expected7[] = {0x3c, 0xe3, 0x8b, 0x3c, 0xe3, 0x8b, 0xff}; + T_eq_mem(&self->buf[0], expected7, sizeof(expected7)); + + /* + * Test valid payload with series of target sizes. All target sizes + * less than three are invalid for the given payload and will result + * in an error. + */ + const uint8_t expected9[] = {0x3c, 0xe3, 0x8b, 0xff}; + + for (size_t i = 0; i < 4; ++i) { + memset(&self->buf[0], 0xff, sizeof(self->buf)); + _Base64_Decode_initialize(&self->base, &self->buf[0], i); + rv = test_run(self, "POOL"); + + if (i < 3) { + T_eq_int(rv, BASE64_DECODE_OVERFLOW); + T_eq_int(self->base.state, i); + T_ne_ptr(self->base.target, &self->buf[3]); + T_ne_mem(&self->buf[0], expected9, sizeof(expected9)); + } else { + T_eq_int(rv, BASE64_DECODE_SUCCESS); + T_eq_int(self->base.state, BASE64_DECODE_STATE_0); + T_eq_ptr(self->base.target, &self->buf[3]); + T_eq_mem(&self->buf[0], expected9, sizeof(expected9)); + } + } + + /* No overflow in state 1 */ + memset(&self->buf[0], 0xff, sizeof(self->buf)); + _Base64_Decode_initialize(&self->base, &self->buf[0], 1); + rv = test_run(self, "AA"); + T_eq_int(rv, BASE64_DECODE_SUCCESS); + T_eq_int(self->base.state, BASE64_DECODE_STATE_2); + T_eq_ptr(self->base.target, &self->buf[1]); + const uint8_t expected10[] = {0x00, 0xff}; + T_eq_mem(&self->buf[0], expected10, sizeof(expected10)); + + /* No overflow in state 2 */ + memset(&self->buf[0], 0xff, sizeof(self->buf)); + _Base64_Decode_initialize(&self->base, &self->buf[0], 2); + rv = test_run(self, "AAA"); + T_eq_int(rv, BASE64_DECODE_SUCCESS); + T_eq_int(self->base.state, BASE64_DECODE_STATE_3); + T_eq_ptr(self->base.target, &self->buf[2]); + const uint8_t expected11[] = {0x00, 0x00, 0xff}; + T_eq_mem(&self->buf[0], expected11, sizeof(expected11)); +} + +T_TEST_CASE(IOBase64DecodeInitialize) { + Base64_Decode_control instance; + Base64_Decode_control* self = &instance; + uint8_t buf[1]; + + memset(self, 0xff, sizeof(*self)); + _Base64_Decode_initialize(self, buf, sizeof(buf)); + T_eq_int(self->state, BASE64_DECODE_STATE_0); + T_eq_ptr(self->target, &buf[0]); + T_eq_ptr(self->target_end, &buf[1]); +} diff --git a/testsuites/unit/tc-compiler-builtins.c b/testsuites/unit/tc-compiler-builtins.c new file mode 100644 index 0000000000..7a470b6632 --- /dev/null +++ b/testsuites/unit/tc-compiler-builtins.c @@ -0,0 +1,1141 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ + +/** + * @file + * + * @ingroup CompilerUnitBuiltins + */ + +/* + * Copyright (C) 2023 embedded brains GmbH & Co. KG + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * This file is part of the RTEMS quality process and was automatically + * generated. If you find something that needs to be fixed or + * worded better please post a report or patch to an RTEMS mailing list + * or raise a bug report: + * + * https://www.rtems.org/bugs.html + * + * For information on updating and regenerating please refer to the How-To + * section in the Software Requirements Engineering chapter of the + * RTEMS Software Engineering manual. The manual is provided as a part of + * a release. For development sources please refer to the online + * documentation at: + * + * https://docs.rtems.org + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <setjmp.h> +#include <stdint.h> + +#include "../validation/tx-support.h" + +#include <rtems/test.h> + +/** + * @defgroup CompilerUnitBuiltins spec:/compiler/unit/builtins + * + * @ingroup TestsuitesUnitNoClock0 + * + * @brief These unit tests check compiler builtins. + * + * Explicitly test the 64-bit integer division and modulo operations. They are + * essential for the timekeeping services. On most 32-bit targets, they need a + * software implementation. + * + * This test case performs the following actions: + * + * - Check the return value of __builtin_clz() for a sample set of inputs. + * + * - Check the return value of __builtin_clzll() for a sample set of inputs. + * + * - Check the return value of __builtin_ctz() for a sample set of inputs. + * + * - Check the return value of __builtin_ctzll() for a sample set of inputs. + * + * - Check the return value of __builtin_ffs() for a sample set of inputs. + * + * - Check the return value of __builtin_ffsll() for a sample set of inputs. + * + * - Check the return value of __builtin_parity() for a sample set of inputs. + * + * - Check the return value of __builtin_parityll() for a sample set of inputs. + * + * - Check the return value of __builtin_popcount() for a sample set of inputs. + * + * - Check the return value of __builtin_popcountll() for a sample set of + * inputs. + * + * - Check the return value of __builtin_bswap32() for a sample set of inputs. + * + * - Check the return value of __builtin_bswap64() for a sample set of inputs. + * + * - Check signed 64-bit comparisons for a sample set of values. + * + * - Check unsigned 64-bit comparisons for a sample set of values. + * + * - Check signed 64-bit arithmetic left shift for a sample set of values. + * + * - Check signed 64-bit arithmetic right shift for a sample set of values. + * + * - Check unsigned 64-bit logical right shift for a sample set of values. + * + * - Check signed 64-bit multiplication for a sample set of values. + * + * - Check signed 64-bit negation for a sample set of values. + * + * - Check signed 64-bit divisions for a sample set of values. + * + * - Check unsigned 64-bit divisions for a sample set of values. + * + * - Check signed 64-bit modulo operations for a sample set of values. + * + * - Check unsigned 64-bit modulo operations for a sample set of values. + * + * @{ + */ + +#if __LONG_MAX__ == 0x7fffffffL && !defined(__aarch64__) +#define TEST_UDIVMODDI4 +#endif + +#if defined(TEST_UDIVMODDI4) +uint64_t __udivmoddi4( uint64_t n, uint64_t d, uint64_t *r ); +#endif + +#if defined(TEST_UDIVMODDI4) && defined(__arm__) +/* + * Here __aeabi_uldivmod() may be used to carry out integer division + * operations even though the reminder is unused. This function is + * implemented by __udivmoddi4() which may never get called without a + * reminder for compiler generated code. + */ +#define TEST_UDIVMODDI4_WITHOUT_REMINDER +#endif + +static bool do_longjmp; + +static jmp_buf exception_return_context; + +static void Fatal( + rtems_fatal_source source, + rtems_fatal_code code, + void *arg +) +{ + (void) code; + + if ( source == RTEMS_FATAL_SOURCE_EXCEPTION && do_longjmp ) { + do_longjmp = false; + _ISR_Set_level( 0 ); + longjmp( arg, 1 ); + } +} + +static void CompilerUnitBuiltins_Setup( void *ctx ) +{ + SetFatalHandler( Fatal, exception_return_context ); +} + +static void CompilerUnitBuiltins_Teardown( void *ctx ) +{ + SetFatalHandler( NULL, NULL ); +} + +static T_fixture CompilerUnitBuiltins_Fixture = { + .setup = CompilerUnitBuiltins_Setup, + .stop = NULL, + .teardown = CompilerUnitBuiltins_Teardown, + .scope = NULL, + .initial_context = NULL +}; + +/** + * @brief Check the return value of __builtin_clz() for a sample set of inputs. + */ +static void CompilerUnitBuiltins_Action_0( void ) +{ + volatile unsigned int n; + + n = 0; + RTEMS_OBFUSCATE_VARIABLE( n ); + + n = 1U; + T_eq_int( __builtin_clz( n ), 31 ); + + n = 1U << 31; + T_eq_int( __builtin_clz( n ), 0 ); + + n = ~0U; + T_eq_int( __builtin_clz( n ), 0 ); +} + +/** + * @brief Check the return value of __builtin_clzll() for a sample set of + * inputs. + */ +static void CompilerUnitBuiltins_Action_1( void ) +{ + volatile unsigned long long n; + + n = 0; + RTEMS_OBFUSCATE_VARIABLE( n ); + + n = 1ULL; + T_eq_int( __builtin_clzll( n ), 63 ); + + n = 1ULL << 31; + T_eq_int( __builtin_clzll( n ), 32 ); + + n = 1ULL << 32; + T_eq_int( __builtin_clzll( n ), 31 ); + + n = 1ULL << 63; + T_eq_int( __builtin_clzll( n ), 0 ); + + n = ~0ULL; + T_eq_int( __builtin_clzll( n ), 0 ); +} + +/** + * @brief Check the return value of __builtin_ctz() for a sample set of inputs. + */ +static void CompilerUnitBuiltins_Action_2( void ) +{ + volatile unsigned int n; + + n = 0; + RTEMS_OBFUSCATE_VARIABLE( n ); + + n = 1U; + T_eq_int( __builtin_ctz( n ), 0 ); + + n = 1U << 31; + T_eq_int( __builtin_ctz( n ), 31 ); + + n = ~0U; + T_eq_int( __builtin_ctz( n ), 0 ); +} + +/** + * @brief Check the return value of __builtin_ctzll() for a sample set of + * inputs. + */ +static void CompilerUnitBuiltins_Action_3( void ) +{ + volatile unsigned long long n; + + n = 0; + RTEMS_OBFUSCATE_VARIABLE( n ); + + n = 1ULL; + T_eq_int( __builtin_ctzll( n ), 0 ); + + n = 1ULL << 31; + T_eq_int( __builtin_ctzll( n ), 31 ); + + n = 1ULL << 32; + T_eq_int( __builtin_ctzll( n ), 32 ); + + n = 1ULL << 63; + T_eq_int( __builtin_ctzll( n ), 63 ); + + n = ~0ULL; + T_eq_int( __builtin_ctzll( n ), 0 ); +} + +/** + * @brief Check the return value of __builtin_ffs() for a sample set of inputs. + */ +static void CompilerUnitBuiltins_Action_4( void ) +{ + volatile unsigned int n; + + n = 0; + RTEMS_OBFUSCATE_VARIABLE( n ); + + n = 1U; + T_eq_int( __builtin_ffs( n ), 1 ); + + n = 1U << 31; + T_eq_int( __builtin_ffs( n ), 32 ); + + n = 0U; + T_eq_int( __builtin_ffs( n ), 0 ); +} + +/** + * @brief Check the return value of __builtin_ffsll() for a sample set of + * inputs. + */ +static void CompilerUnitBuiltins_Action_5( void ) +{ + volatile unsigned long long n; + + n = 0; + RTEMS_OBFUSCATE_VARIABLE( n ); + + n = 1ULL; + T_eq_int( __builtin_ffsll( n ), 1 ); + + n = 1ULL << 31; + T_eq_int( __builtin_ffsll( n ), 32 ); + + n = 1ULL << 32; + T_eq_int( __builtin_ffsll( n ), 33 ); + + n = 1ULL << 63; + T_eq_int( __builtin_ffsll( n ), 64 ); + + n = 0ULL; + T_eq_int( __builtin_ffsll( n ), 0 ); +} + +/** + * @brief Check the return value of __builtin_parity() for a sample set of + * inputs. + */ +static void CompilerUnitBuiltins_Action_6( void ) +{ + volatile unsigned int n; + + n = 0; + RTEMS_OBFUSCATE_VARIABLE( n ); + + n = 1U; + T_eq_int( __builtin_parity( n ), 1 ); + + n = ~0U; + T_eq_int( __builtin_parity( n ), 0 ); +} + +/** + * @brief Check the return value of __builtin_parityll() for a sample set of + * inputs. + */ +static void CompilerUnitBuiltins_Action_7( void ) +{ + volatile unsigned long long n; + + n = 0; + RTEMS_OBFUSCATE_VARIABLE( n ); + + n = 1ULL; + T_eq_int( __builtin_parityll( n ), 1 ); + + n = ~0ULL; + T_eq_int( __builtin_parityll( n ), 0 ); +} + +/** + * @brief Check the return value of __builtin_popcount() for a sample set of + * inputs. + */ +static void CompilerUnitBuiltins_Action_8( void ) +{ + volatile unsigned int n; + + n = 0; + RTEMS_OBFUSCATE_VARIABLE( n ); + + n = 0U; + T_eq_int( __builtin_popcount( n ), 0 ); + + n = 1U; + T_eq_int( __builtin_popcount( n ), 1 ); + + n = ~0U; + T_eq_int( __builtin_popcount( n ), 32 ); +} + +/** + * @brief Check the return value of __builtin_popcountll() for a sample set of + * inputs. + */ +static void CompilerUnitBuiltins_Action_9( void ) +{ + volatile unsigned long long n; + + n = 0; + RTEMS_OBFUSCATE_VARIABLE( n ); + + n = 0ULL; + T_eq_int( __builtin_popcountll( n ), 0 ); + + n = 1ULL; + T_eq_int( __builtin_popcountll( n ), 1 ); + + n = ~0ULL; + T_eq_int( __builtin_popcountll( n ), 64 ); +} + +/** + * @brief Check the return value of __builtin_bswap32() for a sample set of + * inputs. + */ +static void CompilerUnitBuiltins_Action_10( void ) +{ + volatile uint32_t n; + + n = 0; + RTEMS_OBFUSCATE_VARIABLE( n ); + + n = UINT32_C( 0 ); + T_eq_u32( __builtin_bswap32( n ), n ); + + n = UINT32_C( 1 ); + T_eq_u32( __builtin_bswap32( n ), n << 24 ); + + n = UINT32_C( 0x12345678 ); + T_eq_u32( __builtin_bswap32( n ), UINT32_C( 0x78563412 ) ); + + n = ~UINT32_C( 0 ); + T_eq_u32( __builtin_bswap32( n ), n ); +} + +/** + * @brief Check the return value of __builtin_bswap64() for a sample set of + * inputs. + */ +static void CompilerUnitBuiltins_Action_11( void ) +{ + volatile uint64_t n; + + n = 0; + RTEMS_OBFUSCATE_VARIABLE( n ); + + n = UINT64_C( 0 ); + T_eq_u64( __builtin_bswap64( n ), n ); + + n = UINT64_C( 1 ); + T_eq_u64( __builtin_bswap64( n ), n << 56 ); + + n = UINT64_C( 0x123456789abcdef0 ); + T_eq_u64( __builtin_bswap64( n ), UINT64_C( 0xf0debc9a78563412 ) ); + + n = ~UINT64_C( 0 ); + T_eq_u64( __builtin_bswap64( n ), n ); +} + +/** + * @brief Check signed 64-bit comparisons for a sample set of values. + */ +static void CompilerUnitBuiltins_Action_12( void ) +{ + volatile int64_t a; + volatile int64_t b; + + a = 0; + RTEMS_OBFUSCATE_VARIABLE( a ); + b = 0; + RTEMS_OBFUSCATE_VARIABLE( b ); + + a = INT64_C( 0 ); + b = INT64_C( 0 ); + T_false( a < b ); + + a = INT64_C( 0 ); + b = INT64_C( 1 ); + T_true( a < b ); + + a = INT64_C( 0x123456789abcdef0 ); + b = INT64_C( 0xf0debc9a78563412 ); + T_false( a < b ); + + a = INT64_C( 0xf0debc9a78563412 ); + b = INT64_C( 0x123456789abcdef0 ); + T_true( a < b ); +} + +/** + * @brief Check unsigned 64-bit comparisons for a sample set of values. + */ +static void CompilerUnitBuiltins_Action_13( void ) +{ + volatile uint64_t a; + volatile uint64_t b; + + a = 0; + RTEMS_OBFUSCATE_VARIABLE( a ); + b = 0; + RTEMS_OBFUSCATE_VARIABLE( b ); + + a = UINT64_C( 0 ); + b = UINT64_C( 0 ); + T_false( a < b ); + + a = UINT64_C( 0 ); + b = UINT64_C( 1 ); + T_true( a < b ); + + a = UINT64_C( 0x123456789abcdef0 ); + b = UINT64_C( 0xf0debc9a78563412 ); + T_true( a < b ); + + a = UINT64_C( 0xf0debc9a78563412 ); + b = UINT64_C( 0x123456789abcdef0 ); + T_false( a < b ); +} + +/** + * @brief Check signed 64-bit arithmetic left shift for a sample set of values. + */ +static void CompilerUnitBuiltins_Action_14( void ) +{ + volatile int64_t i; + volatile int s; + + i = 0; + RTEMS_OBFUSCATE_VARIABLE( i ); + s = 0; + RTEMS_OBFUSCATE_VARIABLE( s ); + + i = INT64_C( 1 ); + s = 0; + T_eq_i64( i << s, INT64_C( 1 ) ); + + i = -INT64_C( 1 ); + s = 0; + T_eq_i64( i << s, -INT64_C( 1 ) ); + + i = INT64_C( 1 ); + s = 1; + T_eq_i64( i << s, INT64_C( 2 ) ); + + i = -INT64_C( 1 ); + s = 1; + T_eq_i64( i << s, -INT64_C( 2 ) ); +} + +/** + * @brief Check signed 64-bit arithmetic right shift for a sample set of + * values. + */ +static void CompilerUnitBuiltins_Action_15( void ) +{ + volatile int64_t i; + volatile int s; + + i = 0; + RTEMS_OBFUSCATE_VARIABLE( i ); + s = 0; + RTEMS_OBFUSCATE_VARIABLE( s ); + + i = INT64_C( 1 ); + s = 0; + T_eq_i64( i >> s, INT64_C( 1 ) ); + + i = -INT64_C( 1 ); + s = 0; + T_eq_i64( i >> s, -INT64_C( 1 ) ); + + i = INT64_C( 2 ); + s = 1; + T_eq_i64( i >> s, INT64_C( 1 ) ); + + i = -INT64_C( 2 ); + s = 1; + T_eq_i64( i >> s, -INT64_C( 1 ) ); +} + +/** + * @brief Check unsigned 64-bit logical right shift for a sample set of values. + */ +static void CompilerUnitBuiltins_Action_16( void ) +{ + volatile uint64_t i; + volatile int s; + + i = 0; + RTEMS_OBFUSCATE_VARIABLE( i ); + s = 0; + RTEMS_OBFUSCATE_VARIABLE( s ); + + i = UINT64_C( 1 ); + s = 0; + T_eq_u64( i >> s, UINT64_C( 1 ) ); + + i = -UINT64_C( 1 ); + s = 0; + T_eq_u64( i >> s, UINT64_C( 0xffffffffffffffff ) ); + + i = UINT64_C( 2 ); + s = 1; + T_eq_u64( i >> s, UINT64_C( 1 ) ); + + i = -UINT64_C( 2 ); + s = 1; + T_eq_u64( i >> s, UINT64_C( 0x7fffffffffffffff ) ); +} + +/** + * @brief Check signed 64-bit multiplication for a sample set of values. + */ +static void CompilerUnitBuiltins_Action_17( void ) +{ + volatile int64_t a; + volatile int64_t b; + + a = 0; + RTEMS_OBFUSCATE_VARIABLE( a ); + b = 0; + RTEMS_OBFUSCATE_VARIABLE( b ); + + a = INT64_C( 1 ); + b = INT64_C( 1 ); + T_eq_i64( a * b, INT64_C( 1 ) ); + + a = INT64_C( 1 ); + b = INT64_C( 0 ); + T_eq_i64( a * b, INT64_C( 0 ) ); + + a = INT64_C( 0 ); + b = INT64_C( 1 ); + T_eq_i64( a * b, INT64_C( 0 ) ); +} + +/** + * @brief Check signed 64-bit negation for a sample set of values. + */ +static void CompilerUnitBuiltins_Action_18( void ) +{ + volatile int64_t i; + + i = 0; + RTEMS_OBFUSCATE_VARIABLE( i ); + + i = INT64_C( 1 ); + T_eq_i64( -i, -INT64_C( 1 ) ); + + i = -INT64_C( 1 ); + T_eq_i64( -i, INT64_C( 1 ) ); +} + +/** + * @brief Check signed 64-bit divisions for a sample set of values. + */ +static void CompilerUnitBuiltins_Action_19( void ) +{ + volatile int64_t n; + volatile int64_t d; + volatile int64_t x; + + n = 0; + RTEMS_OBFUSCATE_VARIABLE( n ); + d = 0; + RTEMS_OBFUSCATE_VARIABLE( d ); + x = 0; + RTEMS_OBFUSCATE_VARIABLE( x ); + + n = INT64_C( 0 ); + d = INT64_C( 0 ); + do_longjmp = true; + + if ( setjmp( exception_return_context ) == 0 ) { + x = n / d; + } + + n = INT64_C( 1 ); + d = INT64_C( 0 ); + do_longjmp = true; + + if ( setjmp( exception_return_context ) == 0 ) { + x = n / d; + } + + n = INT64_C( 0x7fffffffffffffff ); + d = INT64_C( 0 ); + do_longjmp = true; + + if ( setjmp( exception_return_context ) == 0 ) { + x = n / d; + } + + n = INT64_C( 0x7fffffff00000000 ); + d = INT64_C( 0 ); + do_longjmp = true; + + if ( setjmp( exception_return_context ) == 0 ) { + x = n / d; + } + + n = INT64_C( 0 ); + d = INT64_C( 1 ); + T_eq_i64( n / d, INT64_C( 0 ) ); + + n = INT64_C( 1 ); + d = INT64_C( 1 ); + T_eq_i64( n / d, INT64_C( 1 ) ); + + n = INT64_C( 0x7fffffffffffffff ); + d = INT64_C( 1 ); + T_eq_i64( n / d, INT64_C( 9223372036854775807 ) ); + + n = INT64_C( 2 ); + d = INT64_C( 1 ); + T_eq_i64( n / d, INT64_C( 2 ) ); + + n = INT64_C( 2 ); + d = INT64_C( 1 ); + T_eq_i64( n / d, INT64_C( 2 ) ); + + n = INT64_C( 1 ); + d = INT64_C( 0x7fffffffffffffff ); + T_eq_i64( n / d, INT64_C( 0 ) ); + + n = INT64_C( 0x7fffffffffffffff ); + d = INT64_C( 0x7fffffffffffffff ); + T_eq_i64( n / d, INT64_C( 1 ) ); + + n = INT64_C( 1 ); + d = INT64_C( 0x7fffffff00000000 ); + T_eq_i64( n / d, INT64_C( 0 ) ); + + n = INT64_C( 0x7fffffff00000000 ); + d = INT64_C( 0x7fffffff00000000 ); + T_eq_i64( n / d, INT64_C( 1 ) ); + + n = INT64_C( 0x7fffffffffffffff ); + d = INT64_C( 0x7fffffff00000000 ); + T_eq_i64( n / d, INT64_C( 1 ) ); + + n = INT64_C( 0x7fffffffffffffff ); + d = INT64_C( 0x8000000000000000 ); + T_eq_i64( n / d, INT64_C( 0 ) ); + + n = INT64_C( 0x7fffffffffffffff ); + d = INT64_C( 0x0000000080000000 ); + T_eq_i64( n / d, INT64_C( 0xffffffff ) ); + + n = INT64_C( 0x7fffffffffffffff ); + d = INT64_C( 0x00000000f0000000 ); + T_eq_i64( n / d, INT64_C( 2290649224 ) ); + + n = INT64_C( 0x00000001ffffffff ); + d = INT64_C( 0x00000000f0000000 ); + T_eq_i64( n / d, INT64_C( 2 ) ); + + n = INT64_C( 0x0000000fffffffff ); + d = INT64_C( 0x000000000000000f ); + T_eq_i64( n / d, INT64_C( 4581298449 ) ); + + n = INT64_C( 0x0000000100000001 ); + d = INT64_C( 0x0000000f00000000 ); + T_eq_i64( n / d, INT64_C( 0 ) ); + + n = INT64_C( 0x0000000f0000000f ); + d = INT64_C( 0x000000ff0000000f ); + T_eq_i64( n / d, INT64_C( 0 ) ); +} + +/** + * @brief Check unsigned 64-bit divisions for a sample set of values. + */ +static void CompilerUnitBuiltins_Action_20( void ) +{ + volatile uint64_t n; + volatile uint64_t d; + volatile uint64_t x; + + n = 0; + RTEMS_OBFUSCATE_VARIABLE( n ); + d = 0; + RTEMS_OBFUSCATE_VARIABLE( d ); + x = 0; + RTEMS_OBFUSCATE_VARIABLE( x ); + + n = UINT64_C( 0 ); + d = UINT64_C( 0 ); + do_longjmp = true; + + if ( setjmp( exception_return_context ) == 0 ) { + x = n / d; + } + + #if defined(TEST_UDIVMODDI4_WITHOUT_REMINDER) + do_longjmp = true; + + if ( setjmp( exception_return_context ) == 0 ) { + __udivmoddi4( n, d, NULL ); + } + #endif + + n = UINT64_C( 1 ); + d = UINT64_C( 0 ); + do_longjmp = true; + + if ( setjmp( exception_return_context ) == 0 ) { + x = n / d; + } + + #if defined(TEST_UDIVMODDI4_WITHOUT_REMINDER) + do_longjmp = true; + + if ( setjmp( exception_return_context ) == 0 ) { + __udivmoddi4( n, d, NULL ); + } + #endif + + n = UINT64_C( 0x7fffffffffffffff ); + d = UINT64_C( 0 ); + do_longjmp = true; + + if ( setjmp( exception_return_context ) == 0 ) { + x = n / d; + } + + #if defined(TEST_UDIVMODDI4_WITHOUT_REMINDER) + do_longjmp = true; + + if ( setjmp( exception_return_context ) == 0 ) { + __udivmoddi4( n, d, NULL ); + } + #endif + + n = UINT64_C( 0x7fffffff00000000 ); + d = UINT64_C( 0 ); + do_longjmp = true; + + if ( setjmp( exception_return_context ) == 0 ) { + x = n / d; + } + + #if defined(TEST_UDIVMODDI4_WITHOUT_REMINDER) + do_longjmp = true; + + if ( setjmp( exception_return_context ) == 0 ) { + __udivmoddi4( n, d, NULL ); + } + #endif + + n = UINT64_C( 0x7fffffff00000000 ); + d = UINT64_C( 0x7fffffff00000000 ); + do_longjmp = true; + + if ( setjmp( exception_return_context ) == 0 ) { + x = n / d; + } + + #if defined(TEST_UDIVMODDI4_WITHOUT_REMINDER) + do_longjmp = true; + + if ( setjmp( exception_return_context ) == 0 ) { + __udivmoddi4( n, d, NULL ); + } + #endif + + n = UINT64_C( 0 ); + d = UINT64_C( 1 ); + T_eq_u64( n / d, UINT64_C( 0 ) ); + #if defined(TEST_UDIVMODDI4_WITHOUT_REMINDER) + T_eq_u64( __udivmoddi4( n, d, NULL ), UINT64_C( 0 ) ); + #endif + + n = UINT64_C( 1 ); + d = UINT64_C( 1 ); + T_eq_u64( n / d, UINT64_C( 1 ) ); + #if defined(TEST_UDIVMODDI4_WITHOUT_REMINDER) + T_eq_u64( __udivmoddi4( n, d, NULL ), UINT64_C( 1 ) ); + #endif + + n = UINT64_C( 0xffffffffffffffff ); + d = UINT64_C( 1 ); + T_eq_u64( n / d, UINT64_C( 0xffffffffffffffff ) ); + #if defined(TEST_UDIVMODDI4_WITHOUT_REMINDER) + T_eq_u64( __udivmoddi4( n, d, NULL ), UINT64_C( 0xffffffffffffffff ) ); + #endif + + n = UINT64_C( 2 ); + d = UINT64_C( 1 ); + T_eq_u64( n / d, UINT64_C( 2 ) ); + #if defined(TEST_UDIVMODDI4_WITHOUT_REMINDER) + T_eq_u64( __udivmoddi4( n, d, NULL ), UINT64_C( 2 ) ); + #endif + + n = UINT64_C( 1 ); + d = UINT64_C( 0xffffffffffffffff ); + T_eq_u64( n / d, UINT64_C( 0 ) ); + #if defined(TEST_UDIVMODDI4_WITHOUT_REMINDER) + T_eq_u64( __udivmoddi4( n, d, NULL ), UINT64_C( 0 ) ); + #endif + + n = UINT64_C( 0xffffffffffffffff ); + d = UINT64_C( 0xffffffffffffffff ); + T_eq_u64( n / d, UINT64_C( 1 ) ); + #if defined(TEST_UDIVMODDI4_WITHOUT_REMINDER) + T_eq_u64( __udivmoddi4( n, d, NULL ), UINT64_C( 1 ) ); + #endif + + n = UINT64_C( 0xffffffffffffffff ); + d = UINT64_C( 0x8000000000000000 ); + T_eq_u64( n / d, UINT64_C( 1 ) ); + #if defined(TEST_UDIVMODDI4_WITHOUT_REMINDER) + T_eq_u64( __udivmoddi4( n, d, NULL ), UINT64_C( 1 ) ); + #endif + + n = UINT64_C( 0x0000000100000001 ); + d = UINT64_C( 0x0000000f00000000 ); + T_eq_u64( n / d, UINT64_C( 0 ) ); + #if defined(TEST_UDIVMODDI4_WITHOUT_REMINDER) + T_eq_u64( __udivmoddi4( n, d, NULL ), UINT64_C( 0 ) ); + #endif + + n = UINT64_C( 0x0000000100000000 ); + d = UINT64_C( 0x0000000f00000001 ); + T_eq_u64( n / d, UINT64_C( 0 ) ); + #if defined(TEST_UDIVMODDI4_WITHOUT_REMINDER) + T_eq_u64( __udivmoddi4( n, d, NULL ), UINT64_C( 0 ) ); + #endif + + n = UINT64_C( 0xffffffff0000000f ); + d = UINT64_C( 0x000000010000000f ); + T_eq_u64( n / d, UINT64_C( 4294967280 ) ); + #if defined(TEST_UDIVMODDI4_WITHOUT_REMINDER) + T_eq_u64( __udivmoddi4( n, d, NULL ), UINT64_C( 4294967280 ) ); + #endif +} + +/** + * @brief Check signed 64-bit modulo operations for a sample set of values. + */ +static void CompilerUnitBuiltins_Action_21( void ) +{ + volatile int64_t n; + volatile int64_t d; + volatile int64_t x; + + n = 0; + RTEMS_OBFUSCATE_VARIABLE( n ); + d = 0; + RTEMS_OBFUSCATE_VARIABLE( d ); + x = 0; + RTEMS_OBFUSCATE_VARIABLE( x ); + + n = INT64_C( 0 ); + d = INT64_C( 0 ); + do_longjmp = true; + + if ( setjmp( exception_return_context ) == 0 ) { + x = n % d; + } + + n = INT64_C( 1 ); + d = INT64_C( 0 ); + do_longjmp = true; + + if ( setjmp( exception_return_context ) == 0 ) { + x = n % d; + } + + n = INT64_C( 0x7fffffffffffffff ); + d = INT64_C( 0 ); + do_longjmp = true; + + if ( setjmp( exception_return_context ) == 0 ) { + x = n % d; + } + + n = INT64_C( 0x7fffffff00000000 ); + d = INT64_C( 0 ); + do_longjmp = true; + + if ( setjmp( exception_return_context ) == 0 ) { + x = n % d; + } + + n = INT64_C( 0 ); + d = INT64_C( 1 ); + T_eq_i64( n % d, INT64_C( 0 ) ); + + n = INT64_C( 1 ); + d = INT64_C( 1 ); + T_eq_i64( n % d, INT64_C( 0 ) ); + + n = INT64_C( 0x7fffffffffffffff ); + d = INT64_C( 1 ); + T_eq_i64( n % d, INT64_C( 0 ) ); + + n = INT64_C( 2 ); + d = INT64_C( 1 ); + T_eq_i64( n % d, INT64_C( 0 ) ); + + n = INT64_C( 2 ); + d = INT64_C( 1 ); + T_eq_i64( n % d, INT64_C( 0 ) ); + + n = INT64_C( 1 ); + d = INT64_C( 0x7fffffffffffffff ); + T_eq_i64( n % d, INT64_C( 1 ) ); + + n = INT64_C( 0x7fffffffffffffff ); + d = INT64_C( 0x7fffffffffffffff ); + T_eq_i64( n % d, INT64_C( 0 ) ); + + n = INT64_C( 1 ); + d = INT64_C( 0x7fffffff00000000 ); + T_eq_i64( n % d, INT64_C( 1 ) ); + + n = INT64_C( 0x7fffffff00000000 ); + d = INT64_C( 0x7fffffff00000000 ); + T_eq_i64( n % d, INT64_C( 0 ) ); + + n = INT64_C( 0x7fffffffffffffff ); + d = INT64_C( 0x7fffffff00000000 ); + T_eq_i64( n % d, INT64_C( 0xffffffff ) ); + + n = INT64_C( 0x7fffffffffffffff ); + d = INT64_C( 0x8000000000000000 ); + T_eq_i64( n % d, INT64_C( 0x7fffffffffffffff ) ); + + n = INT64_C( 0x7fffffffffffffff ); + d = INT64_C( 0x0000000080000000 ); + T_eq_i64( n % d, INT64_C( 2147483647 ) ); + + n = INT64_C( 0x7fffffffffffffff ); + d = INT64_C( 0x00000000f0000000 ); + T_eq_i64( n % d, INT64_C( 2147483647 ) ); + + n = INT64_C( 0x00000001ffffffff ); + d = INT64_C( 0x00000000f0000000 ); + T_eq_i64( n % d, INT64_C( 536870911 ) ); + + n = INT64_C( 0x0000000fffffffff ); + d = INT64_C( 0x000000000000000f ); + T_eq_i64( n % d, INT64_C( 0 ) ); + + n = INT64_C( 0x0000000100000001 ); + d = INT64_C( 0x0000000f00000000 ); + T_eq_i64( n % d, INT64_C( 4294967297 ) ); + + n = INT64_C( 0x0000000f0000000f ); + d = INT64_C( 0x000000ff0000000f ); + T_eq_i64( n % d, INT64_C( 64424509455 ) ); + + #if defined(TEST_UDIVMODDI4) + /* + * The above test cases may use __udivmoddi4(). However, the below + * parameter values for __udivmoddi4() cannot be obtained through the + * signed modulo or division operations. On some targets, calls to + * __udivmoddi4() may result from complex optimizations. + */ + n = INT64_C( 0xffffffff0000000f ); + d = INT64_C( 0x000000010000000f ); + T_eq_u64( __udivmoddi4( n, d, NULL ), INT64_C( 4294967280 ) ); + #endif +} + +/** + * @brief Check unsigned 64-bit modulo operations for a sample set of values. + */ +static void CompilerUnitBuiltins_Action_22( void ) +{ + volatile uint64_t n; + volatile uint64_t d; + volatile uint64_t x; + + n = 0; + RTEMS_OBFUSCATE_VARIABLE( n ); + d = 0; + RTEMS_OBFUSCATE_VARIABLE( d ); + x = 0; + RTEMS_OBFUSCATE_VARIABLE( x ); + + n = UINT64_C( 0 ); + d = UINT64_C( 0 ); + do_longjmp = true; + + if ( setjmp( exception_return_context ) == 0 ) { + x = n % d; + } + + n = UINT64_C( 1 ); + d = UINT64_C( 0 ); + do_longjmp = true; + + if ( setjmp( exception_return_context ) == 0 ) { + x = n % d; + } + + n = UINT64_C( 0 ); + d = UINT64_C( 1 ); + T_eq_u64( n % d, UINT64_C( 0 ) ); + + n = UINT64_C( 1 ); + d = UINT64_C( 1 ); + T_eq_u64( n % d, UINT64_C( 0 ) ); + + n = UINT64_C( 0xffffffffffffffff ); + d = UINT64_C( 1 ); + T_eq_u64( n % d, UINT64_C( 0 ) ); + + n = UINT64_C( 2 ); + d = UINT64_C( 1 ); + T_eq_u64( n % d, UINT64_C( 0 ) ); + + n = UINT64_C( 1 ); + d = UINT64_C( 0xffffffffffffffff ); + T_eq_u64( n % d, UINT64_C( 1 ) ); + + n = UINT64_C( 0xffffffffffffffff ); + d = UINT64_C( 0xffffffffffffffff ); + T_eq_u64( n % d, UINT64_C( 0 ) ); +} + +/** + * @fn void T_case_body_CompilerUnitBuiltins( void ) + */ +T_TEST_CASE_FIXTURE( CompilerUnitBuiltins, &CompilerUnitBuiltins_Fixture ) +{ + CompilerUnitBuiltins_Action_0(); + CompilerUnitBuiltins_Action_1(); + CompilerUnitBuiltins_Action_2(); + CompilerUnitBuiltins_Action_3(); + CompilerUnitBuiltins_Action_4(); + CompilerUnitBuiltins_Action_5(); + CompilerUnitBuiltins_Action_6(); + CompilerUnitBuiltins_Action_7(); + CompilerUnitBuiltins_Action_8(); + CompilerUnitBuiltins_Action_9(); + CompilerUnitBuiltins_Action_10(); + CompilerUnitBuiltins_Action_11(); + CompilerUnitBuiltins_Action_12(); + CompilerUnitBuiltins_Action_13(); + CompilerUnitBuiltins_Action_14(); + CompilerUnitBuiltins_Action_15(); + CompilerUnitBuiltins_Action_16(); + CompilerUnitBuiltins_Action_17(); + CompilerUnitBuiltins_Action_18(); + CompilerUnitBuiltins_Action_19(); + CompilerUnitBuiltins_Action_20(); + CompilerUnitBuiltins_Action_21(); + CompilerUnitBuiltins_Action_22(); +} + +/** @} */ diff --git a/testsuites/unit/tc-config.c b/testsuites/unit/tc-config.c new file mode 100644 index 0000000000..415142e1b4 --- /dev/null +++ b/testsuites/unit/tc-config.c @@ -0,0 +1,171 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ + +/** + * @file + * + * @ingroup RtemsConfigUnitConfig + */ + +/* + * Copyright (C) 2021 embedded brains GmbH & Co. KG + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * This file is part of the RTEMS quality process and was automatically + * generated. If you find something that needs to be fixed or + * worded better please post a report or patch to an RTEMS mailing list + * or raise a bug report: + * + * https://www.rtems.org/bugs.html + * + * For information on updating and regenerating please refer to the How-To + * section in the Software Requirements Engineering chapter of the + * RTEMS Software Engineering manual. The manual is provided as a part of + * a release. For development sources please refer to the online + * documentation at: + * + * https://docs.rtems.org + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems.h> +#include <rtems/rtems/semdata.h> +#include <rtems/score/object.h> +#include <rtems/score/objectdata.h> + +#include <rtems/test.h> + +/** + * @defgroup RtemsConfigUnitConfig spec:/rtems/config/unit/config + * + * @ingroup TestsuitesUnitNoClock0 + * + * @brief Unit tests for the configuration manager. + * + * Parts of the file ``cpukit/sapi/src/getconfigmax.c`` are only executed when + * unlimited objects are configured. The space qualified code subset does not + * support this feature. This test exercises the code parts otherwise not + * reached in order to achieve full code coverage. + * + * This test case performs the following actions: + * + * - Call get_config_max() indirectly through + * rtems_configuration_get_maximum_semaphores() with a specially manipulated + * argument to enter an if-branch only accessed when unlimited objects are + * configured. + * + * - The value returned by the function call must be the one artificially + * injected by this test. + * + * @{ + */ + +#define SEMAPHORES_PER_BLOCK 32 + +/** + * @brief Test context for spec:/rtems/config/unit/config test case. + */ +typedef struct { + /** + * @brief This member contains the original value of + * ``_Semaphore_Information->objects_per_block``. + */ + Objects_Maximum objects_per_block_ori; +} RtemsConfigUnitConfig_Context; + +static RtemsConfigUnitConfig_Context + RtemsConfigUnitConfig_Instance; + +static void RtemsConfigUnitConfig_Setup( RtemsConfigUnitConfig_Context *ctx ) +{ + ctx->objects_per_block_ori = _Semaphore_Information.objects_per_block; + _Semaphore_Information.objects_per_block = SEMAPHORES_PER_BLOCK; +} + +static void RtemsConfigUnitConfig_Setup_Wrap( void *arg ) +{ + RtemsConfigUnitConfig_Context *ctx; + + ctx = arg; + RtemsConfigUnitConfig_Setup( ctx ); +} + +static void RtemsConfigUnitConfig_Teardown( + RtemsConfigUnitConfig_Context *ctx +) +{ + _Semaphore_Information.objects_per_block = ctx->objects_per_block_ori; +} + +static void RtemsConfigUnitConfig_Teardown_Wrap( void *arg ) +{ + RtemsConfigUnitConfig_Context *ctx; + + ctx = arg; + RtemsConfigUnitConfig_Teardown( ctx ); +} + +static T_fixture RtemsConfigUnitConfig_Fixture = { + .setup = RtemsConfigUnitConfig_Setup_Wrap, + .stop = NULL, + .teardown = RtemsConfigUnitConfig_Teardown_Wrap, + .scope = NULL, + .initial_context = &RtemsConfigUnitConfig_Instance +}; + +/** + * @brief Call get_config_max() indirectly through + * rtems_configuration_get_maximum_semaphores() with a specially manipulated + * argument to enter an if-branch only accessed when unlimited objects are + * configured. + */ +static void RtemsConfigUnitConfig_Action_0( + RtemsConfigUnitConfig_Context *ctx +) +{ + uint32_t max = rtems_configuration_get_maximum_semaphores(); + + /* + * The value returned by the function call must be the one artificially + * injected by this test. + */ + T_eq_u32( max, SEMAPHORES_PER_BLOCK | RTEMS_UNLIMITED_OBJECTS ); +} + +/** + * @fn void T_case_body_RtemsConfigUnitConfig( void ) + */ +T_TEST_CASE_FIXTURE( RtemsConfigUnitConfig, &RtemsConfigUnitConfig_Fixture ) +{ + RtemsConfigUnitConfig_Context *ctx; + + ctx = T_fixture_context(); + + RtemsConfigUnitConfig_Action_0( ctx ); +} + +/** @} */ diff --git a/testsuites/unit/tc-crc.c b/testsuites/unit/tc-crc.c new file mode 100644 index 0000000000..d33a837860 --- /dev/null +++ b/testsuites/unit/tc-crc.c @@ -0,0 +1,48 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ + +/** + * @file + * + * @ingroup TestsuitesUnitNoClock0 + */ + +/* + * Copyright (C) 2023 embedded brains GmbH & Co. KG + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <rtems/crc.h> + +#include <rtems/test.h> + +T_TEST_CASE(CRC24Q) { + uint32_t state = _CRC24Q_Update(CRC24Q_SEED, 0); + T_eq_u32(state, 0); + state = _CRC24Q_Update(CRC24Q_SEED, '1'); + state = _CRC24Q_Update(state, '2'); + state = _CRC24Q_Update(state, '3'); + T_eq_u32(state & CRC24Q_MASK, 0x2c3045); + uint8_t bytes[] = {'1', '2', '3'}; + state = _CRC24Q_Sequence_update(CRC24Q_SEED, &bytes[0], sizeof(bytes)); + T_eq_u32(state & CRC24Q_MASK, 0x2c3045); +} diff --git a/testsuites/unit/tc-misaligned-builtin-memcpy.c b/testsuites/unit/tc-misaligned-builtin-memcpy.c index 2021a68551..6ce19e0521 100644 --- a/testsuites/unit/tc-misaligned-builtin-memcpy.c +++ b/testsuites/unit/tc-misaligned-builtin-memcpy.c @@ -1,7 +1,13 @@ /* SPDX-License-Identifier: BSD-2-Clause */ +/** + * @file + * + * @ingroup TestsuitesUnitNoClock0 + */ + /* - * Copyright (C) 2019 embedded brains GmbH (http://www.embedded-brains.de) + * Copyright (C) 2019 embedded brains GmbH & Co. KG * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions diff --git a/testsuites/unit/tc-score-msgq.c b/testsuites/unit/tc-score-msgq.c new file mode 100644 index 0000000000..c4cb690c2f --- /dev/null +++ b/testsuites/unit/tc-score-msgq.c @@ -0,0 +1,452 @@ +/* SPDX-License-Identifier: BSD-2-Clause */ + +/** + * @file + * + * @ingroup ScoreMsgqUnitMsgq + */ + +/* + * Copyright (C) 2021 embedded brains GmbH & Co. KG + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * This file is part of the RTEMS quality process and was automatically + * generated. If you find something that needs to be fixed or + * worded better please post a report or patch to an RTEMS mailing list + * or raise a bug report: + * + * https://www.rtems.org/bugs.html + * + * For information on updating and regenerating please refer to the How-To + * section in the Software Requirements Engineering chapter of the + * RTEMS Software Engineering manual. The manual is provided as a part of + * a release. For development sources please refer to the online + * documentation at: + * + * https://docs.rtems.org + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <rtems.h> +#include <rtems/rtems/messageimpl.h> +#include <rtems/rtems/statusimpl.h> +#include <rtems/score/coremsgimpl.h> + +#include "../validation/tx-support.h" + +#include <rtems/test.h> + +/** + * @defgroup ScoreMsgqUnitMsgq spec:/score/msgq/unit/msgq + * + * @ingroup TestsuitesUnitNoClock0 + * + * @brief Unit tests for the Message Queue Handler. + * + * Parts of the files ``cpukit/score/src/coremsginsert.c``, + * ``cpukit/score/src/coremsgseize.c``, and + * ``cpukit/score/src/coremsgsubmit.c`` are only executed by the POSIX API. + * Currently, the pre-qualified subset of RTEMS does not contain the POSIX API. + * This test exercises the code parts otherwise only reached by the POSIX API + * to achieve full code coverage. + * + * This test case performs the following actions: + * + * - Use _CORE_message_queue_Insert_message() to insert two messages into a + * message queue and use the POSIX message priority to define their order in + * the queue. + * + * - Check that _CORE_message_queue_Submit() was executed successfully. + * + * - Check that the messages are in the right order in the message queue. + * + * - Submit three messages into a message queue which can only store two and + * have the third submit() blocked till a seize() occurs. + * + * - Check that the third _CORE_message_queue_Submit() did actually block + * till there was room for the message in the message queue. + * + * - Submit messages in the queue from within an ISR. + * + * - Check that the first two messages were successfully send. + * + * - Check that trying to send the third message from ISR when the message + * queue was full was rejected. + * + * @{ + */ + +#define MAXIMUM_PENDING_MESSAGES 2 +#define MAXIMUM_MESSAGE_SIZE 3 + +static void WorkerTask( rtems_task_argument argument ); + +/** + * @brief Test context for spec:/score/msgq/unit/msgq test case. + */ +typedef struct { + /** + * @brief This member contains a valid ID of a message queue. + */ + rtems_id message_queue_id; + + /** + * @brief This member is used as storage area for the message queue. + */ + RTEMS_MESSAGE_QUEUE_BUFFER( MAXIMUM_MESSAGE_SIZE ) + storage_area[ MAXIMUM_PENDING_MESSAGES]; + + /** + * @brief This member contains the task identifier of the worker task. + */ + rtems_id worker_id; + + /** + * @brief This member indicated whether the worker task is currently sending + * a message (``true``) or whether it is waiting to receive an event + * (``false``). + */ + bool is_worker_working; + + /** + * @brief This member contains the returned status code of the SendMessage() + * function. + */ + rtems_status_code send_status; +} ScoreMsgqUnitMsgq_Context; + +static ScoreMsgqUnitMsgq_Context + ScoreMsgqUnitMsgq_Instance; + +#define EVENT_SEND RTEMS_EVENT_17 +#define MESSAGE_CONTENT_LOW { 1, 2, 3 } +#define MESSAGE_CONTENT_HIGH { 4, 5 } +#define MESSAGE_PRIORITY_LOW 5 +#define MESSAGE_PRIORITY_HIGH 7 +#define DO_WAIT true + +typedef ScoreMsgqUnitMsgq_Context Context; + +/* + * This is a code fragment from rtems_message_queue_send() with the + * specialty that it uses a POSIX priority and the sender + * task will wait in case the queue is full. + */ +static rtems_status_code SubmitMessage( + rtems_id id, + uint8_t *message, + size_t message_size, + unsigned int posix_piority +) +{ + rtems_status_code status; + Thread_queue_Context queue_context; + Message_queue_Control *the_message_queue; + + T_assert_lt_uint( posix_piority, MQ_PRIO_MAX ); + + the_message_queue = _Message_queue_Get( + id, + &queue_context + ); + T_assert_not_null( the_message_queue ); + + /* The next two calls are from _POSIX_Message_queue_Send_support() */ + _Thread_queue_Context_set_enqueue_callout( + &queue_context, + _Thread_queue_Enqueue_do_nothing_extra + ); + _Thread_queue_Context_set_timeout_argument( &queue_context, NULL, true ); + + _CORE_message_queue_Acquire_critical( + &the_message_queue->message_queue, + &queue_context + ); + + status = _CORE_message_queue_Submit( + &the_message_queue->message_queue, + _Thread_Executing, + message, + message_size, + (CORE_message_queue_Submit_types) ( posix_piority * -1 ), + DO_WAIT, + &queue_context + ); + + return _Status_Get( status ); +} + +static rtems_status_code ReceiveMessage( + rtems_id id, + void *buffer, + size_t *size +) +{ + return rtems_message_queue_receive( + id, + buffer, + size, + RTEMS_LOCAL | RTEMS_NO_WAIT, + RTEMS_NO_TIMEOUT + ); +} + +static rtems_status_code ReceiveOneMessages( Context *ctx ) +{ + uint8_t message_buffer[ MAXIMUM_MESSAGE_SIZE ]; + size_t message_size; + + return ReceiveMessage( + ctx->message_queue_id, + &message_buffer, + &message_size + ); +} + +static void SendMessage( Context *ctx ) +{ + uint8_t message[] = { 100, 101, 102 }; + ctx->send_status = SubmitMessage( + ctx->message_queue_id, + message, + sizeof( message ), + MESSAGE_PRIORITY_LOW + ); +} + +static void WorkerTask( rtems_task_argument argument ) +{ + Context *ctx = (Context *) argument; + + while ( true ) { + ctx->is_worker_working = false; + ReceiveAnyEvents(); + ctx->is_worker_working = true; + SendMessage( ctx ); + T_assert_rsc_success( ctx->send_status ); + } +} + +static void WorkerSendMessage( Context *ctx ) +{ + SendEvents( ctx->worker_id, EVENT_SEND ); +} + +static void ScoreMsgqUnitMsgq_Setup( ScoreMsgqUnitMsgq_Context *ctx ) +{ + rtems_status_code status; + rtems_message_queue_config config = { + .name = rtems_build_name( 'M', 'S', 'G', 'Q' ), + .maximum_pending_messages = MAXIMUM_PENDING_MESSAGES, + .maximum_message_size = MAXIMUM_MESSAGE_SIZE, + .storage_area = ctx->storage_area, + .storage_size = sizeof( ctx->storage_area ), + .storage_free = NULL, + .attributes = RTEMS_DEFAULT_ATTRIBUTES + }; + + status = rtems_message_queue_construct( + &config, + &ctx->message_queue_id + ); + T_rsc_success( status ); + + SetSelfPriority( PRIO_NORMAL ); + + ctx->worker_id = CreateTask( "WORK", PRIO_HIGH ); + StartTask( ctx->worker_id, WorkerTask, ctx ); +} + +static void ScoreMsgqUnitMsgq_Setup_Wrap( void *arg ) +{ + ScoreMsgqUnitMsgq_Context *ctx; + + ctx = arg; + ScoreMsgqUnitMsgq_Setup( ctx ); +} + +static void ScoreMsgqUnitMsgq_Teardown( ScoreMsgqUnitMsgq_Context *ctx ) +{ + DeleteTask( ctx->worker_id ); + RestoreRunnerPriority(); + T_rsc_success( rtems_message_queue_delete( ctx->message_queue_id ) ); +} + +static void ScoreMsgqUnitMsgq_Teardown_Wrap( void *arg ) +{ + ScoreMsgqUnitMsgq_Context *ctx; + + ctx = arg; + ScoreMsgqUnitMsgq_Teardown( ctx ); +} + +static T_fixture ScoreMsgqUnitMsgq_Fixture = { + .setup = ScoreMsgqUnitMsgq_Setup_Wrap, + .stop = NULL, + .teardown = ScoreMsgqUnitMsgq_Teardown_Wrap, + .scope = NULL, + .initial_context = &ScoreMsgqUnitMsgq_Instance +}; + +/** + * @brief Use _CORE_message_queue_Insert_message() to insert two messages into + * a message queue and use the POSIX message priority to define their order + * in the queue. + */ +static void ScoreMsgqUnitMsgq_Action_0( ScoreMsgqUnitMsgq_Context *ctx ) +{ + rtems_status_code status_submit_low; + rtems_status_code status_submit_high; + rtems_status_code status_receive_low; + rtems_status_code status_receive_high; + uint8_t message_low[] = MESSAGE_CONTENT_LOW; + uint8_t message_high[] = MESSAGE_CONTENT_HIGH; + uint8_t message_buffer_low[ MAXIMUM_MESSAGE_SIZE ]; + uint8_t message_buffer_high[ MAXIMUM_MESSAGE_SIZE ]; + size_t message_size_low; + size_t message_size_high; + + status_submit_low = SubmitMessage( + ctx->message_queue_id, + message_low, + sizeof( message_low ), + MESSAGE_PRIORITY_LOW + ); + + status_submit_high = SubmitMessage( + ctx->message_queue_id, + message_high, + sizeof( message_high ), + MESSAGE_PRIORITY_HIGH + ); + + status_receive_high = ReceiveMessage( + ctx->message_queue_id, + &message_buffer_high, + &message_size_high + ); + + status_receive_low = ReceiveMessage( + ctx->message_queue_id, + &message_buffer_low, + &message_size_low + ); + + /* + * Check that _CORE_message_queue_Submit() was executed successfully. + */ + T_rsc_success( status_submit_low ); + T_rsc_success( status_submit_high ); + + /* + * Check that the messages are in the right order in the message queue. + */ + T_rsc_success( status_receive_high ); + T_eq_sz( message_size_high, sizeof( message_high ) ); + T_eq_mem( message_buffer_high, message_high, message_size_high ); + + T_rsc_success( status_receive_low ); + T_eq_sz( message_size_low, sizeof( message_low ) ); + T_eq_mem( message_buffer_low, message_low, message_size_low ); +} + +/** + * @brief Submit three messages into a message queue which can only store two + * and have the third submit() blocked till a seize() occurs. + */ +static void ScoreMsgqUnitMsgq_Action_1( ScoreMsgqUnitMsgq_Context *ctx ) +{ + bool is_worker_blocked_after_third_send; + bool is_worker_blocked_after_first_receive; + + WorkerSendMessage( ctx ); + WorkerSendMessage( ctx ); + WorkerSendMessage( ctx ); + is_worker_blocked_after_third_send = ctx->is_worker_working; + + T_rsc_success( ReceiveOneMessages( ctx ) ); + is_worker_blocked_after_first_receive = ctx->is_worker_working; + + T_rsc_success( ReceiveOneMessages( ctx ) ); + T_rsc_success( ReceiveOneMessages( ctx ) ); + + /* + * Check that the third _CORE_message_queue_Submit() did actually block till + * there was room for the message in the message queue. + */ + T_true( is_worker_blocked_after_third_send ); + T_true( !is_worker_blocked_after_first_receive ); +} + +/** + * @brief Submit messages in the queue from within an ISR. + */ +static void ScoreMsgqUnitMsgq_Action_2( ScoreMsgqUnitMsgq_Context *ctx ) +{ + rtems_status_code status_send_first_message; + rtems_status_code status_send_second_message; + rtems_status_code status_send_third_message; + + CallWithinISR( ( void (*)(void*) ) SendMessage, ctx ); + status_send_first_message = ctx->send_status; + CallWithinISR( ( void (*)(void*) ) SendMessage, ctx ); + status_send_second_message = ctx->send_status; + CallWithinISR( ( void (*)(void*) ) SendMessage, ctx ); + status_send_third_message = ctx->send_status; + + T_rsc_success( ReceiveOneMessages( ctx ) ); + T_rsc_success( ReceiveOneMessages( ctx ) ); + + /* + * Check that the first two messages were successfully send. + */ + T_assert_rsc_success( status_send_first_message ); + T_assert_rsc_success( status_send_second_message ); + + /* + * Check that trying to send the third message from ISR when the message + * queue was full was rejected. + */ + T_rsc( status_send_third_message, STATUS_CLASSIC_INTERNAL_ERROR ); +} + +/** + * @fn void T_case_body_ScoreMsgqUnitMsgq( void ) + */ +T_TEST_CASE_FIXTURE( ScoreMsgqUnitMsgq, &ScoreMsgqUnitMsgq_Fixture ) +{ + ScoreMsgqUnitMsgq_Context *ctx; + + ctx = T_fixture_context(); + + ScoreMsgqUnitMsgq_Action_0( ctx ); + ScoreMsgqUnitMsgq_Action_1( ctx ); + ScoreMsgqUnitMsgq_Action_2( ctx ); +} + +/** @} */ diff --git a/testsuites/unit/tc-score-rbtree.c b/testsuites/unit/tc-score-rbtree.c index 36fff61b8f..ec286838d0 100644 --- a/testsuites/unit/tc-score-rbtree.c +++ b/testsuites/unit/tc-score-rbtree.c @@ -3,11 +3,11 @@ /** * @file * - * @ingroup RTEMSTestCaseScoreRbtreeUnitRbtree + * @ingroup ScoreRbtreeUnitRbtree */ /* - * Copyright (C) 2021 embedded brains GmbH (http://www.embedded-brains.de) + * Copyright (C) 2021 embedded brains GmbH & Co. KG * Copyright (C) 2010 Gedare Bloom * * Redistribution and use in source and binary forms, with or without @@ -59,9 +59,9 @@ #include <rtems/test.h> /** - * @defgroup RTEMSTestCaseScoreRbtreeUnitRbtree spec:/score/rbtree/unit/rbtree + * @defgroup ScoreRbtreeUnitRbtree spec:/score/rbtree/unit/rbtree * - * @ingroup RTEMSTestSuiteTestsuitesUnitNoClock0 + * @ingroup TestsuitesUnitNoClock0 * * @brief Unit tests for the red-black tree implementation. * diff --git a/testsuites/unit/ts-unit-no-clock-0.c b/testsuites/unit/ts-unit-no-clock-0.c index 8fa8518d36..88e67f91bd 100644 --- a/testsuites/unit/ts-unit-no-clock-0.c +++ b/testsuites/unit/ts-unit-no-clock-0.c @@ -3,11 +3,11 @@ /** * @file * - * @ingroup RTEMSTestSuiteTestsuitesUnitNoClock0 + * @ingroup TestsuitesUnitNoClock0 */ /* - * Copyright (C) 2021 embedded brains GmbH (http://www.embedded-brains.de) + * Copyright (C) 2021 embedded brains GmbH & Co. KG * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -55,10 +55,9 @@ #include <rtems/test.h> /** - * @defgroup RTEMSTestSuiteTestsuitesUnitNoClock0 \ - * spec:/testsuites/unit-no-clock-0 + * @defgroup TestsuitesUnitNoClock0 spec:/testsuites/unit-no-clock-0 * - * @ingroup RTEMSTestSuites + * @ingroup RTEMSTestSuitesUnit * * @brief This general purpose unit test suite provides enough resources to run * basic tests without a Clock Driver for all specified managers and @@ -70,7 +69,7 @@ * @{ */ -const char rtems_test_name[] = "UnitNoClock0"; +const char rtems_test_name[] = "TestsuitesUnitNoClock0"; #define CONFIGURE_MAXIMUM_PROCESSORS 4 |