Initial contribution
This commit is contained in:
parent
7b5cc4fa59
commit
11d9ce37aa
580 changed files with 155133 additions and 162 deletions
16
src/os/tests/CMakeLists.txt
Normal file
16
src/os/tests/CMakeLists.txt
Normal file
|
@ -0,0 +1,16 @@
|
|||
#
|
||||
# Copyright(c) 2006 to 2018 ADLINK Technology Limited and others
|
||||
#
|
||||
# This program and the accompanying materials are made available under the
|
||||
# terms of the Eclipse Public License v. 2.0 which is available at
|
||||
# http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
|
||||
# v. 1.0 which is available at
|
||||
# http://www.eclipse.org/org/documents/edl-v10.php.
|
||||
#
|
||||
# SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
|
||||
#
|
||||
include(CUnit)
|
||||
|
||||
add_cunit_executable(abstraction .)
|
||||
target_link_libraries(abstraction OSAPI)
|
||||
|
467
src/os/tests/atomics.c
Normal file
467
src/os/tests/atomics.c
Normal file
|
@ -0,0 +1,467 @@
|
|||
/*
|
||||
* Copyright(c) 2006 to 2018 ADLINK Technology Limited and others
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License v. 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
|
||||
* v. 1.0 which is available at
|
||||
* http://www.eclipse.org/org/documents/edl-v10.php.
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
|
||||
*/
|
||||
#include "os/os.h"
|
||||
#include "CUnit/Runner.h"
|
||||
|
||||
uint32_t _osuint32 = 0;
|
||||
uint64_t _osuint64 = 0;
|
||||
// os_address is uintptr_t
|
||||
uintptr_t _osaddress = 0;
|
||||
ptrdiff_t _ptrdiff = 0;
|
||||
void * _osvoidp = (uintptr_t *)0;
|
||||
|
||||
CUnit_Test(os_atomics, load_store)
|
||||
{
|
||||
volatile os_atomic_uint32_t uint32 = OS_ATOMIC_UINT32_INIT(5);
|
||||
#if OS_ATOMIC64_SUPPORT
|
||||
volatile os_atomic_uint64_t uint64 = OS_ATOMIC_UINT64_INIT(5);
|
||||
#endif
|
||||
volatile os_atomic_uintptr_t uintptr = OS_ATOMIC_UINTPTR_INIT(5);
|
||||
volatile os_atomic_voidp_t voidp = OS_ATOMIC_VOIDP_INIT((uintptr_t)5);
|
||||
|
||||
/* Test uint32 LD-ST */
|
||||
printf ("Starting os_atomics_load_store_001\n");
|
||||
CU_ASSERT (os_atomic_ld32 (&uint32) == 5); /* Returns contents of uint32 */
|
||||
os_atomic_st32 (&uint32, _osuint32); /* Writes os_uint32 into uint32 */
|
||||
CU_ASSERT (os_atomic_ld32 (&uint32) == _osuint32);
|
||||
|
||||
/* Test uint64 LD-ST */
|
||||
printf ("Starting os_atomics_load_store_002\n");
|
||||
#if OS_ATOMIC64_SUPPORT
|
||||
CU_ASSERT (os_atomic_ld64 (&uint64) == 5);
|
||||
os_atomic_st64 (&uint64, _osuint64);
|
||||
CU_ASSERT (os_atomic_ld64 (&uint64) == _osuint64);
|
||||
#endif
|
||||
|
||||
/* Test uintptr LD-ST */
|
||||
printf ("Starting os_atomics_load_store_003\n");
|
||||
CU_ASSERT (os_atomic_ldptr (&uintptr) == 5);
|
||||
os_atomic_stptr (&uintptr, _osaddress);
|
||||
CU_ASSERT (os_atomic_ldptr (&uintptr) == _osaddress);
|
||||
|
||||
/* Test uintvoidp LD-ST */
|
||||
printf ("Starting os_atomics_load_store_004\n");
|
||||
CU_ASSERT (os_atomic_ldvoidp (&voidp) == (uintptr_t*)5);
|
||||
os_atomic_stvoidp (&voidp, _osvoidp);
|
||||
CU_ASSERT (os_atomic_ldvoidp (&voidp) == (uintptr_t*)_osvoidp);
|
||||
|
||||
printf ("Ending atomics_load_store\n");
|
||||
}
|
||||
|
||||
CUnit_Test(os_atomics, compare_and_swap)
|
||||
{
|
||||
/* Compare and Swap
|
||||
* if (ptr == expected) { ptr = newval; }
|
||||
*/
|
||||
volatile os_atomic_uint32_t uint32 = OS_ATOMIC_UINT32_INIT(0);
|
||||
#if OS_ATOMIC64_SUPPORT
|
||||
volatile os_atomic_uint64_t uint64 = OS_ATOMIC_UINT64_INIT(0);
|
||||
#endif
|
||||
volatile os_atomic_uintptr_t uintptr = OS_ATOMIC_UINTPTR_INIT(0);
|
||||
volatile os_atomic_voidp_t uintvoidp = OS_ATOMIC_VOIDP_INIT((uintptr_t)0);
|
||||
_osuint32 = 1;
|
||||
_osuint64 = 1;
|
||||
_osaddress = 1;
|
||||
_osvoidp = (uintptr_t *)1;
|
||||
uint32_t expected = 0, newval = 5;
|
||||
uintptr_t addr_expected = 0, addr_newval = 5;
|
||||
void *void_expected = (uintptr_t*)0;
|
||||
void *void_newval = (uintptr_t*)5;
|
||||
int ret = 0;
|
||||
|
||||
/* Test os_atomic_cas32 */
|
||||
printf ("Starting os_atomics_compare_and_swap_001\n");
|
||||
ret = os_atomic_cas32 (&uint32, expected, newval);
|
||||
CU_ASSERT (os_atomic_ld32 (&uint32) == newval && ret == 1);
|
||||
os_atomic_st32 (&uint32, _osuint32);
|
||||
ret = os_atomic_cas32 (&uint32, expected, newval);
|
||||
CU_ASSERT (os_atomic_ld32 (&uint32) != newval && ret == 0);
|
||||
|
||||
/* Test os_atomic_cas64 */
|
||||
printf ("Starting os_atomics_compare_and_swap_002\n");
|
||||
#if OS_ATOMIC64_SUPPORT
|
||||
ret = os_atomic_cas64 (&uint64, expected, newval);
|
||||
CU_ASSERT (os_atomic_ld64 (&uint64) == newval && ret == 1);
|
||||
os_atomic_st64 (&uint64, _osuint64);
|
||||
ret = os_atomic_cas64 (&uint64, expected, newval);
|
||||
CU_ASSERT (os_atomic_ld64 (&uint64) != newval && ret == 0);
|
||||
#endif
|
||||
|
||||
/* Test os_atomic_casptr */
|
||||
printf ("Starting os_atomics_compare_and_swap_003\n");
|
||||
ret = os_atomic_casptr (&uintptr, addr_expected, addr_newval);
|
||||
CU_ASSERT (os_atomic_ldptr (&uintptr) == addr_newval && ret == 1);
|
||||
os_atomic_stptr (&uintptr, _osaddress);
|
||||
ret = os_atomic_casptr (&uintptr, addr_expected, addr_newval);
|
||||
CU_ASSERT (os_atomic_ldptr (&uintptr) != addr_newval && ret == 0);
|
||||
|
||||
/* Test os_atomic_casvoidp */
|
||||
printf ("Starting os_atomics_compare_and_swap_003\n");
|
||||
ret = os_atomic_casvoidp (&uintvoidp, void_expected, void_newval);
|
||||
CU_ASSERT (os_atomic_ldvoidp (&uintvoidp) == (uintptr_t*)void_newval && ret == 1);
|
||||
os_atomic_stvoidp (&uintvoidp, _osvoidp);
|
||||
ret = os_atomic_casvoidp (&uintvoidp, void_expected, void_newval);
|
||||
CU_ASSERT (os_atomic_ldvoidp (&uintvoidp) == (uintptr_t*)1 && ret == 0);
|
||||
|
||||
printf ("Ending atomics_compare_and_swap\n");
|
||||
}
|
||||
|
||||
CUnit_Test(os_atomics, increment)
|
||||
{
|
||||
volatile os_atomic_uint32_t uint32 = OS_ATOMIC_UINT32_INIT(0);
|
||||
#if OS_ATOMIC64_SUPPORT
|
||||
volatile os_atomic_uint64_t uint64 = OS_ATOMIC_UINT64_INIT(0);
|
||||
#endif
|
||||
volatile os_atomic_uintptr_t uintptr = OS_ATOMIC_UINTPTR_INIT(0);
|
||||
_osuint32 = 0;
|
||||
_osuint64 = 0;
|
||||
_osaddress = 0;
|
||||
_osvoidp = (uintptr_t *)0;
|
||||
|
||||
/* Test os_inc32 */
|
||||
printf ("Starting os_atomics_increment_001\n");
|
||||
os_atomic_inc32 (&uint32);
|
||||
CU_ASSERT (os_atomic_ld32 (&uint32) == 1);
|
||||
|
||||
/* Test os_inc64 */
|
||||
printf ("Starting os_atomics_increment_002\n");
|
||||
#if OS_ATOMIC64_SUPPORT
|
||||
os_atomic_inc64 (&uint64);
|
||||
CU_ASSERT (os_atomic_ld64 (&uint64) == 1);
|
||||
#endif
|
||||
|
||||
/* Test os_incptr */
|
||||
printf ("Starting os_atomics_increment_003\n");
|
||||
os_atomic_incptr (&uintptr);
|
||||
CU_ASSERT (os_atomic_ldptr (&uintptr) == 1);
|
||||
|
||||
/* Test os_atomic_inc32_nv */
|
||||
printf ("Starting os_atomics_increment_004\n");
|
||||
os_atomic_st32 (&uint32, _osuint32);
|
||||
CU_ASSERT (os_atomic_inc32_nv (&uint32) == 1);
|
||||
|
||||
/* Test os_atomic_inc64_nv */
|
||||
printf ("Starting os_atomics_increment_005\n");
|
||||
#if OS_ATOMIC64_SUPPORT
|
||||
os_atomic_st64 (&uint64, _osuint64);
|
||||
CU_ASSERT (os_atomic_inc64_nv (&uint64) == 1);
|
||||
#endif
|
||||
|
||||
/* Test os_atomic_incptr_nv */
|
||||
printf ("Starting os_atomics_increment_006\n");
|
||||
os_atomic_stptr (&uintptr, _osaddress);
|
||||
CU_ASSERT (os_atomic_incptr_nv(&uintptr) == 1);
|
||||
|
||||
printf ("Ending atomics_increment\n");
|
||||
}
|
||||
|
||||
CUnit_Test(os_atomics, decrement)
|
||||
{
|
||||
volatile os_atomic_uint32_t uint32 = OS_ATOMIC_UINT32_INIT(1);
|
||||
#if OS_ATOMIC64_SUPPORT
|
||||
volatile os_atomic_uint64_t uint64 = OS_ATOMIC_UINT64_INIT(1);
|
||||
#endif
|
||||
volatile os_atomic_uintptr_t uintptr = OS_ATOMIC_UINTPTR_INIT(1);
|
||||
_osuint32 = 1;
|
||||
_osuint64 = 1;
|
||||
_osaddress = 1;
|
||||
_osvoidp = (uintptr_t *)1;
|
||||
|
||||
/* Test os_atomic_dec32 */
|
||||
printf ("Starting os_atomics_decrement_001\n");
|
||||
os_atomic_dec32 (&uint32);
|
||||
CU_ASSERT (os_atomic_ld32 (&uint32) == 0);
|
||||
|
||||
/* Test os_atomic_dec64 */
|
||||
printf ("Starting os_atomics_decrement_002\n");
|
||||
#if OS_ATOMIC64_SUPPORT
|
||||
os_atomic_dec64 (&uint64);
|
||||
CU_ASSERT (os_atomic_ld64 (&uint64) == 0);
|
||||
#endif
|
||||
|
||||
/* Test os_atomic_decptr */
|
||||
printf ("Starting os_atomics_decrement_003\n");
|
||||
os_atomic_decptr (&uintptr);
|
||||
CU_ASSERT (os_atomic_ldptr (&uintptr) == 0);
|
||||
|
||||
/* Test os_atomic_dec32_nv */
|
||||
printf ("Starting os_atomics_decrement_004\n");
|
||||
os_atomic_st32 (&uint32, _osuint32);
|
||||
CU_ASSERT (os_atomic_dec32_nv (&uint32) == 0);
|
||||
|
||||
/* Test os_atomic_dec64_nv */
|
||||
printf ("Starting os_atomics_decrement_005\n");
|
||||
#if OS_ATOMIC64_SUPPORT
|
||||
os_atomic_st64 (&uint64, _osuint64);
|
||||
CU_ASSERT (os_atomic_dec64_nv (&uint64) == 0);
|
||||
#endif
|
||||
|
||||
/* Test os_atomic_decptr_nv */
|
||||
printf ("Starting os_atomics_decrement_006\n");
|
||||
os_atomic_stptr (&uintptr, _osaddress);
|
||||
CU_ASSERT (os_atomic_decptr_nv(&uintptr) == 0);
|
||||
|
||||
printf ("Ending atomics_decrement\n");
|
||||
}
|
||||
|
||||
CUnit_Test(os_atomics, add)
|
||||
{
|
||||
volatile os_atomic_uint32_t uint32 = OS_ATOMIC_UINT32_INIT(1);
|
||||
#if OS_ATOMIC64_SUPPORT
|
||||
volatile os_atomic_uint64_t uint64 = OS_ATOMIC_UINT64_INIT(1);
|
||||
#endif
|
||||
volatile os_atomic_uintptr_t uintptr = OS_ATOMIC_UINTPTR_INIT(1);
|
||||
volatile os_atomic_voidp_t uintvoidp = OS_ATOMIC_VOIDP_INIT((uintptr_t)1);
|
||||
_osuint32 = 2;
|
||||
_osuint64 = 2;
|
||||
_osaddress = 2;
|
||||
_ptrdiff = 2;
|
||||
|
||||
/* Test os_atomic_add32 */
|
||||
printf ("Starting os_atomics_add_001\n");
|
||||
os_atomic_add32 (&uint32, _osuint32);
|
||||
CU_ASSERT (os_atomic_ld32 (&uint32) == 3);
|
||||
|
||||
/* Test os_atomic_add64 */
|
||||
printf ("Starting os_atomics_add_002\n");
|
||||
#if OS_ATOMIC64_SUPPORT
|
||||
os_atomic_add64 (&uint64, _osuint64);
|
||||
CU_ASSERT (os_atomic_ld64 (&uint64) == 3);
|
||||
#endif
|
||||
|
||||
/* Test os_atomic_addptr */
|
||||
printf ("Starting os_atomics_add_003\n");
|
||||
os_atomic_addptr (&uintptr, _osaddress);
|
||||
CU_ASSERT (os_atomic_ldptr (&uintptr) == 3);
|
||||
|
||||
/* Test os_atomic_addvoidp */
|
||||
printf ("Starting os_atomics_add_004\n");
|
||||
os_atomic_addvoidp (&uintvoidp, _ptrdiff);
|
||||
CU_ASSERT (os_atomic_ldvoidp (&uintvoidp) == (uintptr_t*)3);
|
||||
|
||||
/* Test os_atomic_add32_nv */
|
||||
printf ("Starting os_atomics_add_005\n");
|
||||
os_atomic_st32 (&uint32, 1);
|
||||
CU_ASSERT (os_atomic_add32_nv (&uint32, _osuint32) == 3);
|
||||
|
||||
/* Test os_atomic_add64_nv */
|
||||
printf ("Starting os_atomics_add_006\n");
|
||||
#if OS_ATOMIC64_SUPPORT
|
||||
os_atomic_st64 (&uint64, 1);
|
||||
CU_ASSERT (os_atomic_add64_nv (&uint64, _osuint64) == 3);
|
||||
#endif
|
||||
|
||||
/* Test os_atomic_addptr_nv */
|
||||
printf ("Starting os_atomics_add_007\n");
|
||||
os_atomic_stptr (&uintptr, 1);
|
||||
CU_ASSERT (os_atomic_addptr_nv (&uintptr, _osaddress) == 3);
|
||||
|
||||
/* Test os_atomic_addvoidp_nv */
|
||||
printf ("Starting os_atomics_add_008\n");
|
||||
os_atomic_stvoidp (&uintvoidp, (uintptr_t*)1);
|
||||
CU_ASSERT (os_atomic_addvoidp_nv (&uintvoidp, _ptrdiff) == (uintptr_t*)3);
|
||||
|
||||
printf ("Ending atomics_add\n");
|
||||
}
|
||||
|
||||
CUnit_Test(os_atomics, subtract)
|
||||
{
|
||||
volatile os_atomic_uint32_t uint32 = OS_ATOMIC_UINT32_INIT(5);
|
||||
#if OS_ATOMIC64_SUPPORT
|
||||
volatile os_atomic_uint64_t uint64 = OS_ATOMIC_UINT64_INIT(5);
|
||||
#endif
|
||||
volatile os_atomic_uintptr_t uintptr = OS_ATOMIC_UINTPTR_INIT(5);
|
||||
volatile os_atomic_voidp_t uintvoidp = OS_ATOMIC_VOIDP_INIT((uintptr_t)5);
|
||||
_osuint32 = 2;
|
||||
_osuint64 = 2;
|
||||
_osaddress = 2;
|
||||
_ptrdiff = 2;
|
||||
|
||||
/* Test os_atomic_sub32 */
|
||||
printf ("Starting os_atomics_subtract_001\n");
|
||||
os_atomic_sub32 (&uint32, _osuint32);
|
||||
CU_ASSERT (os_atomic_ld32 (&uint32) == 3);
|
||||
|
||||
/* Test os_atomic_sub64 */
|
||||
printf ("Starting os_atomics_subtract_002\n");
|
||||
#if OS_ATOMIC64_SUPPORT
|
||||
os_atomic_sub64 (&uint64, _osuint64);
|
||||
CU_ASSERT (os_atomic_ld64 (&uint64) == 3);
|
||||
#endif
|
||||
|
||||
/* Test os_atomic_subptr */
|
||||
printf ("Starting os_atomics_subtract_003\n");
|
||||
os_atomic_subptr (&uintptr, _osaddress);
|
||||
CU_ASSERT (os_atomic_ldptr (&uintptr) == 3);
|
||||
|
||||
/* Test os_atomic_subvoidp */
|
||||
printf ("Starting os_atomics_subtract_004\n");
|
||||
os_atomic_subvoidp (&uintvoidp, _ptrdiff);
|
||||
CU_ASSERT (os_atomic_ldvoidp (&uintvoidp) == (uintptr_t*)3);
|
||||
|
||||
/* Test os_atomic_sub32_nv */
|
||||
printf ("Starting os_atomics_subtract_005\n");
|
||||
os_atomic_st32 (&uint32, 5);
|
||||
CU_ASSERT (os_atomic_sub32_nv (&uint32, _osuint32) == 3);
|
||||
|
||||
/* Test os_atomic_sub64_nv */
|
||||
printf ("Starting os_atomics_subtract_006\n");
|
||||
#if OS_ATOMIC64_SUPPORT
|
||||
os_atomic_st64 (&uint64, 5);
|
||||
CU_ASSERT (os_atomic_sub64_nv (&uint64, _osuint64) == 3);
|
||||
#endif
|
||||
|
||||
/* Test os_atomic_subptr_nv */
|
||||
printf ("Starting os_atomics_subtract_007\n");
|
||||
os_atomic_stptr (&uintptr, 5);
|
||||
CU_ASSERT (os_atomic_subptr_nv (&uintptr, _osaddress) == 3);
|
||||
|
||||
/* Test os_atomic_subvoidp_nv */
|
||||
printf ("Starting os_atomics_subtract_008\n");
|
||||
os_atomic_stvoidp (&uintvoidp, (uintptr_t*)5);
|
||||
CU_ASSERT (os_atomic_subvoidp_nv (&uintvoidp, _ptrdiff) == (void *)3);
|
||||
|
||||
printf ("Ending atomics_subtract\n");
|
||||
}
|
||||
|
||||
CUnit_Test(os_atomics, and)
|
||||
{
|
||||
/* AND Operation:
|
||||
|
||||
150 010010110
|
||||
500 111110100
|
||||
|
||||
148 010010100 */
|
||||
|
||||
volatile os_atomic_uint32_t uint32 = OS_ATOMIC_UINT32_INIT(150);
|
||||
#if OS_ATOMIC64_SUPPORT
|
||||
volatile os_atomic_uint64_t uint64 = OS_ATOMIC_UINT64_INIT(150);
|
||||
#endif
|
||||
volatile os_atomic_uintptr_t uintptr = OS_ATOMIC_UINTPTR_INIT(150);
|
||||
_osuint32 = 500;
|
||||
_osuint64 = 500;
|
||||
_osaddress = 500;
|
||||
|
||||
/* Test os_atomic_and32 */
|
||||
printf ("Starting os_atomics_and_001\n");
|
||||
os_atomic_and32 (&uint32, _osuint32);
|
||||
CU_ASSERT (os_atomic_ld32 (&uint32) == 148);
|
||||
|
||||
/* Test os_atomic_and64 */
|
||||
printf ("Starting os_atomics_and_002\n");
|
||||
#if OS_ATOMIC64_SUPPORT
|
||||
os_atomic_and64 (&uint64, _osuint64);
|
||||
CU_ASSERT (os_atomic_ld64 (&uint64) == 148);
|
||||
#endif
|
||||
|
||||
/* Test os_atomic_andptr */
|
||||
printf ("Starting os_atomics_and_003\n");
|
||||
os_atomic_andptr (&uintptr, _osaddress);
|
||||
CU_ASSERT (os_atomic_ldptr (&uintptr) == 148);
|
||||
|
||||
/* Test os_atomic_and32_ov */
|
||||
printf ("Starting os_atomics_and_004\n");
|
||||
CU_ASSERT (os_atomic_and32_ov (&uint32, _osuint32) == 148);
|
||||
|
||||
/* Test os_atomic_and64_ov */
|
||||
printf ("Starting os_atomics_and_005\n");
|
||||
#if OS_ATOMIC64_SUPPORT
|
||||
CU_ASSERT (os_atomic_and64_ov (&uint64, _osuint64) == 148);
|
||||
#endif
|
||||
|
||||
/* Test os_atomic_andptr_ov */
|
||||
printf ("Starting os_atomics_and_006\n");
|
||||
CU_ASSERT (os_atomic_andptr_ov (&uintptr, _osaddress) == 148);
|
||||
|
||||
/* Test os_atomic_and32_nv */
|
||||
printf ("Starting os_atomics_and_007\n");
|
||||
CU_ASSERT (os_atomic_and32_nv (&uint32, _osuint32) == 148);
|
||||
|
||||
/* Test os_atomic_and64_nv */
|
||||
printf ("Starting os_atomics_and_008\n");
|
||||
#if OS_ATOMIC64_SUPPORT
|
||||
CU_ASSERT (os_atomic_and64_nv (&uint64, _osuint64) == 148);
|
||||
#endif
|
||||
|
||||
/* Test os_atomic_andptr_nv */
|
||||
printf ("Starting os_atomics_and_009\n");
|
||||
CU_ASSERT (os_atomic_andptr_nv (&uintptr, _osaddress) == 148);
|
||||
|
||||
printf ("Ending atomics_and\n");
|
||||
}
|
||||
|
||||
CUnit_Test(os_atomics, or)
|
||||
{
|
||||
/* OR Operation:
|
||||
|
||||
150 010010110
|
||||
500 111110100
|
||||
|
||||
502 111110110 */
|
||||
|
||||
volatile os_atomic_uint32_t uint32 = OS_ATOMIC_UINT32_INIT(150);
|
||||
#if OS_ATOMIC64_SUPPORT
|
||||
volatile os_atomic_uint64_t uint64 = OS_ATOMIC_UINT64_INIT(150);
|
||||
#endif
|
||||
volatile os_atomic_uintptr_t uintptr = OS_ATOMIC_UINTPTR_INIT(150);
|
||||
_osuint32 = 500;
|
||||
_osuint64 = 500;
|
||||
_osaddress = 500;
|
||||
|
||||
/* Test os_atomic_or32 */
|
||||
printf ("Starting os_atomics_or_001\n");
|
||||
os_atomic_or32 (&uint32, _osuint32);
|
||||
CU_ASSERT (os_atomic_ld32 (&uint32) == 502);
|
||||
|
||||
/* Test os_atomic_or64 */
|
||||
printf ("Starting os_atomics_or_002\n");
|
||||
#if OS_ATOMIC64_SUPPORT
|
||||
os_atomic_or64 (&uint64, _osuint64);
|
||||
CU_ASSERT (os_atomic_ld64 (&uint64) == 502);
|
||||
#endif
|
||||
|
||||
/* Test os_atomic_orptr */
|
||||
printf ("Starting os_atomics_or_003\n");
|
||||
os_atomic_orptr (&uintptr, _osaddress);
|
||||
CU_ASSERT (os_atomic_ldptr (&uintptr) == 502);
|
||||
|
||||
/* Test os_atomic_or32_ov */
|
||||
printf ("Starting os_atomics_or_004\n");
|
||||
CU_ASSERT (os_atomic_or32_ov (&uint32, _osuint32) == 502);
|
||||
|
||||
/* Test os_atomic_or64_ov */
|
||||
printf ("Starting os_atomics_or_005\n");
|
||||
#if OS_ATOMIC64_SUPPORT
|
||||
CU_ASSERT (os_atomic_or64_ov (&uint64, _osuint64) == 502);
|
||||
#endif
|
||||
|
||||
/* Test os_atomic_orptr_ov */
|
||||
printf ("Starting os_atomics_or_006\n");
|
||||
CU_ASSERT (os_atomic_orptr_ov (&uintptr, _osaddress) == 502);
|
||||
|
||||
/* Test os_atomic_or32_nv */
|
||||
printf ("Starting os_atomics_or_007\n");
|
||||
CU_ASSERT (os_atomic_or32_nv (&uint32, _osuint32) == 502);
|
||||
|
||||
/* Test os_atomic_or64_nv */
|
||||
printf ("Starting os_atomics_or_008\n");
|
||||
#if OS_ATOMIC64_SUPPORT
|
||||
CU_ASSERT (os_atomic_or64_nv (&uint64, _osuint64) == 502);
|
||||
#endif
|
||||
|
||||
/* Test os_atomic_orptr_nv */
|
||||
printf ("Starting os_atomics_or_009\n");
|
||||
CU_ASSERT (os_atomic_orptr_nv (&uintptr, _osaddress) == 502);
|
||||
|
||||
printf ("Ending atomics_or\n");
|
||||
}
|
||||
|
47
src/os/tests/error_no.c
Normal file
47
src/os/tests/error_no.c
Normal file
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
* Copyright(c) 2006 to 2018 ADLINK Technology Limited and others
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License v. 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
|
||||
* v. 1.0 which is available at
|
||||
* http://www.eclipse.org/org/documents/edl-v10.php.
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
|
||||
*/
|
||||
#include "CUnit/Runner.h"
|
||||
#include "os/os.h"
|
||||
|
||||
|
||||
CUnit_Suite_Initialize(os_errno)
|
||||
{
|
||||
int result = 0;
|
||||
os_osInit();
|
||||
printf("Run os_errno_Initialize\n");
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
CUnit_Suite_Cleanup(os_errno)
|
||||
{
|
||||
int result = 0;
|
||||
os_osExit();
|
||||
printf("Run os_errno_Cleanup\n");
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
CUnit_Test(os_errno, get_and_set)
|
||||
{
|
||||
printf ("Starting os_errno_get_and_set_001\n");
|
||||
os_setErrno (0);
|
||||
CU_ASSERT (os_getErrno () == 0);
|
||||
|
||||
printf ("Starting os_errno_get_and_set_002\n");
|
||||
os_setErrno (0);
|
||||
/* Call strtol with an invalid format on purpose. */
|
||||
(void)strtol ("1000000000000000000000000000000000000000000000000", NULL, 10);
|
||||
CU_ASSERT (os_getErrno () != 0);
|
||||
|
||||
printf ("Ending tc_os_errno\n");
|
||||
}
|
197
src/os/tests/heap.c
Normal file
197
src/os/tests/heap.c
Normal file
|
@ -0,0 +1,197 @@
|
|||
/*
|
||||
* Copyright(c) 2006 to 2018 ADLINK Technology Limited and others
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License v. 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
|
||||
* v. 1.0 which is available at
|
||||
* http://www.eclipse.org/org/documents/edl-v10.php.
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
|
||||
*/
|
||||
#include "CUnit/Runner.h"
|
||||
#include "os/os.h"
|
||||
|
||||
|
||||
CUnit_Suite_Initialize(os_heap)
|
||||
{
|
||||
int result = 0;
|
||||
os_osInit();
|
||||
printf("Run os_heap_Initialize\n");
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
CUnit_Suite_Cleanup(os_heap)
|
||||
{
|
||||
int result = 0;
|
||||
os_osExit();
|
||||
printf("Run os_heap_Cleanup\n");
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static const size_t allocsizes[] = {0, 1, 2, 3, 4, 5, 10, 20, 257, 1024};
|
||||
static const size_t nof_allocsizes = sizeof allocsizes / sizeof *allocsizes;
|
||||
|
||||
CUnit_Test(os_heap, os_malloc)
|
||||
{
|
||||
for(int i = 0; i < nof_allocsizes; i++) {
|
||||
for(int j = 0; j < nof_allocsizes; j++) {
|
||||
size_t s = allocsizes[i] * allocsizes[j]; /* Allocates up to 1MB */
|
||||
void *ptr = os_malloc(s);
|
||||
CU_ASSERT_PTR_NOT_EQUAL(ptr, NULL); /* os_malloc is supposed to abort on failure */
|
||||
memset(ptr, 0, s); /* This potentially segfaults if the actual allocated block is too small */
|
||||
os_free(ptr);
|
||||
}
|
||||
}
|
||||
CU_PASS("os_malloc");
|
||||
}
|
||||
|
||||
CUnit_Test(os_heap, os_malloc_0)
|
||||
{
|
||||
for(int i = 0; i < nof_allocsizes; i++) {
|
||||
for(int j = 0; j < nof_allocsizes; j++) {
|
||||
size_t s = allocsizes[i] * allocsizes[j]; /* Allocates up to 1MB */
|
||||
char *ptr = os_malloc_0(s);
|
||||
CU_ASSERT_PTR_NOT_EQUAL(ptr, NULL); /* os_malloc_0 is supposed to abort on failure */
|
||||
if(s) {
|
||||
CU_ASSERT (ptr[0] == 0 && !memcmp(ptr, ptr + 1, s - 1)); /* malloc_0 should memset properly */
|
||||
}
|
||||
os_free(ptr);
|
||||
}
|
||||
}
|
||||
CU_PASS("os_malloc_0");
|
||||
}
|
||||
|
||||
CUnit_Test(os_heap, os_calloc)
|
||||
{
|
||||
for(int i = 0; i < nof_allocsizes; i++) {
|
||||
for(int j = 0; j < nof_allocsizes; j++) {
|
||||
char *ptr = os_calloc(allocsizes[i], allocsizes[j]);
|
||||
CU_ASSERT_PTR_NOT_EQUAL(ptr, NULL); /* os_calloc is supposed to abort on failure */
|
||||
if(allocsizes[i] * allocsizes[j]) {
|
||||
CU_ASSERT (ptr[0] == 0 && !memcmp(ptr, ptr + 1, (allocsizes[i] * allocsizes[j]) - 1)); /* os_calloc should memset properly */
|
||||
}
|
||||
os_free(ptr);
|
||||
}
|
||||
}
|
||||
CU_PASS("os_calloc");
|
||||
}
|
||||
|
||||
CUnit_Test(os_heap, os_realloc)
|
||||
{
|
||||
char *ptr = NULL;
|
||||
size_t unchanged, s, prevs = 0;
|
||||
|
||||
for(int i = 0; i < nof_allocsizes; i++) {
|
||||
for(int j = 0; j < nof_allocsizes; j++) {
|
||||
s = allocsizes[i] * allocsizes[j]; /* Allocates up to 1MB */
|
||||
printf("os_realloc(%p) %zu -> %zu\n", ptr, prevs, s);
|
||||
ptr = os_realloc(ptr, s);
|
||||
CU_ASSERT_PTR_NOT_EQUAL(ptr, NULL); /* os_realloc is supposed to abort on failure */
|
||||
unchanged = (prevs < s) ? prevs : s;
|
||||
if(unchanged) {
|
||||
CU_ASSERT (ptr[0] == 1 && !memcmp(ptr, ptr + 1, unchanged - 1)); /* os_realloc shouldn't change memory */
|
||||
}
|
||||
memset(ptr, 1, s); /* This potentially segfaults if the actual allocated block is too small */
|
||||
prevs = s;
|
||||
}
|
||||
}
|
||||
os_free(ptr);
|
||||
CU_PASS("os_realloc");
|
||||
}
|
||||
|
||||
static const size_t allocsizes_s[] = {0, 1, 2, 3, 4, 5, 10, 20, 257, 1024, 8192};
|
||||
static const size_t nof_allocsizes_s = sizeof allocsizes_s / sizeof *allocsizes_s;
|
||||
|
||||
CUnit_Test(os_heap, os_malloc_s)
|
||||
{
|
||||
for(int i = 0; i < nof_allocsizes_s; i++) {
|
||||
for(int j = 0; j < nof_allocsizes_s; j++) {
|
||||
size_t s = allocsizes_s[i] * allocsizes_s[j]; /* Allocates up to 8MB */
|
||||
void *ptr = os_malloc_s(s); /* If s == 0, os_malloc_s should still return a pointer */
|
||||
if(ptr) {
|
||||
memset(ptr, 0, s); /* This potentially segfaults if the actual allocated block is too small */
|
||||
} else if (s <= 16) {
|
||||
/* Failure to allocate can't be considered a test fault really,
|
||||
* except that a malloc(<=16) would fail is unlikely. */
|
||||
CU_FAIL("os_malloc_0_s(<=16) returned NULL");
|
||||
}
|
||||
os_free(ptr);
|
||||
}
|
||||
}
|
||||
CU_PASS("os_malloc_s");
|
||||
}
|
||||
|
||||
CUnit_Test(os_heap, os_malloc_0_s)
|
||||
{
|
||||
for(int i = 0; i < nof_allocsizes_s; i++) {
|
||||
for(int j = 0; j < nof_allocsizes_s; j++) {
|
||||
size_t s = allocsizes_s[i] * allocsizes_s[j]; /* Allocates up to 8MB */
|
||||
char *ptr = os_malloc_0_s(s); /* If s == 0, os_malloc_0_s should still return a pointer */
|
||||
if(ptr) {
|
||||
if(s) {
|
||||
CU_ASSERT (ptr[0] == 0 && !memcmp(ptr, ptr + 1, s - 1)); /* malloc_0_s should memset properly */
|
||||
}
|
||||
} else if (s <= 16) {
|
||||
/* Failure to allocate can't be considered a test fault really,
|
||||
* except that a malloc(<=16) would fail is unlikely. */
|
||||
CU_FAIL("os_malloc_0_s(<=16) returned NULL");
|
||||
}
|
||||
os_free(ptr);
|
||||
}
|
||||
}
|
||||
CU_PASS("os_malloc_0_s");
|
||||
}
|
||||
|
||||
CUnit_Test(os_heap, os_calloc_s)
|
||||
{
|
||||
for(int i = 0; i < nof_allocsizes_s; i++) {
|
||||
for(int j = 0; j < nof_allocsizes_s; j++) {
|
||||
size_t s = allocsizes_s[i] * allocsizes_s[j];
|
||||
char *ptr = os_calloc_s(allocsizes_s[i], allocsizes_s[j]); /* If either one is 0, os_calloc_s should still return a pointer */
|
||||
if(ptr) {
|
||||
if(s) {
|
||||
CU_ASSERT (ptr[0] == 0 && !memcmp(ptr, ptr + 1, s - 1)); /* malloc_0_s should memset properly */
|
||||
}
|
||||
} else if (s <= 16) {
|
||||
/* Failure to allocate can't be considered a test fault really,
|
||||
* except that a calloc(<=16) would fail is unlikely. */
|
||||
CU_FAIL("os_calloc_s(<=16) returned NULL");
|
||||
}
|
||||
os_free(ptr);
|
||||
}
|
||||
}
|
||||
CU_PASS("os_calloc_s");
|
||||
}
|
||||
|
||||
CUnit_Test(os_heap, os_realloc_s)
|
||||
{
|
||||
char *newptr, *ptr = NULL;
|
||||
size_t unchanged, s, prevs = 0;
|
||||
|
||||
for(int i = 0; i < nof_allocsizes_s; i++) {
|
||||
for(int j = 0; j < nof_allocsizes_s; j++) {
|
||||
s = allocsizes_s[i] * allocsizes_s[j]; /* Allocates up to 8MB */
|
||||
newptr = os_realloc_s(ptr, s);
|
||||
printf("%p = os_realloc_s(%p) %zu -> %zu\n", newptr, ptr, prevs, s);
|
||||
if (s <= 16) {
|
||||
/* Failure to allocate can't be considered a test fault really,
|
||||
* except that a os_realloc_s(0 < s <=16) would fail is unlikely. */
|
||||
CU_ASSERT_PTR_NOT_EQUAL(newptr, NULL);
|
||||
}
|
||||
if(newptr){
|
||||
unchanged = (prevs < s) ? prevs : s;
|
||||
if(unchanged) {
|
||||
CU_ASSERT (newptr[0] == 1 && !memcmp(newptr, newptr + 1, unchanged - 1)); /* os_realloc_s shouldn't change memory */
|
||||
}
|
||||
memset(newptr, 1, s); /* This potentially segfaults if the actual allocated block is too small */
|
||||
}
|
||||
prevs = s;
|
||||
ptr = newptr;
|
||||
}
|
||||
}
|
||||
os_free(ptr);
|
||||
CU_PASS("os_realloc_s");
|
||||
}
|
239
src/os/tests/iter.c
Executable file
239
src/os/tests/iter.c
Executable file
|
@ -0,0 +1,239 @@
|
|||
/*
|
||||
* Copyright(c) 2006 to 2018 ADLINK Technology Limited and others
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License v. 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
|
||||
* v. 1.0 which is available at
|
||||
* http://www.eclipse.org/org/documents/edl-v10.php.
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
|
||||
*/
|
||||
#include "CUnit/Runner.h"
|
||||
#include "os/os.h"
|
||||
#include "assert.h"
|
||||
|
||||
static int32_t one = 1;
|
||||
static int32_t two = 2;
|
||||
static int32_t three = 3;
|
||||
static int32_t four = 4;
|
||||
static int32_t five = 5;
|
||||
|
||||
CUnit_Test(os_iter, create)
|
||||
{
|
||||
os_iter *iter;
|
||||
|
||||
iter = os_iterNew();
|
||||
CU_ASSERT_PTR_NOT_NULL_FATAL(iter);
|
||||
CU_ASSERT_EQUAL(os_iterLength(iter), 0);
|
||||
CU_ASSERT_PTR_NULL(os_iterObject(iter, 0));
|
||||
CU_ASSERT_PTR_NULL(os_iterTake(iter, 0));
|
||||
os_iterFree(iter, NULL);
|
||||
}
|
||||
|
||||
CUnit_Test(os_iter, prepend)
|
||||
{
|
||||
os_iter *iter;
|
||||
int32_t idx;
|
||||
|
||||
iter = os_iterNew();
|
||||
CU_ASSERT_PTR_NOT_NULL_FATAL(iter);
|
||||
idx = os_iterInsert(iter, &one, 0);
|
||||
CU_ASSERT_EQUAL(idx, 0);
|
||||
idx = os_iterInsert(iter, &two, 0);
|
||||
CU_ASSERT_EQUAL(idx, 0);
|
||||
idx = os_iterInsert(iter, &three, 0);
|
||||
CU_ASSERT_EQUAL(idx, 0);
|
||||
CU_ASSERT_EQUAL(os_iterLength(iter), 3);
|
||||
CU_ASSERT_EQUAL(*(int32_t *)os_iterObject(iter, 0), 3);
|
||||
CU_ASSERT_EQUAL(*(int32_t *)os_iterObject(iter, 1), 2);
|
||||
CU_ASSERT_EQUAL(*(int32_t *)os_iterObject(iter, 2), 1);
|
||||
os_iterFree(iter, NULL);
|
||||
}
|
||||
|
||||
CUnit_Test(os_iter, append)
|
||||
{
|
||||
os_iter *iter;
|
||||
int32_t idx;
|
||||
|
||||
iter = os_iterNew();
|
||||
CU_ASSERT_PTR_NOT_NULL_FATAL(iter);
|
||||
idx = os_iterInsert(iter, &one, OS_ITER_LENGTH);
|
||||
CU_ASSERT_EQUAL(idx, 0);
|
||||
idx = os_iterInsert(iter, &two, OS_ITER_LENGTH);
|
||||
CU_ASSERT_EQUAL(idx, 1);
|
||||
idx = os_iterInsert(iter, &three, OS_ITER_LENGTH);
|
||||
CU_ASSERT_EQUAL(idx, 2);
|
||||
CU_ASSERT_EQUAL(os_iterLength(iter), 3);
|
||||
CU_ASSERT_EQUAL(*(int32_t *)os_iterObject(iter, 0), 1);
|
||||
CU_ASSERT_EQUAL(*(int32_t *)os_iterObject(iter, 1), 2);
|
||||
CU_ASSERT_EQUAL(*(int32_t *)os_iterObject(iter, 2), 3);
|
||||
os_iterFree(iter, NULL);
|
||||
}
|
||||
|
||||
CUnit_Test(os_iter, insert)
|
||||
{
|
||||
os_iter *iter;
|
||||
int32_t idx;
|
||||
|
||||
iter = os_iterNew();
|
||||
CU_ASSERT_PTR_NOT_NULL_FATAL(iter);
|
||||
idx = os_iterInsert(iter, &one, 0);
|
||||
CU_ASSERT_EQUAL(idx, 0);
|
||||
idx = os_iterInsert(iter, &three, OS_ITER_LENGTH);
|
||||
CU_ASSERT_EQUAL(idx, 1);
|
||||
idx = os_iterInsert(iter, &two, idx);
|
||||
CU_ASSERT_EQUAL(idx, 1);
|
||||
idx = os_iterInsert(iter, &four, -2);
|
||||
CU_ASSERT_EQUAL(idx, 1);
|
||||
idx = os_iterInsert(iter, &five, -2);
|
||||
CU_ASSERT_EQUAL(idx, 2);
|
||||
CU_ASSERT_EQUAL(os_iterLength(iter), 5);
|
||||
CU_ASSERT_EQUAL(*(int32_t *)os_iterObject(iter, 0), 1);
|
||||
CU_ASSERT_EQUAL(*(int32_t *)os_iterObject(iter, 1), 4);
|
||||
CU_ASSERT_EQUAL(*(int32_t *)os_iterObject(iter, 2), 5);
|
||||
CU_ASSERT_EQUAL(*(int32_t *)os_iterObject(iter, 3), 2);
|
||||
CU_ASSERT_EQUAL(*(int32_t *)os_iterObject(iter, 4), 3);
|
||||
os_iterFree(iter, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
iter_free_callback(
|
||||
void *ptr)
|
||||
{
|
||||
(*(int32_t *)ptr)++;
|
||||
}
|
||||
|
||||
CUnit_Test(os_iter, free)
|
||||
{
|
||||
os_iter *iter;
|
||||
int32_t cnt = 0;
|
||||
|
||||
iter = os_iterNew();
|
||||
CU_ASSERT_PTR_NOT_NULL_FATAL(iter);
|
||||
(void)os_iterInsert(iter, &cnt, OS_ITER_LENGTH);
|
||||
(void)os_iterInsert(iter, &cnt, OS_ITER_LENGTH);
|
||||
(void)os_iterInsert(iter, &cnt, OS_ITER_LENGTH);
|
||||
os_iterFree(iter, &iter_free_callback);
|
||||
CU_ASSERT_EQUAL(cnt, 3);
|
||||
}
|
||||
|
||||
static void
|
||||
iter_walk_callback(
|
||||
void *ptr, void *arg)
|
||||
{
|
||||
(*(int32_t *)ptr)++;
|
||||
(*(int32_t *)arg)++;
|
||||
}
|
||||
|
||||
CUnit_Test(os_iter, walk)
|
||||
{
|
||||
os_iter *iter;
|
||||
int32_t cnt = 0;
|
||||
|
||||
iter = os_iterNew();
|
||||
CU_ASSERT_PTR_NOT_NULL_FATAL(iter);
|
||||
(void)os_iterInsert(iter, &cnt, OS_ITER_LENGTH);
|
||||
(void)os_iterInsert(iter, &cnt, OS_ITER_LENGTH);
|
||||
(void)os_iterInsert(iter, &cnt, OS_ITER_LENGTH);
|
||||
os_iterWalk(iter, &iter_walk_callback, &cnt);
|
||||
CU_ASSERT_EQUAL(cnt, 6);
|
||||
os_iterFree(iter, &iter_free_callback);
|
||||
CU_ASSERT_EQUAL(cnt, 9);
|
||||
}
|
||||
|
||||
static os_iter *
|
||||
iter_new(
|
||||
void)
|
||||
{
|
||||
os_iter *iter;
|
||||
int32_t idx;
|
||||
|
||||
iter = os_iterNew();
|
||||
CU_ASSERT_PTR_NOT_NULL_FATAL(iter);
|
||||
idx = os_iterInsert(iter, &one, OS_ITER_LENGTH);
|
||||
CU_ASSERT_EQUAL_FATAL(idx, 0);
|
||||
idx = os_iterInsert(iter, &two, OS_ITER_LENGTH);
|
||||
CU_ASSERT_EQUAL_FATAL(idx, 1);
|
||||
idx = os_iterInsert(iter, &three, OS_ITER_LENGTH);
|
||||
CU_ASSERT_EQUAL_FATAL(idx, 2);
|
||||
idx = os_iterInsert(iter, &four, OS_ITER_LENGTH);
|
||||
CU_ASSERT_EQUAL_FATAL(idx, 3);
|
||||
idx = os_iterInsert(iter, &five, OS_ITER_LENGTH);
|
||||
CU_ASSERT_EQUAL_FATAL(idx, 4);
|
||||
CU_ASSERT_EQUAL_FATAL(os_iterLength(iter), 5);
|
||||
|
||||
return iter;
|
||||
}
|
||||
|
||||
CUnit_Test(os_iter, object_indices)
|
||||
{
|
||||
os_iter *iter;
|
||||
int32_t *num;
|
||||
|
||||
iter = iter_new();
|
||||
|
||||
/* index out of range on purpose */
|
||||
OS_WARNING_MSVC_OFF(28020);
|
||||
num = os_iterObject(iter, OS_ITER_LENGTH);
|
||||
OS_WARNING_MSVC_ON(28020);
|
||||
|
||||
CU_ASSERT_PTR_NULL(num);
|
||||
num = os_iterObject(iter, os_iterLength(iter));
|
||||
CU_ASSERT_PTR_NULL(num);
|
||||
num = os_iterObject(iter, -6);
|
||||
CU_ASSERT_PTR_NULL(num);
|
||||
num = os_iterObject(iter, 0);
|
||||
CU_ASSERT_PTR_EQUAL(num, &one);
|
||||
num = os_iterObject(iter, -5);
|
||||
CU_ASSERT_PTR_EQUAL(num, &one);
|
||||
num = os_iterObject(iter, os_iterLength(iter) - 1);
|
||||
CU_ASSERT_PTR_EQUAL(num, &five);
|
||||
num = os_iterObject(iter, -1);
|
||||
CU_ASSERT_PTR_EQUAL(num, &five);
|
||||
num = os_iterObject(iter, 2);
|
||||
CU_ASSERT_PTR_EQUAL(num, &three);
|
||||
num = os_iterObject(iter, -3);
|
||||
CU_ASSERT_PTR_EQUAL(num, &three);
|
||||
os_iterFree(iter, NULL);
|
||||
}
|
||||
|
||||
CUnit_Test(os_iter, take_indices)
|
||||
{
|
||||
os_iter *iter;
|
||||
int32_t *num, cnt = 0;
|
||||
|
||||
iter = iter_new();
|
||||
|
||||
/* index out of range on purpose */
|
||||
OS_WARNING_MSVC_OFF(28020);
|
||||
num = os_iterTake(iter, OS_ITER_LENGTH);
|
||||
OS_WARNING_MSVC_ON(28020);
|
||||
CU_ASSERT_PTR_NULL(num);
|
||||
num = os_iterTake(iter, os_iterLength(iter));
|
||||
CU_ASSERT_PTR_NULL(num);
|
||||
num = os_iterTake(iter, -6);
|
||||
CU_ASSERT_PTR_NULL(num);
|
||||
num = os_iterTake(iter, -5);
|
||||
CU_ASSERT_PTR_EQUAL(num, &one);
|
||||
CU_ASSERT_EQUAL(os_iterLength(iter), 4);
|
||||
num = os_iterTake(iter, -3);
|
||||
CU_ASSERT_PTR_EQUAL(num, &three);
|
||||
CU_ASSERT_EQUAL(os_iterLength(iter), 3);
|
||||
num = os_iterTake(iter, -1);
|
||||
CU_ASSERT_PTR_EQUAL(num, &five);
|
||||
CU_ASSERT_EQUAL(os_iterLength(iter), 2);
|
||||
num = os_iterTake(iter, 1);
|
||||
CU_ASSERT_PTR_EQUAL(num, &four);
|
||||
CU_ASSERT_EQUAL(os_iterLength(iter), 1);
|
||||
num = os_iterTake(iter, 1);
|
||||
CU_ASSERT_PTR_NULL(num);
|
||||
num = os_iterTake(iter, -2);
|
||||
CU_ASSERT_PTR_NULL(num);
|
||||
num = os_iterTake(iter, -1);
|
||||
CU_ASSERT_PTR_EQUAL(num, &two);
|
||||
CU_ASSERT_EQUAL(os_iterLength(iter), 0);
|
||||
os_iterWalk(iter, &iter_walk_callback, &cnt);
|
||||
CU_ASSERT_EQUAL(cnt, 0);
|
||||
os_iterFree(iter, NULL);
|
||||
}
|
369
src/os/tests/mutex.c
Normal file
369
src/os/tests/mutex.c
Normal file
|
@ -0,0 +1,369 @@
|
|||
/*
|
||||
* Copyright(c) 2006 to 2018 ADLINK Technology Limited and others
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License v. 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
|
||||
* v. 1.0 which is available at
|
||||
* http://www.eclipse.org/org/documents/edl-v10.php.
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
|
||||
*/
|
||||
#include "CUnit/Runner.h"
|
||||
#include "os/os.h"
|
||||
|
||||
#ifdef __VXWORKS__
|
||||
# ifdef _WRS_KERNEL
|
||||
# define FORCE_SCHEDULING() taskDelay(1)
|
||||
# else
|
||||
# define FORCE_SCHEDULING() sched_yield()
|
||||
# endif
|
||||
#else
|
||||
# define FORCE_SCHEDULING()
|
||||
#endif
|
||||
|
||||
#define BUSYLOOP (100000)
|
||||
#define MAX_LOOPS (20)
|
||||
|
||||
typedef struct {
|
||||
os_mutex global_mutex;
|
||||
os_threadId global_data;
|
||||
int nolock_corrupt_count;
|
||||
int nolock_loop_count;
|
||||
int lock_corrupt_count;
|
||||
int lock_loop_count;
|
||||
int trylock_corrupt_count;
|
||||
int trylock_loop_count;
|
||||
int trylock_busy_count;
|
||||
int stop;
|
||||
} shared_data;
|
||||
|
||||
os_threadAttr mutex_os_threadAttr;
|
||||
os_threadId mutex_os_threadId[4];
|
||||
os_time delay1 = { 5, 0 };
|
||||
os_time pdelay = { 1, 0 };
|
||||
os_procId mutex_os_procId;
|
||||
os_procId mutex_os_procId1;
|
||||
os_procId mutex_os_procId2;
|
||||
char buffer[512];
|
||||
int supported_resultBusy;
|
||||
int loop;
|
||||
static shared_data *sd;
|
||||
char filePath[255];
|
||||
|
||||
uint32_t concurrent_lock_thread (_In_opt_ void *arg)
|
||||
{
|
||||
int j;
|
||||
int loopc = 0;
|
||||
int printed = 0;
|
||||
|
||||
while (!sd->stop)
|
||||
{
|
||||
if (arg) os_mutexLock (&sd->global_mutex);
|
||||
sd->global_data = os_threadIdSelf();
|
||||
|
||||
FORCE_SCHEDULING();
|
||||
|
||||
for (j = 0; j < BUSYLOOP; j++);
|
||||
if (os_threadIdToInteger(sd->global_data) !=
|
||||
os_threadIdToInteger(os_threadIdSelf()))
|
||||
{
|
||||
if (arg)
|
||||
{
|
||||
sd->lock_corrupt_count++;
|
||||
}
|
||||
else
|
||||
{
|
||||
sd->nolock_corrupt_count++;
|
||||
}
|
||||
if (!printed) {
|
||||
printed++;
|
||||
}
|
||||
}
|
||||
if (arg)
|
||||
{
|
||||
sd->lock_loop_count++;
|
||||
os_mutexUnlock (&sd->global_mutex);
|
||||
}
|
||||
else
|
||||
{
|
||||
sd->nolock_loop_count++;
|
||||
}
|
||||
|
||||
FORCE_SCHEDULING();
|
||||
|
||||
for (j = 0; j < BUSYLOOP; j++);
|
||||
loopc++;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32_t concurrent_trylock_thread (_In_opt_ void *arg)
|
||||
{
|
||||
int j;
|
||||
int loopc = 0;
|
||||
int printed = 0;
|
||||
os_result result;
|
||||
|
||||
while (!sd->stop)
|
||||
{
|
||||
if (arg)
|
||||
{
|
||||
while ((result = os_mutexTryLock (&sd->global_mutex))
|
||||
!= os_resultSuccess)
|
||||
{
|
||||
if (result == os_resultBusy)
|
||||
{
|
||||
sd->trylock_busy_count++;
|
||||
}
|
||||
FORCE_SCHEDULING();
|
||||
}
|
||||
}
|
||||
sd->global_data = os_threadIdSelf();
|
||||
|
||||
FORCE_SCHEDULING();
|
||||
|
||||
for (j = 0; j < BUSYLOOP; j++);
|
||||
if (os_threadIdToInteger(sd->global_data) !=
|
||||
os_threadIdToInteger(os_threadIdSelf()))
|
||||
{
|
||||
if (arg)
|
||||
{
|
||||
sd->trylock_corrupt_count++;
|
||||
}
|
||||
else
|
||||
{
|
||||
sd->nolock_corrupt_count++;
|
||||
}
|
||||
if (!printed) {
|
||||
printed++;
|
||||
}
|
||||
}
|
||||
if (arg)
|
||||
{
|
||||
sd->trylock_loop_count++;
|
||||
os_mutexUnlock (&sd->global_mutex);
|
||||
}
|
||||
else
|
||||
{
|
||||
sd->nolock_loop_count++;
|
||||
}
|
||||
|
||||
FORCE_SCHEDULING();
|
||||
|
||||
for (j = 0; j < BUSYLOOP; j++);
|
||||
loopc++;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
CUnit_Suite_Initialize(os_mutex)
|
||||
{
|
||||
printf ( "Run os_mutex_Initialize\n" );
|
||||
|
||||
os_osInit();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
CUnit_Suite_Cleanup(os_mutex)
|
||||
{
|
||||
printf("Run os_mutex_Cleanup\n");
|
||||
|
||||
os_osExit();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* This test only checks a single-threaded use-case; just API availability.*/
|
||||
CUnit_Test(os_mutex, basic)
|
||||
{
|
||||
os_mutex m;
|
||||
os_result r;
|
||||
|
||||
printf("Starting os_mutex_basic\n");
|
||||
|
||||
os_mutexInit(&m);
|
||||
os_mutexLock(&m);
|
||||
os_mutexUnlock(&m);
|
||||
r = os_mutexLock_s(&m);
|
||||
CU_ASSERT_EQUAL(r, os_resultSuccess); /* Failure can't be forced */
|
||||
os_mutexUnlock(&m);
|
||||
os_mutexDestroy(&m);
|
||||
printf("Ending os_mutex_basic\n");
|
||||
}
|
||||
|
||||
#define RUNTIME_SEC (4)
|
||||
#define NUM_THREADS (8)
|
||||
#define OS_STRESS_STOP (0)
|
||||
#define OS_STRESS_GO (1)
|
||||
#define THREAD_NAME_LEN (8)
|
||||
|
||||
struct os_mutex_stress {
|
||||
os_threadId tid;
|
||||
os_mutex m;
|
||||
os_atomic_uint32_t * flag;
|
||||
char name[THREAD_NAME_LEN];
|
||||
};
|
||||
|
||||
static uint32_t
|
||||
os_mutex_init_thr(
|
||||
void *args)
|
||||
{
|
||||
struct os_mutex_stress *state = (struct os_mutex_stress *)args;
|
||||
os_result r;
|
||||
uint32_t iterations = 0;
|
||||
|
||||
do {
|
||||
os_mutexInit(&state->m);
|
||||
r = os_mutexLock_s(&state->m); /* Use the mutex to check that all is OK. */
|
||||
CU_ASSERT_EQUAL(r, os_resultSuccess); /* Failure can't be forced. */
|
||||
os_mutexUnlock(&state->m);
|
||||
os_mutexDestroy(&state->m);
|
||||
iterations++;
|
||||
} while ( os_atomic_ld32(state->flag) != OS_STRESS_STOP && r == os_resultSuccess);
|
||||
|
||||
printf("%s <%"PRIxMAX">: Performed %u iterations. Stopping now.\n", state->name, os_threadIdToInteger(os_threadIdSelf()), iterations);
|
||||
return r != os_resultSuccess; /* Return true on faulure */
|
||||
}
|
||||
|
||||
CUnit_Test(os_mutex, init_stress)
|
||||
{
|
||||
struct os_mutex_stress threads[NUM_THREADS];
|
||||
os_threadAttr tattr;
|
||||
unsigned i;
|
||||
os_atomic_uint32_t flag = OS_ATOMIC_UINT32_INIT(OS_STRESS_GO);
|
||||
os_time runtime = { .tv_sec = RUNTIME_SEC, .tv_nsec = 0 };
|
||||
|
||||
printf("Starting os_mutex_init_stress\n");
|
||||
|
||||
os_threadAttrInit(&tattr);
|
||||
for ( i = 0; i < NUM_THREADS; i++ ) {
|
||||
(void) snprintf(&threads[i].name[0], THREAD_NAME_LEN, "thr%u", i);
|
||||
threads[i].flag = &flag;
|
||||
os_threadCreate(&threads[i].tid, threads[i].name, &tattr, &os_mutex_init_thr, &threads[i]);
|
||||
printf("main <%"PRIxMAX">: Started thread '%s' with thread-id %" PRIxMAX "\n", os_threadIdToInteger(os_threadIdSelf()), threads[i].name, os_threadIdToInteger(threads[i].tid));
|
||||
}
|
||||
|
||||
printf("main <%"PRIxMAX">: Test will run for ~%ds with %d threads\n", os_threadIdToInteger(os_threadIdSelf()), RUNTIME_SEC, NUM_THREADS);
|
||||
os_nanoSleep(runtime);
|
||||
os_atomic_st32(&flag, OS_STRESS_STOP);
|
||||
|
||||
for ( ; i != 0; i-- ) {
|
||||
uint32_t thread_failed;
|
||||
os_threadWaitExit(threads[i - 1].tid, &thread_failed);
|
||||
printf("main <%"PRIxMAX">: Thread %s <%" PRIxMAX "> stopped with result %s.\n", os_threadIdToInteger(os_threadIdSelf()), threads[i - 1].name, os_threadIdToInteger(threads[i - 1].tid), thread_failed ? "FAILED" : "PASS");
|
||||
|
||||
CU_ASSERT_FALSE(thread_failed);
|
||||
}
|
||||
printf("Ending os_mutex_init_stress\n");
|
||||
}
|
||||
|
||||
CUnit_Test(os_mutex, lock, false)
|
||||
{
|
||||
/* Test critical section access with locking and PRIVATE scope */
|
||||
printf ("Starting tc_os_mutex_lock_001\n");
|
||||
os_threadAttrInit (&mutex_os_threadAttr);
|
||||
|
||||
FORCE_SCHEDULING();
|
||||
|
||||
delay1.tv_sec = 3;
|
||||
printf ("Testing for %d.%9.9d seconds without lock\n", delay1.tv_sec, delay1.tv_nsec);
|
||||
sd->stop = 0;
|
||||
sd->nolock_corrupt_count = 0;
|
||||
sd->nolock_loop_count = 0;
|
||||
sd->lock_corrupt_count = 0;
|
||||
sd->lock_loop_count = 0;
|
||||
sd->trylock_corrupt_count = 0;
|
||||
sd->trylock_loop_count = 0;
|
||||
sd->trylock_busy_count = 0;
|
||||
os_threadCreate (&mutex_os_threadId[0], "thr0", &mutex_os_threadAttr, &concurrent_lock_thread, NULL);
|
||||
os_threadCreate (&mutex_os_threadId[1], "thr1", &mutex_os_threadAttr, &concurrent_lock_thread, NULL);
|
||||
os_threadCreate (&mutex_os_threadId[2], "thr2", &mutex_os_threadAttr, &concurrent_trylock_thread, NULL);
|
||||
os_threadCreate (&mutex_os_threadId[3], "thr3", &mutex_os_threadAttr, &concurrent_trylock_thread, NULL);
|
||||
os_nanoSleep (delay1);
|
||||
sd->stop = 1;
|
||||
os_threadWaitExit (mutex_os_threadId[0], NULL);
|
||||
os_threadWaitExit (mutex_os_threadId[1], NULL);
|
||||
os_threadWaitExit (mutex_os_threadId[2], NULL);
|
||||
os_threadWaitExit (mutex_os_threadId[3], NULL);
|
||||
printf ("All threads stopped\n");
|
||||
|
||||
delay1.tv_sec = 3;
|
||||
printf ("Testing for %d.%9.9d seconds with lock\n", delay1.tv_sec, delay1.tv_nsec);
|
||||
sd->stop = 0;
|
||||
sd->nolock_corrupt_count = 0;
|
||||
sd->nolock_loop_count = 0;
|
||||
sd->lock_corrupt_count = 0;
|
||||
sd->lock_loop_count = 0;
|
||||
sd->trylock_corrupt_count = 0;
|
||||
sd->trylock_loop_count = 0;
|
||||
sd->trylock_busy_count = 0;
|
||||
os_threadCreate (&mutex_os_threadId[0], "thr0", &mutex_os_threadAttr, &concurrent_lock_thread, (void *)1);
|
||||
os_threadCreate (&mutex_os_threadId[1], "thr1", &mutex_os_threadAttr, &concurrent_lock_thread, (void *)1);
|
||||
os_threadCreate (&mutex_os_threadId[2], "thr2", &mutex_os_threadAttr, &concurrent_trylock_thread, (void *)1);
|
||||
os_threadCreate (&mutex_os_threadId[3], "thr3", &mutex_os_threadAttr, &concurrent_trylock_thread, (void *)1);
|
||||
os_nanoSleep (delay1);
|
||||
sd->stop = 1;
|
||||
os_threadWaitExit (mutex_os_threadId[0], NULL);
|
||||
os_threadWaitExit (mutex_os_threadId[1], NULL);
|
||||
os_threadWaitExit (mutex_os_threadId[2], NULL);
|
||||
os_threadWaitExit (mutex_os_threadId[3], NULL);
|
||||
printf ("All threads stopped\n");
|
||||
|
||||
CU_ASSERT (sd->lock_corrupt_count == 0 || sd->lock_loop_count > 0);
|
||||
|
||||
/* Lock mutex with PRIVATE scope and Success result */
|
||||
printf ("Starting tc_os_mutex_lock_002\n");
|
||||
os_mutexLock (&sd->global_mutex); //Cannot be checked
|
||||
os_mutexUnlock (&sd->global_mutex);
|
||||
|
||||
/* Lock mutex with PRIVATE scope and Fail result */
|
||||
printf ("Starting tc_os_mutex_lock_003\n");
|
||||
printf ("N.A - Failure cannot be forced\n");
|
||||
|
||||
/* mutexLock_s with PRIVATE scope and Success result */
|
||||
printf ("Starting tc_os_mutex_lock_004\n");
|
||||
CU_ASSERT (os_mutexLock_s (&sd->global_mutex) == os_resultSuccess);
|
||||
os_mutexUnlock (&sd->global_mutex);
|
||||
|
||||
printf ("Ending os_mutex_lock\n");
|
||||
}
|
||||
|
||||
CUnit_Test(os_mutex, trylock, false)
|
||||
{
|
||||
os_result result;
|
||||
|
||||
/* Test critical section access with trylocking and PRIVATE scope */
|
||||
printf ("Starting os_mutex_trylock_001\n");
|
||||
CU_ASSERT (sd->trylock_corrupt_count == 0 || sd->trylock_loop_count > 0);
|
||||
|
||||
/* TryLock mutex with PRIVATE scope and Success result */
|
||||
printf ("Starting os_mutex_trylock_002\n");
|
||||
result = os_mutexTryLock (&sd->global_mutex);
|
||||
CU_ASSERT (result == os_resultSuccess);
|
||||
|
||||
/* TryLock mutex with PRIVATE scope and Busy result */
|
||||
printf ("Starting os_mutex_trylock_003\n");
|
||||
#if defined(__VXWORKS__) && !defined(_WRS_KERNEL)
|
||||
printf ("N.A - Mutexes are recursive on VxWorks RTP so this test is disabled\n");
|
||||
#endif
|
||||
|
||||
result = os_mutexTryLock (&sd->global_mutex);
|
||||
CU_ASSERT (result == os_resultBusy);
|
||||
|
||||
printf ("Ending os_mutex_trylock\n");
|
||||
}
|
||||
|
||||
CUnit_Test(os_mutex, destroy, false)
|
||||
{
|
||||
/* Deinitialize mutex with PRIVATE scope and Success result */
|
||||
printf ("Starting os_mutex_destroy_001\n");
|
||||
os_mutexDestroy(&sd->global_mutex); // Cannot be checked directly - Success is assumed
|
||||
|
||||
/* Deinitialize mutex with PRIVATE scope and Fail result */
|
||||
printf ("Starting os_mutex_destroy_002\n");
|
||||
printf ("N.A - Failure cannot be forced\n");
|
||||
|
||||
printf ("Ending os_mutex_destroy\n");
|
||||
}
|
167
src/os/tests/once.c
Normal file
167
src/os/tests/once.c
Normal file
|
@ -0,0 +1,167 @@
|
|||
/*
|
||||
* Copyright(c) 2006 to 2018 ADLINK Technology Limited and others
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License v. 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
|
||||
* v. 1.0 which is available at
|
||||
* http://www.eclipse.org/org/documents/edl-v10.php.
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
|
||||
*/
|
||||
#include "CUnit/Runner.h"
|
||||
#include "os/os.h"
|
||||
|
||||
/* Suite os_once*/
|
||||
CUnit_Suite_Initialize(os_once)
|
||||
{
|
||||
printf("Run os_once_Initialize\n");
|
||||
|
||||
os_osInit();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
CUnit_Suite_Cleanup(os_once)
|
||||
{
|
||||
printf("Run os_once_Cleanup\n");
|
||||
|
||||
os_osExit();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static uint32_t counter;
|
||||
|
||||
static void once_func(void)
|
||||
{
|
||||
counter++;
|
||||
printf("Counter increased to %u\n", counter);
|
||||
}
|
||||
|
||||
/* This test only checks a single-threaded use-case; mostly API availability and mere basics.*/
|
||||
CUnit_Test(os_once, basic)
|
||||
{
|
||||
static os_once_t init = OS_ONCE_T_STATIC_INIT;
|
||||
|
||||
printf("Starting os_once_basic\n");
|
||||
|
||||
os_once(&init, &once_func);
|
||||
CU_ASSERT(counter == 1);
|
||||
os_once(&init, &once_func);
|
||||
CU_ASSERT(counter == 1);
|
||||
|
||||
printf("Ending os_once_basic\n");
|
||||
}
|
||||
|
||||
/* Update atomically, so that a failing os_once can be detected and isn't potentially lost due to a race. */
|
||||
static os_atomic_uint32_t counter1 = OS_ATOMIC_UINT32_INIT(0);
|
||||
static void once1_func(void)
|
||||
{
|
||||
os_time delay = { .tv_sec = 0,.tv_nsec = 250000000 }; /* 250ms */
|
||||
os_nanoSleep(delay);
|
||||
printf("%"PRIxMAX": Counter 1 increased to %u\n", os_threadIdToInteger(os_threadIdSelf()), os_atomic_inc32_nv(&counter1));
|
||||
}
|
||||
|
||||
/* Update atomically, so that a failing os_once can be detected and isn't potentially lost due to a race. */
|
||||
static os_atomic_uint32_t counter2 = OS_ATOMIC_UINT32_INIT(0);
|
||||
static void once2_func(void)
|
||||
{
|
||||
os_time delay = { .tv_sec = 0, .tv_nsec = 500000000 }; /* 500ms */
|
||||
os_nanoSleep(delay);
|
||||
printf("%"PRIxMAX": Counter 2 increased to %u\n", os_threadIdToInteger(os_threadIdSelf()), os_atomic_inc32_nv(&counter2));
|
||||
}
|
||||
|
||||
#define OS_ONCE_NUM_THREADS (20)
|
||||
#define OS_ONCE_STATE_STARTUP (0)
|
||||
#define OS_ONCE_STATE_GO (1)
|
||||
|
||||
struct os_once_parallel {
|
||||
os_mutex m;
|
||||
os_cond c;
|
||||
os_atomic_uint32_t flag;
|
||||
os_atomic_uint32_t started;
|
||||
os_once_t init1;
|
||||
os_once_t init2;
|
||||
};
|
||||
|
||||
static uint32_t
|
||||
os_once_parallel_thr(
|
||||
void *args)
|
||||
{
|
||||
const os_time sched_delay = { .tv_sec = 0,.tv_nsec = 25000000 }; /* 25ms */
|
||||
const os_time poll_delay = { .tv_sec = 0,.tv_nsec = 5000000 }; /* 5ms */
|
||||
struct os_once_parallel *state = (struct os_once_parallel *)args;
|
||||
bool done = false;
|
||||
bool started = false;
|
||||
|
||||
while (!done) {
|
||||
switch (os_atomic_ld32(&state->flag)) {
|
||||
case OS_ONCE_STATE_STARTUP:
|
||||
if (!started && (os_atomic_inc32_nv(&state->started) == OS_ONCE_NUM_THREADS)) {
|
||||
printf("%"PRIxMAX": Started. Signalling GO.\n", os_threadIdToInteger(os_threadIdSelf()));
|
||||
os_atomic_st32(&state->flag, OS_ONCE_STATE_GO);
|
||||
os_mutexLock(&state->m);
|
||||
os_condBroadcast(&state->c);
|
||||
os_mutexUnlock(&state->m);
|
||||
os_nanoSleep(sched_delay);
|
||||
}
|
||||
else {
|
||||
if(!started ) printf("%"PRIxMAX": Started. Awaiting GO.\n", os_threadIdToInteger(os_threadIdSelf()));
|
||||
os_mutexLock(&state->m);
|
||||
(void) os_condTimedWait(&state->c, &state->m, &poll_delay);
|
||||
os_mutexUnlock(&state->m);
|
||||
}
|
||||
started = true;
|
||||
break;
|
||||
case OS_ONCE_STATE_GO:
|
||||
os_once(&state->init1, &once1_func);
|
||||
os_once(&state->init2, &once2_func);
|
||||
/* Fallthrough intentional */
|
||||
default:
|
||||
done = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
CUnit_Test(os_once, parallel)
|
||||
{
|
||||
os_threadId threads[OS_ONCE_NUM_THREADS];
|
||||
struct os_once_parallel state = {
|
||||
.init1 = OS_ONCE_T_STATIC_INIT,
|
||||
.init2 = OS_ONCE_T_STATIC_INIT,
|
||||
.started = OS_ATOMIC_UINT32_INIT(0),
|
||||
.flag = OS_ATOMIC_UINT32_INIT(OS_ONCE_STATE_STARTUP)
|
||||
};
|
||||
os_threadAttr tattr;
|
||||
unsigned i;
|
||||
|
||||
printf("Starting os_once_parallel\n");
|
||||
|
||||
os_mutexInit(&state.m);
|
||||
os_condInit(&state.c, &state.m);
|
||||
|
||||
os_threadAttrInit(&tattr);
|
||||
for (i = 0; i < OS_ONCE_NUM_THREADS; i++) {
|
||||
char thrname[16];
|
||||
(void) snprintf(thrname, sizeof thrname, "thr%u", i);
|
||||
os_threadCreate(&threads[i], thrname, &tattr, &os_once_parallel_thr, &state);
|
||||
printf("%"PRIxMAX": Started thread '%s' with thread-id %" PRIxMAX "\n", os_threadIdToInteger(os_threadIdSelf()), thrname, os_threadIdToInteger(threads[i]));
|
||||
}
|
||||
|
||||
for (; i != 0; i--) {
|
||||
os_threadWaitExit(threads[i - 1], NULL);
|
||||
printf("%"PRIxMAX": Thread with thread-id %" PRIxMAX " stopped.\n", os_threadIdToInteger(os_threadIdSelf()), os_threadIdToInteger(threads[i - 1]));
|
||||
}
|
||||
|
||||
CU_ASSERT(os_atomic_ld32(&counter1) == 1);
|
||||
CU_ASSERT(os_atomic_ld32(&counter2) == 1);
|
||||
|
||||
os_condDestroy(&state.c);
|
||||
os_mutexDestroy(&state.m);
|
||||
|
||||
printf("Ending os_once_parallel\n");
|
||||
}
|
404
src/os/tests/report.c
Normal file
404
src/os/tests/report.c
Normal file
|
@ -0,0 +1,404 @@
|
|||
/*
|
||||
* Copyright(c) 2006 to 2018 ADLINK Technology Limited and others
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License v. 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
|
||||
* v. 1.0 which is available at
|
||||
* http://www.eclipse.org/org/documents/edl-v10.php.
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
|
||||
*/
|
||||
#include "CUnit/Runner.h"
|
||||
#include "os/os.h"
|
||||
#include "os/os_project.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
CUnit_Suite_Initialize(os_report)
|
||||
{
|
||||
os_putenv(OS_PROJECT_NAME_NOSPACE_CAPS"_ERRORFILE=vdds_test_error");
|
||||
os_putenv(OS_PROJECT_NAME_NOSPACE_CAPS"_INFOFILE=vdds_test_info");
|
||||
os_putenv(OS_PROJECT_NAME_NOSPACE_CAPS"_LOGAPPEND=TRUE");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void remove_logs()
|
||||
{
|
||||
const char * error_file_name = os_getenv(OS_PROJECT_NAME_NOSPACE_CAPS"_ERRORFILE");
|
||||
const char * info_file_name = os_getenv(OS_PROJECT_NAME_NOSPACE_CAPS"_INFOFILE");
|
||||
|
||||
os_remove(error_file_name);
|
||||
os_remove(info_file_name);
|
||||
}
|
||||
|
||||
void check_existence(os_result error_log_existence, os_result info_log_existence)
|
||||
{
|
||||
const char * error_file_name = os_getenv(OS_PROJECT_NAME_NOSPACE_CAPS"_ERRORFILE");
|
||||
const char * info_file_name = os_getenv(OS_PROJECT_NAME_NOSPACE_CAPS"_INFOFILE");
|
||||
|
||||
CU_ASSERT(os_access(error_file_name, OS_ROK) == error_log_existence);
|
||||
CU_ASSERT(os_access(info_file_name, OS_ROK) == info_log_existence);
|
||||
}
|
||||
|
||||
CUnit_Suite_Cleanup(os_report)
|
||||
{
|
||||
remove_logs();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
CUnit_Test(os_report, re_init)
|
||||
{
|
||||
os_reportInit(true);
|
||||
|
||||
OS_INFO(OS_FUNCTION, 0, "os_report-info-test %d", __LINE__);
|
||||
OS_ERROR(OS_FUNCTION, 0, "os_report-error-test %d", __LINE__);
|
||||
|
||||
check_existence(os_resultSuccess, os_resultSuccess);
|
||||
|
||||
os_reportExit();
|
||||
|
||||
os_reportInit(true);
|
||||
check_existence(os_resultSuccess, os_resultSuccess);
|
||||
|
||||
OS_INFO(OS_FUNCTION, 0, "os_report-info-test %d", __LINE__);
|
||||
|
||||
os_reportExit();
|
||||
|
||||
remove_logs();
|
||||
}
|
||||
|
||||
|
||||
CUnit_Test(os_report, stack_critical)
|
||||
{
|
||||
os_reportInit(true);
|
||||
|
||||
OS_REPORT_STACK();
|
||||
|
||||
OS_CRITICAL(OS_FUNCTION, 0, "os_report-error-test %d", __LINE__);
|
||||
|
||||
check_existence(os_resultFail, os_resultFail);
|
||||
|
||||
OS_REPORT_FLUSH(false);
|
||||
|
||||
// Since a critical is logged, the error log should be created
|
||||
check_existence(os_resultSuccess, os_resultFail);
|
||||
|
||||
os_reportExit();
|
||||
|
||||
remove_logs();
|
||||
}
|
||||
|
||||
|
||||
CUnit_Test(os_report, stack_non_critical)
|
||||
{
|
||||
os_reportInit(true);
|
||||
|
||||
OS_REPORT_STACK();
|
||||
|
||||
OS_ERROR(OS_FUNCTION, 0, "os_report-error-test %d", __LINE__);
|
||||
|
||||
check_existence(os_resultFail, os_resultFail);
|
||||
|
||||
OS_REPORT_FLUSH(false);
|
||||
|
||||
// Since a non critical is logged, the error log should not be created
|
||||
check_existence(os_resultFail, os_resultFail);
|
||||
|
||||
os_reportExit();
|
||||
|
||||
remove_logs();
|
||||
}
|
||||
|
||||
|
||||
CUnit_Test(os_report, error_file_creation_critical)
|
||||
{
|
||||
os_reportInit(true);
|
||||
|
||||
OS_CRITICAL(OS_FUNCTION, 0, "os_report-critical-test %d", __LINE__);
|
||||
|
||||
check_existence(os_resultSuccess, os_resultFail);
|
||||
|
||||
os_reportExit();
|
||||
|
||||
remove_logs();
|
||||
}
|
||||
|
||||
|
||||
CUnit_Test(os_report, error_file_creation_fatal)
|
||||
{
|
||||
os_reportInit(true);
|
||||
|
||||
OS_FATAL(OS_FUNCTION, 0, "os_report-fatal-test %d", __LINE__);
|
||||
|
||||
check_existence(os_resultSuccess, os_resultFail);
|
||||
|
||||
os_reportExit();
|
||||
|
||||
remove_logs();
|
||||
}
|
||||
|
||||
|
||||
CUnit_Test(os_report, info_file_creation_warning)
|
||||
{
|
||||
os_reportInit(true);
|
||||
|
||||
OS_WARNING(OS_FUNCTION, 0, "os_report-warning-test %d", __LINE__);
|
||||
|
||||
check_existence(os_resultFail, os_resultSuccess);
|
||||
|
||||
os_reportExit();
|
||||
|
||||
remove_logs();
|
||||
}
|
||||
|
||||
|
||||
CUnit_Test(os_report, info_file_creation_info)
|
||||
{
|
||||
os_reportInit(true);
|
||||
|
||||
OS_INFO(OS_FUNCTION, 0, "os_report-info-test %d", __LINE__);
|
||||
|
||||
check_existence(os_resultFail, os_resultSuccess);
|
||||
|
||||
os_reportExit();
|
||||
|
||||
remove_logs();
|
||||
}
|
||||
|
||||
|
||||
CUnit_Test(os_report, verbosity_low)
|
||||
{
|
||||
os_reportInit(true);
|
||||
check_existence(os_resultFail, os_resultFail);
|
||||
|
||||
os_reportVerbosity = OS_REPORT_ERROR;
|
||||
|
||||
OS_WARNING(OS_FUNCTION, 0, "os_report-info-test %d", __LINE__);
|
||||
|
||||
check_existence(os_resultFail, os_resultFail);
|
||||
|
||||
os_reportExit();
|
||||
|
||||
remove_logs();
|
||||
}
|
||||
|
||||
|
||||
CUnit_Test(os_report, verbosity_high)
|
||||
{
|
||||
os_reportInit(true);
|
||||
check_existence(os_resultFail, os_resultFail);
|
||||
|
||||
os_reportVerbosity = OS_REPORT_DEBUG;
|
||||
|
||||
OS_WARNING(OS_FUNCTION, 0, "os_report-info-test %d", __LINE__);
|
||||
|
||||
check_existence(os_resultFail, os_resultSuccess);
|
||||
|
||||
os_reportExit();
|
||||
|
||||
remove_logs();
|
||||
}
|
||||
|
||||
|
||||
|
||||
CUnit_Test(os_report, verbosity_equal)
|
||||
{
|
||||
os_reportInit(true);
|
||||
check_existence(os_resultFail, os_resultFail);
|
||||
|
||||
os_reportVerbosity = OS_REPORT_WARNING;
|
||||
|
||||
OS_WARNING(OS_FUNCTION, 0, "os_report-info-test %d", __LINE__);
|
||||
|
||||
check_existence(os_resultFail, os_resultSuccess);
|
||||
|
||||
os_reportExit();
|
||||
|
||||
remove_logs();
|
||||
}
|
||||
|
||||
|
||||
CUnit_Test(os_report, stack_verbosity_low)
|
||||
{
|
||||
os_reportInit(true);
|
||||
check_existence(os_resultFail, os_resultFail);
|
||||
|
||||
os_reportVerbosity = OS_REPORT_ERROR;
|
||||
|
||||
OS_REPORT_STACK();
|
||||
OS_WARNING(OS_FUNCTION, 0, "os_report-info-test %d", __LINE__);
|
||||
OS_REPORT_FLUSH(true);
|
||||
|
||||
check_existence(os_resultFail, os_resultFail);
|
||||
|
||||
os_reportExit();
|
||||
|
||||
remove_logs();
|
||||
}
|
||||
|
||||
|
||||
CUnit_Test(os_report, stack_verbosity_high)
|
||||
{
|
||||
os_reportInit(true);
|
||||
check_existence(os_resultFail, os_resultFail);
|
||||
|
||||
os_reportVerbosity = OS_REPORT_DEBUG;
|
||||
|
||||
OS_REPORT_STACK();
|
||||
OS_WARNING(OS_FUNCTION, 0, "os_report-info-test %d", __LINE__);
|
||||
OS_REPORT_FLUSH(true);
|
||||
|
||||
check_existence(os_resultFail, os_resultSuccess);
|
||||
|
||||
os_reportExit();
|
||||
|
||||
remove_logs();
|
||||
}
|
||||
|
||||
|
||||
|
||||
CUnit_Test(os_report, stack_verbosity_equal)
|
||||
{
|
||||
os_reportInit(true);
|
||||
check_existence(os_resultFail, os_resultFail);
|
||||
|
||||
os_reportVerbosity = OS_REPORT_WARNING;
|
||||
|
||||
OS_REPORT_STACK();
|
||||
OS_WARNING(OS_FUNCTION, 0, "os_report-info-test %d", __LINE__);
|
||||
OS_REPORT_FLUSH(true);
|
||||
|
||||
check_existence(os_resultFail, os_resultSuccess);
|
||||
|
||||
os_reportExit();
|
||||
|
||||
remove_logs();
|
||||
}
|
||||
|
||||
|
||||
CUnit_Test(os_report, no_log_append)
|
||||
{
|
||||
os_reportInit(true);
|
||||
check_existence(os_resultFail, os_resultFail);
|
||||
|
||||
OS_ERROR(OS_FUNCTION, 0, "os_report-error-test %d", __LINE__);
|
||||
OS_INFO(OS_FUNCTION, 0, "os_report-info-test %d", __LINE__);
|
||||
|
||||
check_existence(os_resultSuccess, os_resultSuccess);
|
||||
|
||||
os_reportExit();
|
||||
|
||||
os_putenv(OS_PROJECT_NAME_NOSPACE_CAPS"_LOGAPPEND=FALSE");
|
||||
|
||||
os_reportInit(true);
|
||||
|
||||
// Both logs should be deleted
|
||||
check_existence(os_resultFail, os_resultFail);
|
||||
|
||||
os_reportExit();
|
||||
|
||||
remove_logs();
|
||||
}
|
||||
|
||||
|
||||
CUnit_Test(os_report, log_dir)
|
||||
{
|
||||
os_putenv(OS_PROJECT_NAME_NOSPACE_CAPS"_LOGPATH=.");
|
||||
|
||||
os_reportInit(true);
|
||||
|
||||
check_existence(os_resultFail, os_resultFail);
|
||||
|
||||
OS_ERROR(OS_FUNCTION, 0, "os_report-error-test %d", __LINE__);
|
||||
OS_INFO(OS_FUNCTION, 0, "os_report-info-test %d", __LINE__);
|
||||
|
||||
check_existence(os_resultSuccess, os_resultSuccess);
|
||||
|
||||
os_reportExit();
|
||||
|
||||
remove_logs();
|
||||
}
|
||||
|
||||
|
||||
CUnit_Test(os_report, verbosity_env_value_info)
|
||||
{
|
||||
os_putenv(OS_PROJECT_NAME_NOSPACE_CAPS"_VERBOSITY=0");
|
||||
os_reportInit(true);
|
||||
check_existence(os_resultFail, os_resultFail);
|
||||
|
||||
OS_ERROR(OS_FUNCTION, 0, "os_report-error-test %d", __LINE__);
|
||||
OS_INFO(OS_FUNCTION, 0, "os_report-info-test %d", __LINE__);
|
||||
|
||||
check_existence(os_resultSuccess, os_resultSuccess);
|
||||
|
||||
os_reportExit();
|
||||
|
||||
remove_logs();
|
||||
|
||||
//reset for other tests.
|
||||
os_putenv(OS_PROJECT_NAME_NOSPACE_CAPS"_VERBOSITY=");
|
||||
}
|
||||
|
||||
|
||||
CUnit_Test(os_report, verbosity_env_value_error)
|
||||
{
|
||||
os_putenv(OS_PROJECT_NAME_NOSPACE_CAPS"_VERBOSITY=3");
|
||||
os_reportInit(true);
|
||||
check_existence(os_resultFail, os_resultFail);
|
||||
|
||||
OS_ERROR(OS_FUNCTION, 0, "os_report-error-test %d", __LINE__);
|
||||
OS_INFO(OS_FUNCTION, 0, "os_report-info-test %d", __LINE__);
|
||||
|
||||
check_existence(os_resultSuccess, os_resultFail);
|
||||
|
||||
os_reportExit();
|
||||
|
||||
remove_logs();
|
||||
|
||||
//reset for other tests.
|
||||
os_putenv(OS_PROJECT_NAME_NOSPACE_CAPS"_VERBOSITY=");
|
||||
}
|
||||
|
||||
|
||||
CUnit_Test(os_report, verbosity_env_value_error_as_string)
|
||||
{
|
||||
os_putenv(OS_PROJECT_NAME_NOSPACE_CAPS"_VERBOSITY=ERROR");
|
||||
os_reportInit(true);
|
||||
check_existence(os_resultFail, os_resultFail);
|
||||
|
||||
OS_ERROR(OS_FUNCTION, 0, "os_report-error-test %d", __LINE__);
|
||||
OS_DEBUG(OS_FUNCTION, 0, "os_report-info-test %d", __LINE__);
|
||||
|
||||
check_existence(os_resultSuccess, os_resultFail);
|
||||
|
||||
os_reportExit();
|
||||
|
||||
remove_logs();
|
||||
|
||||
//reset for other tests.
|
||||
os_putenv(OS_PROJECT_NAME_NOSPACE_CAPS"_VERBOSITY=");
|
||||
}
|
||||
|
||||
|
||||
CUnit_Test(os_report, verbosity_wrong_env_value)
|
||||
{
|
||||
os_putenv(OS_PROJECT_NAME_NOSPACE_CAPS"_VERBOSITY=WRONG");
|
||||
os_reportInit(true);
|
||||
check_existence(os_resultFail, os_resultFail);
|
||||
|
||||
OS_ERROR(OS_FUNCTION, 0, "os_report-error-test %d", __LINE__);
|
||||
OS_DEBUG(OS_FUNCTION, 0, "os_report-error-test %d", __LINE__);
|
||||
|
||||
check_existence(os_resultSuccess, os_resultFail);
|
||||
|
||||
os_reportExit();
|
||||
|
||||
remove_logs();
|
||||
|
||||
//reset for other tests.
|
||||
os_putenv(OS_PROJECT_NAME_NOSPACE_CAPS"_VERBOSITY=");
|
||||
}
|
577
src/os/tests/rwlock.c
Normal file
577
src/os/tests/rwlock.c
Normal file
|
@ -0,0 +1,577 @@
|
|||
/*
|
||||
* Copyright(c) 2006 to 2018 ADLINK Technology Limited and others
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License v. 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
|
||||
* v. 1.0 which is available at
|
||||
* http://www.eclipse.org/org/documents/edl-v10.php.
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
|
||||
*/
|
||||
#include "CUnit/Runner.h"
|
||||
#include "os/os.h"
|
||||
|
||||
#ifdef __VXWORKS__
|
||||
# ifdef _WRS_KERNEL
|
||||
# define FORCE_SCHEDULING() taskDelay(1)
|
||||
# else
|
||||
# define FORCE_SCHEDULING() sched_yield()
|
||||
# endif
|
||||
#else
|
||||
# define FORCE_SCHEDULING()
|
||||
#endif
|
||||
|
||||
#define ENABLE_TRACING 0
|
||||
#define BUSYLOOP (100000)
|
||||
#define MAX_LOOPS (20)
|
||||
#define RWLOCK_THREADS 12
|
||||
|
||||
os_time rwlock_delay = { 0, 500 };
|
||||
|
||||
typedef struct Par {
|
||||
int lock;
|
||||
int index;
|
||||
int read_access;
|
||||
int concurrent_read_access;
|
||||
} Par;
|
||||
|
||||
typedef struct {
|
||||
os_rwlock global_rwlock;
|
||||
os_threadId global_data;
|
||||
os_threadId read_thread[RWLOCK_THREADS];
|
||||
int read_corrupt_count;
|
||||
int write_corrupt_count;
|
||||
int concurrent_read_access;
|
||||
int concurrent_write_access;
|
||||
int tryread_corrupt_count;
|
||||
int trywrite_corrupt_count;
|
||||
int concurrent_tryread_access;
|
||||
int concurrent_trywrite_access;
|
||||
int tryread_busy_count;
|
||||
int trywrite_busy_count;
|
||||
int stop;
|
||||
} shared_data;
|
||||
|
||||
os_threadAttr rwlock_os_threadAttr;
|
||||
os_threadId rwlock_os_threadId[RWLOCK_THREADS];
|
||||
static int i;
|
||||
char buffer[512];
|
||||
os_procId rwlock_os_procId;
|
||||
int supported_resultBusy;
|
||||
int loop;
|
||||
static shared_data sd;
|
||||
|
||||
uint32_t concurrent_write_thread (_In_ void *arg)
|
||||
{
|
||||
struct Par *par = (struct Par *)arg;
|
||||
os_threadId myid = os_threadIdSelf();
|
||||
int printed = 0;
|
||||
|
||||
while (!sd.stop) {
|
||||
if (par->lock) {
|
||||
os_rwlockWrite (&sd.global_rwlock);
|
||||
}
|
||||
sd.global_data = myid;
|
||||
|
||||
FORCE_SCHEDULING();
|
||||
|
||||
os_nanoSleep( rwlock_delay );
|
||||
if (os_threadIdToInteger(sd.global_data) != os_threadIdToInteger(myid)) {
|
||||
sd.write_corrupt_count++;
|
||||
if (!printed) {
|
||||
/* printf ("Critical section corrupted during write [%d]\n", par->index); */
|
||||
printed++;
|
||||
}
|
||||
}
|
||||
sd.concurrent_write_access++;
|
||||
if (par->lock) {
|
||||
os_rwlockUnlock (&sd.global_rwlock);
|
||||
}
|
||||
|
||||
FORCE_SCHEDULING();
|
||||
|
||||
os_nanoSleep( rwlock_delay );
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32_t concurrent_read_thread (_In_ void *arg)
|
||||
{
|
||||
int j;
|
||||
os_threadId prevId;
|
||||
struct Par *par = (struct Par *)arg;
|
||||
int printed = 0;
|
||||
|
||||
while (!sd.stop) {
|
||||
if (par->lock) {
|
||||
os_rwlockRead (&sd.global_rwlock);
|
||||
}
|
||||
sd.read_thread[par->index] = os_threadIdSelf();
|
||||
par->read_access++;
|
||||
prevId = sd.global_data;
|
||||
|
||||
FORCE_SCHEDULING();
|
||||
|
||||
for (j = 0; j < BUSYLOOP/2; j++) {
|
||||
if (os_threadIdToInteger(sd.global_data) !=
|
||||
os_threadIdToInteger(prevId)) {
|
||||
sd.read_corrupt_count++;
|
||||
if (!printed) {
|
||||
/* printf ("Critical section corrupted during read [%d]\n", par->index); */
|
||||
printed++;
|
||||
}
|
||||
prevId = sd.global_data;
|
||||
}
|
||||
|
||||
FORCE_SCHEDULING();
|
||||
}
|
||||
if (os_threadIdToInteger(sd.read_thread[0]) ||
|
||||
os_threadIdToInteger(sd.read_thread[1]) ||
|
||||
os_threadIdToInteger(sd.read_thread[2]) ||
|
||||
os_threadIdToInteger(sd.read_thread[3]) ||
|
||||
os_threadIdToInteger(sd.read_thread[4]) ||
|
||||
os_threadIdToInteger(sd.read_thread[5]) ||
|
||||
os_threadIdToInteger(sd.read_thread[6]) ||
|
||||
os_threadIdToInteger(sd.read_thread[7]) ||
|
||||
os_threadIdToInteger(sd.read_thread[8]) ||
|
||||
os_threadIdToInteger(sd.read_thread[9]) ||
|
||||
os_threadIdToInteger(sd.read_thread[10]) ||
|
||||
os_threadIdToInteger(sd.read_thread[11])) {
|
||||
par->concurrent_read_access++;
|
||||
}
|
||||
sd.concurrent_read_access++;
|
||||
if (par->lock) {
|
||||
os_rwlockUnlock (&sd.global_rwlock);
|
||||
}
|
||||
|
||||
FORCE_SCHEDULING();
|
||||
|
||||
os_nanoSleep( rwlock_delay );
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32_t concurrent_trywrite_thread (_In_ void *arg)
|
||||
{
|
||||
struct Par *par = (struct Par *)arg;
|
||||
os_result result;
|
||||
os_threadId myid = os_threadIdSelf();
|
||||
int printed = 0;
|
||||
|
||||
while (!sd.stop) {
|
||||
if (par->lock) {
|
||||
while ((result = os_rwlockTryWrite (&sd.global_rwlock)) != os_resultSuccess) {
|
||||
if (result == os_resultBusy) {
|
||||
sd.trywrite_busy_count++;
|
||||
}
|
||||
|
||||
FORCE_SCHEDULING();
|
||||
}
|
||||
}
|
||||
sd.global_data = os_threadIdSelf();
|
||||
|
||||
FORCE_SCHEDULING();
|
||||
|
||||
os_nanoSleep( rwlock_delay );
|
||||
if (os_threadIdToInteger(sd.global_data) != os_threadIdToInteger(myid)) {
|
||||
sd.trywrite_corrupt_count++;
|
||||
if (!printed) {
|
||||
/* printf ("Critical section corrupted during trywrite [%d]\n", par->index); */
|
||||
printed++;
|
||||
}
|
||||
}
|
||||
sd.concurrent_trywrite_access++;
|
||||
if (par->lock) {
|
||||
os_rwlockUnlock (&sd.global_rwlock);
|
||||
}
|
||||
|
||||
FORCE_SCHEDULING();
|
||||
|
||||
os_nanoSleep( rwlock_delay );
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32_t concurrent_tryread_thread (_In_ void *arg)
|
||||
{
|
||||
int j;
|
||||
os_threadId prevId;
|
||||
struct Par *par = (struct Par *)arg;
|
||||
os_result result;
|
||||
int printed = 0;
|
||||
|
||||
while (!sd.stop) {
|
||||
if (par->lock) {
|
||||
while ((result = os_rwlockTryRead (&sd.global_rwlock)) != os_resultSuccess) {
|
||||
if (result == os_resultBusy) {
|
||||
sd.tryread_busy_count++;
|
||||
}
|
||||
|
||||
FORCE_SCHEDULING();
|
||||
}
|
||||
}
|
||||
sd.read_thread[par->index] = os_threadIdSelf();
|
||||
par->read_access++;
|
||||
prevId = sd.global_data;
|
||||
|
||||
FORCE_SCHEDULING();
|
||||
|
||||
for (j = 0; j < BUSYLOOP/2; j++) {
|
||||
if (os_threadIdToInteger(sd.global_data) !=
|
||||
os_threadIdToInteger(prevId)) {
|
||||
sd.tryread_corrupt_count++;
|
||||
if (!printed) {
|
||||
/* printf ("Critical section corrupted during read [%d]\n", par->index); */
|
||||
printed++;
|
||||
}
|
||||
prevId = sd.global_data;
|
||||
}
|
||||
|
||||
FORCE_SCHEDULING();
|
||||
}
|
||||
if (os_threadIdToInteger(sd.read_thread[0]) ||
|
||||
os_threadIdToInteger(sd.read_thread[1]) ||
|
||||
os_threadIdToInteger(sd.read_thread[2]) ||
|
||||
os_threadIdToInteger(sd.read_thread[3]) ||
|
||||
os_threadIdToInteger(sd.read_thread[4]) ||
|
||||
os_threadIdToInteger(sd.read_thread[5]) ||
|
||||
os_threadIdToInteger(sd.read_thread[6]) ||
|
||||
os_threadIdToInteger(sd.read_thread[7]) ||
|
||||
os_threadIdToInteger(sd.read_thread[8]) ||
|
||||
os_threadIdToInteger(sd.read_thread[9]) ||
|
||||
os_threadIdToInteger(sd.read_thread[10]) ||
|
||||
os_threadIdToInteger(sd.read_thread[11])) {
|
||||
par->concurrent_read_access++;
|
||||
}
|
||||
sd.concurrent_tryread_access++;
|
||||
if (par->lock) {
|
||||
os_rwlockUnlock (&sd.global_rwlock);
|
||||
}
|
||||
|
||||
FORCE_SCHEDULING();
|
||||
|
||||
os_nanoSleep( rwlock_delay );
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
CUnit_Suite_Initialize(os_rwlock)
|
||||
{
|
||||
int result = 0;
|
||||
os_osInit();
|
||||
printf("Run os_rwlock_Initialize\n");
|
||||
#ifdef OS_LINUX_RWLOCK_H149C
|
||||
supported_resultBusy = 1;
|
||||
#else
|
||||
supported_resultBusy = 0;
|
||||
#endif
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
CUnit_Suite_Cleanup(os_rwlock)
|
||||
{
|
||||
int result = 0;
|
||||
|
||||
printf("Run os_rwlock_Cleanup\n");
|
||||
os_osExit();
|
||||
return result;
|
||||
}
|
||||
|
||||
CUnit_Test(os_rwlock, init)
|
||||
{
|
||||
/* Initilalize reader/writer lock with PRIVATE scope and Success result */
|
||||
printf ("Starting os_rwlock_init_001\n");
|
||||
os_rwlockInit (&sd.global_rwlock);
|
||||
|
||||
/* Initilalize reader/writer lock with Fail result */
|
||||
printf ("Starting os_rwlock_init_001\n");
|
||||
printf ("N.A - Failure cannot be forced\n");
|
||||
|
||||
printf ("Ending os_rwlock_init\n");
|
||||
}
|
||||
|
||||
CUnit_Test(os_rwlock, read, false)
|
||||
{
|
||||
os_time rdelay = { 3, 0 };
|
||||
struct Par par[RWLOCK_THREADS];
|
||||
/* Test critical section access without locking to show problem */
|
||||
printf ("Starting os_rwlock_read_001\n");
|
||||
rdelay.tv_sec = 3;
|
||||
printf ("Testing for %d.%9.9d seconds without lock\n", rdelay.tv_sec, rdelay.tv_nsec);
|
||||
sd.read_corrupt_count = 0;
|
||||
sd.write_corrupt_count = 0;
|
||||
sd.concurrent_read_access = 0;
|
||||
sd.concurrent_write_access = 0;
|
||||
sd.tryread_corrupt_count = 0;
|
||||
sd.trywrite_corrupt_count = 0;
|
||||
sd.concurrent_tryread_access = 0;
|
||||
sd.concurrent_trywrite_access = 0;
|
||||
sd.tryread_busy_count = 0;
|
||||
sd.trywrite_busy_count = 0;
|
||||
sd.stop = 0;
|
||||
for (i = 0; i < RWLOCK_THREADS; i++) {
|
||||
par[i].concurrent_read_access = 0;
|
||||
par[i].read_access = 0;
|
||||
par[i].lock = 0;
|
||||
par[i].index = i;
|
||||
}
|
||||
os_threadAttrInit (&rwlock_os_threadAttr);
|
||||
os_threadCreate (&rwlock_os_threadId[0], "thr0", &rwlock_os_threadAttr, &concurrent_write_thread, (void *)&par[0]);
|
||||
os_threadCreate (&rwlock_os_threadId[1], "thr1", &rwlock_os_threadAttr, &concurrent_write_thread, (void *)&par[1]);
|
||||
os_threadCreate (&rwlock_os_threadId[2], "thr2", &rwlock_os_threadAttr, &concurrent_read_thread, (void *)&par[2]);
|
||||
os_threadCreate (&rwlock_os_threadId[3], "thr3", &rwlock_os_threadAttr, &concurrent_read_thread, (void *)&par[3]);
|
||||
os_threadCreate (&rwlock_os_threadId[4], "thr4", &rwlock_os_threadAttr, &concurrent_trywrite_thread, (void *)&par[4]);
|
||||
os_threadCreate (&rwlock_os_threadId[5], "thr5", &rwlock_os_threadAttr, &concurrent_trywrite_thread, (void *)&par[5]);
|
||||
os_threadCreate (&rwlock_os_threadId[6], "thr6", &rwlock_os_threadAttr, &concurrent_tryread_thread, (void *)&par[6]);
|
||||
os_threadCreate (&rwlock_os_threadId[7], "thr7", &rwlock_os_threadAttr, &concurrent_tryread_thread, (void *)&par[7]);
|
||||
os_nanoSleep (rdelay);
|
||||
sd.stop = 1;
|
||||
os_threadWaitExit (rwlock_os_threadId[0], NULL);
|
||||
os_threadWaitExit (rwlock_os_threadId[1], NULL);
|
||||
os_threadWaitExit (rwlock_os_threadId[2], NULL);
|
||||
os_threadWaitExit (rwlock_os_threadId[3], NULL);
|
||||
os_threadWaitExit (rwlock_os_threadId[4], NULL);
|
||||
os_threadWaitExit (rwlock_os_threadId[5], NULL);
|
||||
os_threadWaitExit (rwlock_os_threadId[6], NULL);
|
||||
os_threadWaitExit (rwlock_os_threadId[7], NULL);
|
||||
|
||||
printf ("All threads stopped\n");
|
||||
for (i = 2; i < 4; i++) {
|
||||
printf ("total read access %d, concurrent read access %d for thread %d\n",
|
||||
par[i].read_access, par[i].concurrent_read_access, i);
|
||||
}
|
||||
for (i = 6; i < 8; i++) {
|
||||
printf ("total try read access %d, concurrent try read access %d for thread %d\n",
|
||||
par[i].read_access, par[i].concurrent_read_access, i);
|
||||
}
|
||||
printf ("read_corrupt_count = %d\n", sd.read_corrupt_count);
|
||||
printf ("write_corrupt_count = %d\n", sd.write_corrupt_count);
|
||||
printf ("tryread_corrupt_count = %d\n", sd.tryread_corrupt_count);
|
||||
printf ("trywrite_corrupt_count = %d\n", sd.trywrite_corrupt_count);
|
||||
printf ("concurrent_read_access = %d\n", sd.concurrent_read_access);
|
||||
printf ("concurrent_write_access = %d\n", sd.concurrent_write_access);
|
||||
printf ("concurrent_tryread_access = %d\n", sd.concurrent_tryread_access);
|
||||
printf ("concurrent_trywrite_access = %d\n", sd.concurrent_trywrite_access);
|
||||
|
||||
sprintf (buffer, "Corrupt counter = %d, Loop counter is %d",
|
||||
sd.read_corrupt_count + sd.write_corrupt_count + sd.tryread_corrupt_count + sd.trywrite_corrupt_count,
|
||||
sd.concurrent_read_access + sd.concurrent_write_access + sd.concurrent_tryread_access + sd.concurrent_trywrite_access);
|
||||
|
||||
CU_ASSERT((sd.read_corrupt_count > 0 ||
|
||||
sd.write_corrupt_count > 0 ||
|
||||
sd.tryread_corrupt_count > 0 ||
|
||||
sd.trywrite_corrupt_count > 0) &&
|
||||
sd.concurrent_read_access > 0 &&
|
||||
sd.concurrent_write_access > 0 &&
|
||||
sd.concurrent_tryread_access > 0 &&
|
||||
sd.concurrent_trywrite_access > 0);
|
||||
|
||||
/* Test critical section READ access with locking and PRIVATE scope */
|
||||
printf ("Starting os_rwlock_read_002\n");
|
||||
rdelay.tv_sec = 3;
|
||||
printf ("Testing for %d.%9.9d seconds with lock\n", rdelay.tv_sec, rdelay.tv_nsec);
|
||||
sd.read_corrupt_count = 0;
|
||||
sd.write_corrupt_count = 0;
|
||||
sd.concurrent_read_access = 0;
|
||||
sd.concurrent_write_access = 0;
|
||||
sd.tryread_corrupt_count = 0;
|
||||
sd.trywrite_corrupt_count = 0;
|
||||
sd.concurrent_tryread_access = 0;
|
||||
sd.concurrent_trywrite_access = 0;
|
||||
sd.tryread_busy_count = 0;
|
||||
sd.trywrite_busy_count = 0;
|
||||
sd.stop = 0;
|
||||
for (i = 0; i < RWLOCK_THREADS; i++) {
|
||||
par[i].concurrent_read_access = 0;
|
||||
par[i].read_access = 0;
|
||||
par[i].lock = 1;
|
||||
par[i].index = i;
|
||||
}
|
||||
os_threadAttrInit (&rwlock_os_threadAttr);
|
||||
os_threadCreate (&rwlock_os_threadId[0], "thr0", &rwlock_os_threadAttr, &concurrent_write_thread, (void *)&par[0]);
|
||||
os_threadCreate (&rwlock_os_threadId[1], "thr1", &rwlock_os_threadAttr, &concurrent_write_thread, (void *)&par[1]);
|
||||
os_threadCreate (&rwlock_os_threadId[2], "thr2", &rwlock_os_threadAttr, &concurrent_read_thread, (void *)&par[2]);
|
||||
os_threadCreate (&rwlock_os_threadId[3], "thr3", &rwlock_os_threadAttr, &concurrent_read_thread, (void *)&par[3]);
|
||||
os_threadCreate (&rwlock_os_threadId[4], "thr4", &rwlock_os_threadAttr, &concurrent_trywrite_thread, (void *)&par[4]);
|
||||
os_threadCreate (&rwlock_os_threadId[5], "thr5", &rwlock_os_threadAttr, &concurrent_trywrite_thread, (void *)&par[5]);
|
||||
os_threadCreate (&rwlock_os_threadId[6], "thr6", &rwlock_os_threadAttr, &concurrent_tryread_thread, (void *)&par[6]);
|
||||
os_threadCreate (&rwlock_os_threadId[7], "thr7", &rwlock_os_threadAttr, &concurrent_tryread_thread, (void *)&par[7]);
|
||||
os_nanoSleep (rdelay);
|
||||
sd.stop = 1;
|
||||
os_threadWaitExit (rwlock_os_threadId[0], NULL);
|
||||
os_threadWaitExit (rwlock_os_threadId[1], NULL);
|
||||
os_threadWaitExit (rwlock_os_threadId[2], NULL);
|
||||
os_threadWaitExit (rwlock_os_threadId[3], NULL);
|
||||
os_threadWaitExit (rwlock_os_threadId[4], NULL);
|
||||
os_threadWaitExit (rwlock_os_threadId[5], NULL);
|
||||
os_threadWaitExit (rwlock_os_threadId[6], NULL);
|
||||
os_threadWaitExit (rwlock_os_threadId[7], NULL);
|
||||
|
||||
printf ("All threads stopped\n");
|
||||
for (i = 2; i < 4; i++) {
|
||||
printf ("total read access %d, concurrent read access %d for thread %d\n",
|
||||
par[i].read_access, par[i].concurrent_read_access, i);
|
||||
}
|
||||
for (i = 6; i < 8; i++) {
|
||||
printf ("total try read access %d, concurrent try read access %d for thread %d\n",
|
||||
par[i].read_access, par[i].concurrent_read_access, i);
|
||||
}
|
||||
|
||||
sprintf (buffer, "Corrupt read counter = %d, Read loop counter is %d", sd.read_corrupt_count, sd.concurrent_read_access);
|
||||
CU_ASSERT (sd.read_corrupt_count == 0 && sd.concurrent_read_access > 0);
|
||||
|
||||
/* Test read on rwlock with PRIVATE scope and Success result & not locked */
|
||||
printf ("Starting os_rwlock_read_003\n");
|
||||
os_rwlockRead (&sd.global_rwlock); // Cannot be checked
|
||||
os_rwlockUnlock (&sd.global_rwlock);
|
||||
|
||||
/* Test read on rwlock with PRIVATE scope and Success result & locked by read */
|
||||
printf ("Starting os_rwlock_read_004\n");
|
||||
printf ("N.A - Not implemented\n");
|
||||
|
||||
/* Test read on rwlock with PRIVATE scope and Fail result */
|
||||
printf ("Starting os_rwlock_read_005\n");
|
||||
printf ("N.A - Failure cannot be forced\n");
|
||||
|
||||
printf ("Ending os_rwlock_read\n");
|
||||
}
|
||||
|
||||
CUnit_Test(os_rwlock, write, false)
|
||||
{
|
||||
/* Test critical section WRITE access with locking and PRIVATE scope */
|
||||
printf ("Starting os_rwlock_write_001\n");
|
||||
|
||||
sprintf (buffer, "Corrupt write counter = %d, Write loop counter is %d", sd.write_corrupt_count, sd.concurrent_write_access);
|
||||
CU_ASSERT (sd.write_corrupt_count == 0 && sd.concurrent_write_access > 0);
|
||||
|
||||
/* Test write on rwlock with PRIVATE scope and Success result */
|
||||
printf ("Starting os_rwlock_write_002\n");
|
||||
os_rwlockWrite (&sd.global_rwlock); //Cannot be checked
|
||||
os_rwlockUnlock (&sd.global_rwlock);
|
||||
|
||||
/* Test write on rwlock with PRIVATE scope and Fail result */
|
||||
printf ("Starting os_rwlock_write_003\n");
|
||||
printf ("N.A - Failure cannot be forced\n");
|
||||
|
||||
printf ("Ending tc_rwlockWrite\n");
|
||||
}
|
||||
|
||||
CUnit_Test(rwlock, tryread, false)
|
||||
{
|
||||
os_result result;
|
||||
/* Test critical section READ access with trylocking and PRIVATE scope */
|
||||
printf ("Starting os_rwlock_tryread_001\n");
|
||||
|
||||
sprintf (buffer, "Corrupt tryread counter = %d, Tryread loop counter is %d, Busy counter = %d", sd.tryread_corrupt_count, sd.concurrent_tryread_access, sd.tryread_busy_count);
|
||||
CU_ASSERT (sd.tryread_corrupt_count == 0 && sd.concurrent_tryread_access > 0);
|
||||
|
||||
/* Test try read on rwlock with PRIVATE scope and Success result & not locked */
|
||||
printf ("Starting os_rwlock_tryread_002\n");
|
||||
result = os_rwlockTryRead (&sd.global_rwlock);
|
||||
CU_ASSERT (result == os_resultSuccess);
|
||||
os_rwlockUnlock (&sd.global_rwlock);
|
||||
|
||||
/* Test try read on rwlock with PRIVATE scope and Success result & locked by read */
|
||||
printf ("Starting os_rwlock_tryread_003\n");
|
||||
printf ("N.A - Not implemented\n");
|
||||
|
||||
/* Test try read on rwlock with PRIVATE scope and Busy result & locked by write */
|
||||
printf ("Starting os_rwlock_tryread_004\n");
|
||||
printf ("N.A - Not implemented\n");
|
||||
|
||||
/* Test try read on rwlock with PRIVATE scope and Fail result */
|
||||
printf ("Starting os_rwlock_tryread_005\n");
|
||||
printf ("N.A - Failure cannot be forced\n");
|
||||
|
||||
printf ("Ending os_rwlock_tryread\n");
|
||||
}
|
||||
|
||||
CUnit_Test(os_rwlock, trywrite, false)
|
||||
{
|
||||
os_result result;
|
||||
/* Test critical section WRITE access with trylocking and PRIVATE scope */
|
||||
printf ("Starting os_rwlock_trywrite_001\n");
|
||||
|
||||
sprintf (buffer, "Corrupt trywrite counter = %d, Trywrite loop counter is %d, Busy counter = %d", sd.trywrite_corrupt_count, sd.concurrent_trywrite_access, sd.trywrite_busy_count);
|
||||
CU_ASSERT (sd.trywrite_corrupt_count == 0 && sd.concurrent_trywrite_access > 0);
|
||||
|
||||
/* Test try write on rwlock with PRIVATE scope and Success result */
|
||||
printf ("Starting os_rwlock_trywrite_002\n");
|
||||
result = os_rwlockTryWrite (&sd.global_rwlock);
|
||||
CU_ASSERT (result == os_resultSuccess);
|
||||
os_rwlockUnlock (&sd.global_rwlock);
|
||||
|
||||
/* Test try write on rwlock with PRIVATE scope and Busy result & locked by read */
|
||||
printf ("Starting os_rwlock_trywrite_003\n");
|
||||
printf ("N.A - Not implemented\n");
|
||||
|
||||
/* Test try write on rwlock with PRIVATE scope and Busy result & locked by write */
|
||||
printf ("Starting os_rwlock_trywrite_004\n");
|
||||
printf ("N.A - Not implemented\n");
|
||||
|
||||
/* Test try write on rwlock with PRIVATE scope and Fail result */
|
||||
printf ("Starting os_rwlock_trywrite_005\n");
|
||||
printf ("N.A - Failure cannot be forced\n");
|
||||
|
||||
printf ("Ending os_rwlock_trywrite\n");
|
||||
}
|
||||
|
||||
CUnit_Test(os_rwlock, unlock, false)
|
||||
{
|
||||
os_result result;
|
||||
/* Unlock rwlock with PRIVATE scope and Success result and claimed with read */
|
||||
printf ("Starting os_rwlock_unlock_001\n");
|
||||
os_rwlockRead (&sd.global_rwlock);
|
||||
os_rwlockUnlock (&sd.global_rwlock); //Cannot be checked
|
||||
|
||||
/* Unlock rwlock with PRIVATE scope and Success result and claimed with try read */
|
||||
printf ("Starting os_rwlock_unlock_002\n");
|
||||
result = os_rwlockTryRead (&sd.global_rwlock);
|
||||
CU_ASSERT (result == os_resultSuccess);
|
||||
os_rwlockUnlock (&sd.global_rwlock);
|
||||
|
||||
/* Unlock rwlock with PRIVATE scope and Success result and claimed with write */
|
||||
printf ("Starting os_rwlock_unlock_003\n");
|
||||
os_rwlockWrite (&sd.global_rwlock);
|
||||
os_rwlockUnlock (&sd.global_rwlock); //Cannot be checked
|
||||
|
||||
/* Unlock rwlock with PRIVATE scope and Success result and claimed with try write */
|
||||
printf ("Starting os_rwlock_unlock_004\n");
|
||||
result = os_rwlockTryWrite (&sd.global_rwlock);
|
||||
CU_ASSERT (result == os_resultSuccess);
|
||||
os_rwlockUnlock (&sd.global_rwlock);
|
||||
|
||||
/* Unlock rwlock with PRIVATE scope and Fail result */
|
||||
printf ("Starting os_rwlock_unlock_005\n");
|
||||
printf ("N.A - Failure cannot be forced\n");
|
||||
|
||||
printf ("Ending tc_rwlockUnlock\n");
|
||||
}
|
||||
|
||||
CUnit_Test(os_rwlock, destroy, false)
|
||||
{
|
||||
/* Deinitialize rwlock with PRIVATE scope and Success result */
|
||||
printf ("Starting os_rwlock_destroy_001\n");
|
||||
os_rwlockDestroy (&sd.global_rwlock); //Cannot be checked
|
||||
|
||||
/* Deinitialize rwlock with PRIVATE scope and Fail result */
|
||||
printf ("Starting os_rwlock_destroy_002\n");
|
||||
printf ("N.A - Failure cannot be forced\n");
|
||||
|
||||
printf ("Ending tc_rwlockDestroy\n");
|
||||
}
|
||||
|
||||
CUnit_Test(os_rwlock, destroy_shared)
|
||||
{
|
||||
os_rwlock mylock;
|
||||
|
||||
os_rwlockInit(&mylock);
|
||||
os_rwlockRead(&mylock);
|
||||
os_rwlockUnlock(&mylock);
|
||||
/* This test used to assert on a debug-build on Windows. Failure can't be forced, but if
|
||||
* someone adds the naively sensible assert again, this test won't run on a debug-build. */
|
||||
os_rwlockDestroy(&mylock);
|
||||
CU_PASS("os_rwlockDestroy succeeds after releasing a shared lock");
|
||||
}
|
869
src/os/tests/stdlib.c
Executable file
869
src/os/tests/stdlib.c
Executable file
|
@ -0,0 +1,869 @@
|
|||
/*
|
||||
* Copyright(c) 2006 to 2018 ADLINK Technology Limited and others
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License v. 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
|
||||
* v. 1.0 which is available at
|
||||
* http://www.eclipse.org/org/documents/edl-v10.php.
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
|
||||
*/
|
||||
#include "CUnit/Runner.h"
|
||||
#include "os/os.h"
|
||||
|
||||
#ifndef WINCE
|
||||
#include <fcntl.h>
|
||||
#endif
|
||||
|
||||
#if (defined WIN32 || defined WIN64)
|
||||
#include <direct.h>
|
||||
#include <Windows.h>
|
||||
#endif
|
||||
|
||||
static const os_time wait_time_out = { 1, 0 };
|
||||
static FILE *file;
|
||||
|
||||
#define ENABLE_TRACING 0
|
||||
|
||||
#define FLOCKFILE_THREAD1_INPUT1 "thread1_flockfile_proc: *** input 1 ***"
|
||||
#define FLOCKFILE_THREAD1_INPUT3 "thread1_flockfile_proc: *** input 3 ***"
|
||||
#define FLOCKFILE_THREAD2_INPUT2 "thread2_flockfile_proc: *** input 2 ***"
|
||||
|
||||
#define defSignal(signal) \
|
||||
static os_cond signal;\
|
||||
static bool signal##_set = false;
|
||||
|
||||
#define initSignal(signal, mutex) \
|
||||
os_condInit(&signal, &mutex);\
|
||||
signal##_set = false;
|
||||
|
||||
#define sendSignal(signal, mutex) \
|
||||
os_mutexLock(&mutex);\
|
||||
/* signaling */ \
|
||||
signal##_set = true; \
|
||||
os_condSignal(&signal);\
|
||||
os_mutexUnlock(&mutex);
|
||||
|
||||
#define waitForSignal(signal, mutex) \
|
||||
os_mutexLock(&mutex);\
|
||||
while(!signal##_set) { \
|
||||
/* waiting for signal */ \
|
||||
os_condWait(&signal, &mutex);\
|
||||
/* received */ \
|
||||
} /* else already signal received */ \
|
||||
os_mutexUnlock(&mutex);
|
||||
|
||||
#define timedWaitSignal(signal, mutex, time) \
|
||||
{ \
|
||||
os_time duration = time; \
|
||||
os_time startTime, currentTime; \
|
||||
os_result rc; \
|
||||
os_mutexLock(&mutex); \
|
||||
startTime = os_timeGetElapsed(); \
|
||||
while(!signal##_set) { \
|
||||
/* waiting for signal */ \
|
||||
rc = os_condTimedWait(&signal, &mutex, &duration); \
|
||||
/* signal received or timeout */ \
|
||||
if(rc == os_resultTimeout) { \
|
||||
break; \
|
||||
} else { \
|
||||
currentTime = os_timeGetElapsed(); \
|
||||
if(os_timeCompare(os_timeSub(currentTime, startTime), wait_time_out) >= 0) { \
|
||||
break; \
|
||||
} \
|
||||
duration = os_timeSub(wait_time_out, os_timeSub(currentTime, startTime)); \
|
||||
} \
|
||||
} /* else already signal received */ \
|
||||
os_mutexUnlock(&mutex);\
|
||||
}
|
||||
|
||||
static os_mutex mutex;
|
||||
static bool do_locking;
|
||||
|
||||
/* signals set by threads */
|
||||
defSignal(thread1_started);
|
||||
defSignal(thread2_started);
|
||||
defSignal(action1_done);
|
||||
defSignal(action2_done);
|
||||
|
||||
/* signals set by the test orchestrator (doFlockfileTest) */
|
||||
defSignal(do_action1);
|
||||
defSignal(do_action2);
|
||||
defSignal(do_action3);
|
||||
|
||||
static uint32_t thread1_flockfile_proc(void* args) {
|
||||
int result = 0;
|
||||
|
||||
/* thread1: start */
|
||||
sendSignal(thread1_started, mutex);
|
||||
|
||||
waitForSignal(do_action1, mutex);
|
||||
if(do_locking) os_flockfile(file);
|
||||
/* Thread1: writing input 1 to the file */
|
||||
result = fputs(FLOCKFILE_THREAD1_INPUT1, file);
|
||||
CU_ASSERT(result >= 0);
|
||||
|
||||
sendSignal(action1_done, mutex);
|
||||
|
||||
waitForSignal(do_action3, mutex);
|
||||
/* Thread1: writing input 3 to the file */
|
||||
result = fputs(FLOCKFILE_THREAD1_INPUT3, file);
|
||||
CU_ASSERT(result >= 0);
|
||||
if(do_locking) os_funlockfile(file);
|
||||
/* thread1: end */
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static uint32_t thread2_flockfile_proc(void* args) {
|
||||
int result = 0;
|
||||
|
||||
/* thread2: start */
|
||||
sendSignal(thread2_started, mutex);
|
||||
|
||||
waitForSignal(do_action2, mutex);
|
||||
/* Thread2: writing input 2 to the file */
|
||||
result = fputs(FLOCKFILE_THREAD2_INPUT2, file);
|
||||
CU_ASSERT(result >= 0);
|
||||
|
||||
sendSignal(action2_done, mutex);
|
||||
/* thread2: end */
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool doFlockfileTest(bool lock) {
|
||||
bool testPassed = true;
|
||||
bool strcmpResult = true;
|
||||
os_result result;
|
||||
os_threadAttr threadAttr;
|
||||
os_threadId thread1;
|
||||
os_threadId thread2;
|
||||
int FLOCKFILE_INPUT_MAX = sizeof(FLOCKFILE_THREAD1_INPUT1);
|
||||
|
||||
do_locking = lock;
|
||||
|
||||
char *buffer = os_malloc(sizeof(char) * FLOCKFILE_INPUT_MAX);
|
||||
|
||||
file = tmpfile();
|
||||
|
||||
os_mutexInit(&mutex);
|
||||
|
||||
/* initialize all signal conditions */
|
||||
os_mutexLock(&mutex);
|
||||
initSignal(thread1_started, mutex);
|
||||
initSignal(thread2_started, mutex);
|
||||
initSignal(action1_done, mutex);
|
||||
initSignal(action2_done, mutex);
|
||||
|
||||
initSignal(do_action1, mutex);
|
||||
initSignal(do_action2, mutex);
|
||||
initSignal(do_action3, mutex);
|
||||
os_mutexUnlock(&mutex);
|
||||
|
||||
/* create threads... */
|
||||
os_threadAttrInit(&threadAttr);
|
||||
|
||||
result = os_threadCreate(
|
||||
&thread1,
|
||||
"thread 1",
|
||||
&threadAttr,
|
||||
thread1_flockfile_proc,
|
||||
NULL);
|
||||
CU_ASSERT(result == os_resultSuccess);
|
||||
|
||||
result = os_threadCreate(
|
||||
&thread2,
|
||||
"thread 2",
|
||||
&threadAttr,
|
||||
thread2_flockfile_proc,
|
||||
NULL);
|
||||
CU_ASSERT(result == os_resultSuccess);
|
||||
|
||||
/* wait for threads to start */
|
||||
waitForSignal(thread1_started, mutex);
|
||||
waitForSignal(thread2_started, mutex);
|
||||
|
||||
/* get thread one to do its first thing */
|
||||
sendSignal(do_action1, mutex);
|
||||
|
||||
/* wait for thread 1 to acknowledge */
|
||||
timedWaitSignal(action1_done, mutex, wait_time_out);
|
||||
|
||||
/* kick thead 2 */
|
||||
sendSignal(do_action2, mutex);
|
||||
|
||||
/* wait for thread 2 to acknowledge */
|
||||
timedWaitSignal(action2_done, mutex, wait_time_out);
|
||||
|
||||
/* kick thread 1, again */
|
||||
sendSignal(do_action3, mutex);
|
||||
|
||||
/* wait for threads to shutdown */
|
||||
result = os_threadWaitExit(thread1,NULL);
|
||||
CU_ASSERT(result == os_resultSuccess);
|
||||
|
||||
result = os_threadWaitExit(thread2,NULL);
|
||||
CU_ASSERT(result == os_resultSuccess);
|
||||
|
||||
/* if lock then Expected action order: 1 3 2
|
||||
* else Expected action order: 1 2 3 */
|
||||
|
||||
rewind(file);
|
||||
|
||||
if(lock) {
|
||||
if(fgets(buffer, FLOCKFILE_INPUT_MAX, file) > 0) {
|
||||
strcmpResult = (strcmp(buffer, FLOCKFILE_THREAD1_INPUT1) == 0);
|
||||
CU_ASSERT(strcmpResult);
|
||||
testPassed = testPassed && strcmpResult; /* update flag indicating overall test state */
|
||||
}
|
||||
if(fgets(buffer, FLOCKFILE_INPUT_MAX, file) > 0) {
|
||||
strcmpResult = (strcmp(buffer, FLOCKFILE_THREAD1_INPUT3) == 0);
|
||||
CU_ASSERT(strcmpResult);
|
||||
testPassed = testPassed && strcmpResult; /* update flag indicating overall test state */
|
||||
}
|
||||
if(fgets(buffer, FLOCKFILE_INPUT_MAX, file) > 0) {
|
||||
strcmpResult = (strcmp(buffer, FLOCKFILE_THREAD2_INPUT2) == 0);
|
||||
CU_ASSERT(strcmpResult);
|
||||
testPassed = testPassed && strcmpResult; /* update flag indicating overall test state */
|
||||
}
|
||||
} else {
|
||||
if(fgets(buffer, FLOCKFILE_INPUT_MAX, file) > 0) {
|
||||
strcmpResult = (strcmp(buffer, FLOCKFILE_THREAD1_INPUT1) == 0);
|
||||
CU_ASSERT(strcmpResult);
|
||||
testPassed = testPassed && strcmpResult; /* update flag indicating overall test state */
|
||||
}
|
||||
if(fgets(buffer, FLOCKFILE_INPUT_MAX, file) > 0) {
|
||||
strcmpResult = (strcmp(buffer, FLOCKFILE_THREAD2_INPUT2) == 0);
|
||||
CU_ASSERT(strcmpResult);
|
||||
testPassed = testPassed && strcmpResult; /* update flag indicating overall test state */
|
||||
}
|
||||
if(fgets(buffer, FLOCKFILE_INPUT_MAX, file) > 0) {
|
||||
strcmpResult = (strcmp(buffer, FLOCKFILE_THREAD1_INPUT3) == 0);
|
||||
CU_ASSERT(strcmpResult);
|
||||
testPassed = testPassed && strcmpResult; /* update flag indicating overall test state */
|
||||
}
|
||||
}
|
||||
|
||||
/* cleanup */
|
||||
os_free(buffer);
|
||||
fclose(file);
|
||||
|
||||
os_mutexLock(&mutex);
|
||||
os_condDestroy(&do_action1);
|
||||
os_condDestroy(&do_action2);
|
||||
os_condDestroy(&do_action3);
|
||||
|
||||
os_condDestroy(&thread1_started);
|
||||
os_condDestroy(&thread2_started);
|
||||
os_condDestroy(&action1_done);
|
||||
os_condDestroy(&action2_done);
|
||||
os_mutexUnlock(&mutex);
|
||||
os_mutexDestroy(&mutex);
|
||||
/* doFlockfileTest */
|
||||
return testPassed;
|
||||
}
|
||||
|
||||
static int
|
||||
vsnprintfTest(
|
||||
const char *format,
|
||||
...)
|
||||
{
|
||||
va_list varargs;
|
||||
int result = 0;
|
||||
char description[10];
|
||||
va_start(varargs, format);
|
||||
memset(description, 0, sizeof(description));
|
||||
|
||||
result = os_vsnprintf(description, sizeof(description)-1, format, varargs);
|
||||
va_end(varargs);
|
||||
return result;
|
||||
}
|
||||
|
||||
CUnit_Suite_Initialize(os_stdlib)
|
||||
{
|
||||
int result = 0;
|
||||
os_osInit();
|
||||
return result;
|
||||
}
|
||||
|
||||
CUnit_Suite_Cleanup(os_stdlib)
|
||||
{
|
||||
/* Remove files used to test permissions */
|
||||
remove ("exec_only");
|
||||
remove ("read_exec");
|
||||
remove ("read_only");
|
||||
remove ("read_write_exec");
|
||||
remove ("write_only");
|
||||
remove ("existing_file");
|
||||
os_osExit();
|
||||
return 0;
|
||||
}
|
||||
|
||||
CUnit_Test(os_stdlib, strcasecmp)
|
||||
{
|
||||
int res;
|
||||
char *s1, *s2;
|
||||
|
||||
s1 = "a";
|
||||
s2 = "a";
|
||||
printf ("Starting os_stdlib_strcasecmp_001\n");
|
||||
res = os_strcasecmp (s1,s2);
|
||||
CU_ASSERT (res == 0);
|
||||
|
||||
printf ("Starting os_stdlib_strcasecmp_002\n");
|
||||
s1 = "aa";
|
||||
s2 = "a";
|
||||
res = os_strcasecmp (s1,s2);
|
||||
CU_ASSERT (res > 0);
|
||||
|
||||
printf ("Starting os_stdlib_strcasecmp_003\n");
|
||||
s1 = "a";
|
||||
s2 = "aa";
|
||||
res = os_strcasecmp (s1,s2);
|
||||
CU_ASSERT (res < 0);
|
||||
|
||||
printf ("Starting os_stdlib_strcasecmp_004\n");
|
||||
s1 = "a";
|
||||
s2 = "A";
|
||||
res = os_strcasecmp (s1,s2);
|
||||
CU_ASSERT (res == 0);
|
||||
|
||||
printf ("Starting os_stdlib_strcasecmp_005\n");
|
||||
s1 = "A";
|
||||
s2 = "a";
|
||||
res = os_strcasecmp (s1,s2);
|
||||
CU_ASSERT (res == 0);
|
||||
|
||||
printf ("Starting os_stdlib_strcasecmp_006\n");
|
||||
s1 = "a";
|
||||
s2 = "b";
|
||||
res = os_strcasecmp (s1,s2);
|
||||
CU_ASSERT (res < 0);
|
||||
|
||||
printf ("Starting os_stdlib_strcasecmp_007\n");
|
||||
s1 = "b";
|
||||
s2 = "a";
|
||||
res = os_strcasecmp (s1,s2);
|
||||
CU_ASSERT (res > 0);
|
||||
|
||||
printf ("Ending os_stdlib_strcasecmp\n");
|
||||
}
|
||||
|
||||
CUnit_Test(os_stdlib, strncasecmp)
|
||||
{
|
||||
int res;
|
||||
char *s1, *s2;
|
||||
|
||||
s1 = "a";
|
||||
s2 = "a";
|
||||
printf ("Starting os_stdlib_strncasecmp_001\n");
|
||||
res = os_strncasecmp (s1,s2,2);
|
||||
CU_ASSERT (res == 0);
|
||||
|
||||
s1 = "aa";
|
||||
s2 = "a";
|
||||
printf ("Starting os_stdlib_strncasecmp_002\n");
|
||||
res = os_strncasecmp (s1,s2,2);
|
||||
CU_ASSERT (res > 0);
|
||||
|
||||
s1 = "a";
|
||||
s2 = "aa";
|
||||
printf ("Starting os_stdlib_strncasecmp_003\n");
|
||||
res = os_strncasecmp (s1,s2,2);
|
||||
CU_ASSERT (res < 0);
|
||||
|
||||
s1 = "a";
|
||||
s2 = "A";
|
||||
printf ("Starting os_stdlib_strncasecmp_004\n");
|
||||
res = os_strncasecmp (s1,s2,2);
|
||||
CU_ASSERT (res == 0);
|
||||
|
||||
s1 = "A";
|
||||
s2 = "a";
|
||||
printf ("Starting os_stdlib_strncasecmp_005\n");
|
||||
res = os_strncasecmp (s1,s2,2);
|
||||
CU_ASSERT (res == 0);
|
||||
|
||||
s1 = "a";
|
||||
s2 = "b";
|
||||
printf ("Starting os_stdlib_strncasecmp_006\n");
|
||||
res = os_strncasecmp (s1,s2,2);
|
||||
CU_ASSERT (res < 0);
|
||||
|
||||
s1 = "b";
|
||||
s2 = "a";
|
||||
printf ("Starting os_stdlib_strncasecmp_007\n");
|
||||
res = os_strncasecmp (s1,s2,2);
|
||||
CU_ASSERT (res > 0);
|
||||
|
||||
s1 = "abcdefghijkl";
|
||||
s2 = "AbCdEaGhIjKl";
|
||||
printf ("Starting os_stdlib_strncasecmp_008\n");
|
||||
res = os_strncasecmp (s1,s2,5);
|
||||
CU_ASSERT (res == 0);
|
||||
|
||||
s1 = "abcdefghijkl";
|
||||
s2 = "AbCdEaGhIjKl";
|
||||
printf ("Starting os_stdlib_strncasecmp_009\n");
|
||||
res = os_strncasecmp (s1,s2,6);
|
||||
CU_ASSERT (res > 0);
|
||||
|
||||
printf ("Ending os_stdlib_strncasecmp\n");
|
||||
}
|
||||
|
||||
CUnit_Test(os_stdlib, gethostname)
|
||||
{
|
||||
int res;
|
||||
os_result os_res;
|
||||
char os_cpu[200];
|
||||
char cpu[200];
|
||||
|
||||
printf ("Starting os_stdlib_gethostname_001\n");
|
||||
os_cpu[0] = '\0';
|
||||
os_res = os_gethostname (os_cpu, sizeof(os_cpu));
|
||||
CU_ASSERT (os_res == os_resultSuccess);
|
||||
|
||||
cpu[0] = '\0';
|
||||
res = gethostname (cpu, sizeof(cpu));
|
||||
CU_ASSERT (res == 0);
|
||||
|
||||
printf ("Starting os_stdlib_gethostname_002\n");
|
||||
os_res = os_gethostname (os_cpu, strlen(os_cpu)-1);
|
||||
CU_ASSERT (os_res == os_resultFail);
|
||||
printf ("Ending os_stdlib_gethostname\n");
|
||||
}
|
||||
|
||||
CUnit_Test(os_stdlib, putenv)
|
||||
{
|
||||
os_result os_res;
|
||||
|
||||
printf ("Starting os_stdlib_putenv_001\n");
|
||||
os_res = os_putenv ("ABCDE=FGHIJ");
|
||||
CU_ASSERT (os_res == os_resultSuccess);
|
||||
CU_ASSERT (strcmp (os_getenv("ABCDE"), "FGHIJ") == 0);
|
||||
printf ("Ending os_stdlib_putenv\n");
|
||||
}
|
||||
|
||||
CUnit_Test(os_stdlib, getenv)
|
||||
{
|
||||
const char *env;
|
||||
os_result res;
|
||||
|
||||
printf ("Starting os_stdlib_getenv_001\n");
|
||||
|
||||
res = os_putenv("ABCDE=FGHIJ");
|
||||
CU_ASSERT(res == os_resultSuccess);
|
||||
|
||||
env = os_getenv("ABCDE");
|
||||
CU_ASSERT(env != NULL);
|
||||
if (env != NULL) {
|
||||
CU_ASSERT(strcmp(env, "FGHIJ") == 0);
|
||||
}
|
||||
printf ("Starting os_stdlib_getenv_002\n");
|
||||
CU_ASSERT (os_getenv("XXABCDEXX") == NULL );
|
||||
printf ("Ending os_stdlib_getenv\n");
|
||||
}
|
||||
|
||||
CUnit_Test(os_stdlib, fileSep)
|
||||
{
|
||||
#if defined WIN32
|
||||
const char *wanted= "\\";
|
||||
#else
|
||||
const char *wanted= "/";
|
||||
#endif
|
||||
printf ("Starting os_stdlib_fileSep_001\n");
|
||||
CU_ASSERT (strcmp(os_fileSep(), wanted) == 0);
|
||||
printf ("Ending os_stdlib_fileSep\n");
|
||||
}
|
||||
|
||||
CUnit_Test(os_stdlib, access)
|
||||
{
|
||||
os_result os_res;
|
||||
os_result wanted;
|
||||
int fh;
|
||||
|
||||
/* Check correct functioning of os_access, non existing file read access */
|
||||
printf ("Starting os_stdlib_access_001\n");
|
||||
#if defined VXWORKS_RTP || defined _WRS_KERNEL
|
||||
printf ("N.A - Not tested for vxworks.\n");
|
||||
#else
|
||||
os_res = os_access("non_existing_file", OS_ROK);
|
||||
CU_ASSERT (os_res == os_resultFail);
|
||||
|
||||
/* Check correct functioning of os_access, non existing file write access */
|
||||
printf ("Starting os_stdlib_access_002\n");
|
||||
os_res = os_access("non_existing_file", OS_WOK);
|
||||
CU_ASSERT (os_res == os_resultFail);
|
||||
|
||||
/* Check correct functioning of os_access, non existing file execute access */
|
||||
printf ("Starting os_stdlib_access_003\n");
|
||||
os_res = os_access("non_existing_file", OS_XOK);
|
||||
CU_ASSERT (os_res == os_resultFail);
|
||||
|
||||
/* Check correct functioning of os_access, non existing file existence */
|
||||
printf ("Starting os_stdlib_access_004\n");
|
||||
os_res = os_access("non_existing_file", OS_FOK);
|
||||
CU_ASSERT (os_res == os_resultFail);
|
||||
|
||||
/* Check correct functioning of os_access, existing file with no
|
||||
permissions read access */
|
||||
printf ("Starting os_stdlib_access_005\n");
|
||||
#ifdef WIN32
|
||||
fh= _creat("existing_file", 0000); /* Note always has read & execute */
|
||||
if (fh != -1)
|
||||
_close(fh);
|
||||
wanted = os_resultSuccess;
|
||||
#else
|
||||
fh= creat("existing_file", 0000);
|
||||
if (fh != -1)
|
||||
close(fh);
|
||||
wanted = os_resultFail;
|
||||
#endif /* WIN32 */
|
||||
os_res = os_access("existing_file", OS_ROK);
|
||||
CU_ASSERT (os_res == wanted);
|
||||
|
||||
/* Check correct functioning of os_access, existing file with no
|
||||
permissions write access */
|
||||
printf ("Starting os_stdlib_access_006\n");
|
||||
os_res = os_access("existing_file", OS_WOK);
|
||||
CU_ASSERT (os_res == os_resultFail);
|
||||
|
||||
/* Check correct functioning of os_access, existing file with no
|
||||
permissions execute access */
|
||||
printf ("Starting os_stdlib_access_007\n");
|
||||
os_res = os_access("existing_file", OS_XOK);
|
||||
CU_ASSERT (os_res == os_resultFail);
|
||||
|
||||
/* Check correct functioning of os_access, existing file with no permissions existence */
|
||||
printf ("Starting os_stdlib_access_008\n");
|
||||
os_res = os_access("existing_file", OS_FOK);
|
||||
CU_ASSERT (os_res == os_resultSuccess);
|
||||
|
||||
/* Check correct functioning of os_access,
|
||||
existing file with read permissions read access */
|
||||
printf ("Starting os_stdlib_access_009\n");
|
||||
#ifdef WIN32
|
||||
fh= _creat("read_only", _S_IREAD); /* Note always has read & execute */
|
||||
if (fh != -1)
|
||||
_close(fh);
|
||||
#else
|
||||
fh= creat("read_only", S_IRUSR);
|
||||
if (fh != -1)
|
||||
close(fh);
|
||||
#endif /* WIN32 */
|
||||
os_res = os_access("read_only", OS_ROK);
|
||||
CU_ASSERT (os_res == os_resultSuccess);
|
||||
|
||||
/* Check correct functioning of os_access,
|
||||
existing file with read permissions write access */
|
||||
printf ("Starting os_stdlib_access_010\n");
|
||||
os_res = os_access("read_only", OS_WOK);
|
||||
CU_ASSERT (os_res == os_resultFail);
|
||||
|
||||
/* Check correct functioning of os_access,
|
||||
existing file with read permissions execute access */
|
||||
printf ("Starting os_stdlib_access_011\n");
|
||||
os_res = os_access("read_only", OS_XOK);
|
||||
CU_ASSERT (os_res == os_resultFail);
|
||||
|
||||
/* Check correct functioning of os_access,
|
||||
existing file with read permissions existence */
|
||||
printf ("Starting os_stdlib_access_012\n");
|
||||
os_res = os_access("read_only", OS_FOK);
|
||||
CU_ASSERT (os_res == os_resultSuccess);
|
||||
|
||||
/* Check correct functioning of os_access,
|
||||
existing file with write permissions read access */
|
||||
printf ("Starting os_stdlib_access_013\n");
|
||||
#ifdef WIN32
|
||||
fh= _creat("write_only", _S_IWRITE); /* Note windows automatically has read access can't have write only */
|
||||
if (fh != -1)
|
||||
_close(fh);
|
||||
wanted = os_resultSuccess;
|
||||
#else
|
||||
fh= creat("write_only", S_IWUSR);
|
||||
if (fh != -1)
|
||||
close(fh);
|
||||
wanted = os_resultFail;
|
||||
#endif /* WIN32 */
|
||||
os_res = os_access("write_only", OS_ROK);
|
||||
CU_ASSERT (os_res == wanted);
|
||||
|
||||
/* Check correct functioning of os_access,
|
||||
existing file with write permissions write access */
|
||||
printf ("Starting os_stdlib_access_014\n");
|
||||
os_res = os_access("write_only", OS_WOK);
|
||||
CU_ASSERT (os_res == os_resultSuccess);
|
||||
|
||||
/* Check correct functioning of os_access,
|
||||
existing file with write permissions execute access */
|
||||
printf ("Starting os_stdlib_access_015\n");
|
||||
os_res = os_access("write_only", OS_XOK);
|
||||
CU_ASSERT (os_res == os_resultFail);
|
||||
|
||||
/* Check correct functioning of os_access,
|
||||
existing file with write permissions existence */
|
||||
printf ("Starting os_stdlib_access_016\n");
|
||||
os_res = os_access("write_only", OS_FOK);
|
||||
CU_ASSERT (os_res == os_resultSuccess);
|
||||
|
||||
/* Check correct functioning of os_access,
|
||||
existing file with exec permissions read access */
|
||||
printf ("Starting os_stdlib_access_017\n");
|
||||
#ifdef WIN32
|
||||
fh= _creat("exec_only" OS_OS_EXESUFFIX, _S_IREAD); /* Windows always has read and can't do execute (that's based upon filename ext only) */
|
||||
if (fh != -1)
|
||||
_close(fh);
|
||||
wanted = os_resultSuccess;
|
||||
#else
|
||||
fh= creat("exec_only" OS_OS_EXESUFFIX, S_IXUSR);
|
||||
if (fh != -1)
|
||||
close(fh);
|
||||
wanted = os_resultFail;
|
||||
#endif /* WIN32 */
|
||||
os_res = os_access("exec_only" OS_OS_EXESUFFIX, OS_ROK);
|
||||
CU_ASSERT (os_res == wanted);
|
||||
|
||||
/* Check correct functioning of os_access,
|
||||
existing file with exec permissions write access */
|
||||
printf ("Starting os_stdlib_access_018\n");
|
||||
os_res = os_access("exec_only" OS_OS_EXESUFFIX, OS_WOK);
|
||||
CU_ASSERT (os_res == os_resultFail);
|
||||
|
||||
/* Check correct functioning of os_access,
|
||||
existing file with exec permissions execute access */
|
||||
printf ("Starting os_stdlib_access_019\n");
|
||||
os_res = os_access("exec_only" OS_OS_EXESUFFIX, OS_XOK);
|
||||
CU_ASSERT (os_res == os_resultSuccess);
|
||||
|
||||
/* Check correct functioning of os_access,
|
||||
existing file with exec permissions existence */
|
||||
printf ("Starting os_stdlib_access_020\n");
|
||||
os_res = os_access("exec_only" OS_OS_EXESUFFIX, OS_FOK);
|
||||
CU_ASSERT (os_res == os_resultSuccess);
|
||||
|
||||
/* Check correct functioning of os_access,
|
||||
existing file with read/write/exec permissions read access */
|
||||
printf ("Starting os_stdlib_access_021\n");
|
||||
#ifdef WIN32
|
||||
fh= _creat("read_write_exec" OS_OS_EXESUFFIX, _S_IREAD | _S_IWRITE); /* Windows always has read and can't do execute (that's based upon filename ext only) */
|
||||
if (fh != -1)
|
||||
_close(fh);
|
||||
#else
|
||||
fh= creat("read_write_exec" OS_OS_EXESUFFIX, S_IRUSR | S_IWUSR | S_IXUSR);
|
||||
if (fh != -1)
|
||||
close(fh);
|
||||
#endif /* WIN32 */
|
||||
os_res = os_access("read_write_exec" OS_OS_EXESUFFIX, OS_ROK);
|
||||
CU_ASSERT (os_res == os_resultSuccess);
|
||||
|
||||
/* Check correct functioning of os_access,
|
||||
existing file with read/write/exec permissions write access */
|
||||
printf ("Starting os_stdlib_access_022\n");
|
||||
os_res = os_access("read_write_exec" OS_OS_EXESUFFIX, OS_WOK);
|
||||
CU_ASSERT (os_res == os_resultSuccess);
|
||||
|
||||
/* Check correct functioning of os_access,
|
||||
existing file with read/write/exec permissions execute access */
|
||||
printf ("Starting os_stdlib_access_023\n");
|
||||
os_res = os_access("read_write_exec" OS_OS_EXESUFFIX, OS_XOK);
|
||||
CU_ASSERT (os_res == os_resultSuccess);
|
||||
|
||||
/* Check correct functioning of os_access,
|
||||
existing file with read/write/exec permissions existence */
|
||||
printf ("Starting os_stdlib_access_024\n");
|
||||
os_res = os_access("read_write_exec" OS_OS_EXESUFFIX, OS_FOK);
|
||||
CU_ASSERT (os_res == os_resultSuccess);
|
||||
|
||||
/* Check correct functioning of os_access,
|
||||
existing file with read/exec permissions read+write access */
|
||||
printf ("Starting os_stdlib_access_025\n");
|
||||
#ifdef WIN32
|
||||
fh= _creat("read_exec" OS_OS_EXESUFFIX, _S_IREAD); /* Windows always has read and can't do execute (that's based upon filename ext only) */
|
||||
if (fh != -1)
|
||||
_close(fh);
|
||||
#else
|
||||
fh= creat("read_exec" OS_OS_EXESUFFIX, S_IRUSR | S_IXUSR);
|
||||
if (fh != -1)
|
||||
close(fh);
|
||||
#endif /* WIN32 */
|
||||
os_res = os_access("read_exec" OS_OS_EXESUFFIX, OS_ROK|OS_WOK);
|
||||
CU_ASSERT (os_res == os_resultFail);
|
||||
|
||||
/* Check correct functioning of os_access,
|
||||
existing file with read/exec permissions write+exec access */
|
||||
printf ("Starting os_stdlib_access_026\n");
|
||||
os_res = os_access("read_exec" OS_OS_EXESUFFIX, OS_WOK|OS_XOK);
|
||||
CU_ASSERT (os_res == os_resultFail);
|
||||
|
||||
/* Check correct functioning of os_access,
|
||||
existing file with read/exec permissions read+exec access */
|
||||
printf ("Starting os_stdlib_access_027\n");
|
||||
os_res = os_access("read_exec" OS_OS_EXESUFFIX, OS_ROK|OS_XOK);
|
||||
CU_ASSERT (os_res == os_resultSuccess);
|
||||
|
||||
/* Check correct functioning of os_access,
|
||||
existing file with read/exec permissions read+exec+existence */
|
||||
printf ("Starting os_stdlib_access_028\n");
|
||||
os_res = os_access("read_exec" OS_OS_EXESUFFIX, OS_ROK|OS_XOK|OS_FOK);
|
||||
CU_ASSERT (os_res == os_resultSuccess);
|
||||
#endif /* VXWORKS */
|
||||
|
||||
printf ("Ending stdlib_os_access\n");
|
||||
}
|
||||
|
||||
CUnit_Test(os_stdlib, vsnprintf)
|
||||
{
|
||||
printf ("Starting os_stdlib_vsnprintf_001\n");
|
||||
CU_ASSERT (vsnprintfTest("%s","test") == 4);
|
||||
CU_ASSERT (vsnprintfTest("%d",12) == 2);
|
||||
CU_ASSERT (vsnprintfTest("hello %s","world") == 11);
|
||||
|
||||
printf ("Ending os_stdlib_vsnprintf\n");
|
||||
}
|
||||
|
||||
CUnit_Test(os_stdlib, strtok_r)
|
||||
{
|
||||
char * res;
|
||||
char *strtok_r_ts1;
|
||||
char *saveptr;
|
||||
|
||||
printf ("Starting os_stdlib_strtok_r_001\n");
|
||||
strtok_r_ts1= os_strdup("123,234");
|
||||
res = os_strtok_r( strtok_r_ts1, ",", &saveptr );
|
||||
CU_ASSERT (strcmp(res, "123") == 0);
|
||||
|
||||
printf ("Starting os_stdlib_strtok_r_002\n");
|
||||
res = os_strtok_r( NULL, ",", &saveptr );
|
||||
CU_ASSERT (strcmp(res, "234") == 0);
|
||||
|
||||
printf ("Starting os_stdlib_strtok_r_003\n");
|
||||
res = os_strtok_r( NULL, ",", &saveptr );
|
||||
CU_ASSERT (res == NULL);
|
||||
os_free(strtok_r_ts1);
|
||||
|
||||
printf ("Starting os_stdlib_strtok_r_004\n");
|
||||
strtok_r_ts1= os_strdup(",;,123abc,,456,:,");
|
||||
res = os_strtok_r( strtok_r_ts1, ",;", &saveptr );
|
||||
CU_ASSERT (strcmp(res, "123abc") == 0);
|
||||
|
||||
printf ("Starting os_stdlib_strtok_r_005\n");
|
||||
res = os_strtok_r( NULL, ",", &saveptr );
|
||||
CU_ASSERT (strcmp(res, "456") == 0);
|
||||
|
||||
printf ("Starting os_stdlib_strtok_r_006\n");
|
||||
res = os_strtok_r( NULL, ",:", &saveptr );
|
||||
CU_ASSERT (res == NULL);
|
||||
free(strtok_r_ts1);
|
||||
|
||||
printf ("Starting os_stdlib_strtok_r_007\n");
|
||||
strtok_r_ts1= os_strdup(",,,123,,456,789,,,");
|
||||
res = os_strtok_r( strtok_r_ts1, ",", &saveptr );
|
||||
CU_ASSERT (strcmp(res, "123") == 0);
|
||||
|
||||
printf ("Starting os_stdlib_strtok_r_008\n");
|
||||
res = os_strtok_r( NULL, ",", &saveptr );
|
||||
CU_ASSERT (strcmp(res, "456") == 0);
|
||||
|
||||
printf ("Starting os_stdlib_strtok_r_009\n");
|
||||
res = os_strtok_r( NULL, ",", &saveptr );
|
||||
CU_ASSERT (strcmp(res, "789") == 0);
|
||||
|
||||
printf ("Starting os_stdlib_strtok_r_010\n");
|
||||
res = os_strtok_r( NULL, ",:", &saveptr );
|
||||
CU_ASSERT (res == NULL);
|
||||
free(strtok_r_ts1);
|
||||
|
||||
printf ("Ending os_stdlib_strtok_r\n");
|
||||
}
|
||||
|
||||
CUnit_Test(os_stdlib, index)
|
||||
{
|
||||
char * res;
|
||||
char *index_ts1;
|
||||
printf ("Starting os_stdlib_index_001\n");
|
||||
index_ts1 = "abc";
|
||||
res = os_index( index_ts1, 'a' );
|
||||
CU_ASSERT (res == index_ts1);
|
||||
|
||||
printf ("Starting os_stdlib_index_002\n");
|
||||
res = os_index( index_ts1, 'c' );
|
||||
CU_ASSERT (res == &index_ts1[2]);
|
||||
|
||||
printf ("Starting os_stdlib_index_003\n");
|
||||
index_ts1 = "abcdefghij";
|
||||
res = os_index( index_ts1, 'f' );
|
||||
CU_ASSERT (res == &index_ts1[5]);
|
||||
|
||||
printf ("Starting os_stdlib_index_004\n");
|
||||
res = os_index( index_ts1, 'k' );
|
||||
CU_ASSERT (res == NULL);
|
||||
|
||||
printf ("Ending os_stdlib_index\n");
|
||||
}
|
||||
|
||||
CUnit_Test(os_stdlib, flockfile)
|
||||
{
|
||||
bool result = false;
|
||||
|
||||
os_osInit();
|
||||
|
||||
/* Check writing in a FILE from multiple threads without using os_flockfile. */
|
||||
printf ("Starting os_stdlib_flockfile_001\n");
|
||||
result = doFlockfileTest(false);
|
||||
CU_ASSERT (result);
|
||||
|
||||
/* Check writing in a FILE from multiple threads using os_flockfile in the first thread. */
|
||||
printf ("Starting os_stdlib_flockfile_002\n");
|
||||
result = doFlockfileTest(true);
|
||||
CU_ASSERT (result);
|
||||
|
||||
printf ("Ending os_stdlib_flockfile\n");
|
||||
|
||||
os_osExit();
|
||||
}
|
||||
|
||||
CUnit_Test(os_stdlib, getopt)
|
||||
{
|
||||
int c = 0;
|
||||
int argc = 3;
|
||||
char *argv001[] = {"", "-a", "-b"};
|
||||
char *argv002[] = {"", "-c", "foo"};
|
||||
char *argv003[] = {"", "-d"};
|
||||
|
||||
/* Check correct functioning of os_getopt */
|
||||
printf ("Starting os_stdlib_getopt_001\n");
|
||||
c = os_getopt(argc, argv001, "abc:");
|
||||
CU_ASSERT (c == 'a');
|
||||
c = os_getopt(argc, argv001, "abc:");
|
||||
CU_ASSERT (c == 'b');
|
||||
c = os_getopt(argc, argv001, "abc:");
|
||||
CU_ASSERT (c == -1);
|
||||
|
||||
/* Check correct functioning of os_set_optind and os_get_optind */
|
||||
printf ("Starting os_stdlib_getopt_002\n");
|
||||
os_set_optind(1);
|
||||
CU_ASSERT (os_get_optind() == 1);
|
||||
|
||||
/* Check correct functioning of os_get_optarg */
|
||||
printf ("Starting os_stdlib_getopt_003\n");
|
||||
c = os_getopt (argc, argv002, "c:");
|
||||
CU_ASSERT (c == 'c');
|
||||
CU_ASSERT (strcmp(os_get_optarg(), "foo") == 0);
|
||||
c = os_getopt(argc, argv002, "c:");
|
||||
CU_ASSERT (c == -1);
|
||||
|
||||
/* Check correct functioning of os_set_opterr, os_get_opterr and os_get_optopt */
|
||||
printf ("Starting os_stdlib_getopt_004\n");
|
||||
argc = 2;
|
||||
os_set_optind(1);
|
||||
os_set_opterr(0);
|
||||
CU_ASSERT(os_get_opterr() == 0)
|
||||
c = os_getopt (argc, argv003, "c:");
|
||||
CU_ASSERT (c == '?');
|
||||
CU_ASSERT (os_get_optopt() == 'd');
|
||||
|
||||
printf ("Ending os_stdlib_getopt\n");
|
||||
}
|
321
src/os/tests/strtoll.c
Normal file
321
src/os/tests/strtoll.c
Normal file
|
@ -0,0 +1,321 @@
|
|||
/*
|
||||
* Copyright(c) 2006 to 2018 ADLINK Technology Limited and others
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License v. 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
|
||||
* v. 1.0 which is available at
|
||||
* http://www.eclipse.org/org/documents/edl-v10.php.
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
|
||||
*/
|
||||
#include "CUnit/Runner.h"
|
||||
#include "os/os.h"
|
||||
|
||||
long long ll;
|
||||
unsigned long long ull;
|
||||
const char *str;
|
||||
char *ptr;
|
||||
char buf[100];
|
||||
char str_llmin[100];
|
||||
char str_llmax[100];
|
||||
char str_ullmax[100];
|
||||
char str_llrange[100];
|
||||
char str_ullrange[100];
|
||||
|
||||
char str_xllmin[99], str_xllmax[99];
|
||||
|
||||
/* Really test with the maximum values supported on a platform, not some
|
||||
made up number. */
|
||||
long long llmin = OS_MIN_INTEGER(long long);
|
||||
long long llmax = OS_MAX_INTEGER(long long);
|
||||
unsigned long long ullmax = OS_MAX_INTEGER(unsigned long long);
|
||||
|
||||
CUnit_Suite_Initialize(os_str_convert)
|
||||
{
|
||||
int result = 0;
|
||||
os_osInit();
|
||||
printf("Run os_str_convert_Initialize\n");
|
||||
|
||||
(void)snprintf (str_llmin, sizeof(str_llmin), "%lld", llmin);
|
||||
(void)snprintf (str_llmax, sizeof(str_llmax), "%lld", llmax);
|
||||
(void)snprintf (str_llrange, sizeof(str_llrange), "%lld1", llmax);
|
||||
(void)snprintf (str_ullmax, sizeof(str_ullmax), "%llu", ullmax);
|
||||
(void)snprintf (str_ullrange, sizeof(str_ullrange), "%llu1", ullmax);
|
||||
(void)snprintf (str_xllmin, sizeof(str_xllmin), "-%llx", llmin);
|
||||
(void)snprintf (str_xllmax, sizeof(str_xllmax), "+%llx", llmax);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
CUnit_Suite_Cleanup(os_str_convert)
|
||||
{
|
||||
int result = 0;
|
||||
|
||||
printf("Run os_str_convert_Cleanup\n");
|
||||
os_osExit();
|
||||
return result;
|
||||
}
|
||||
|
||||
CUnit_Test(os_str_convert, strtoll)
|
||||
{
|
||||
printf ("Starting os_strtoll_001a\n");
|
||||
str = "gibberish";
|
||||
ll = os_strtoll(str, &ptr, 0);
|
||||
CU_ASSERT (ll == 0 && ptr == str);
|
||||
|
||||
printf ("Starting os_strtoll_001b\n");
|
||||
str = "+gibberish";
|
||||
ll = os_strtoll(str, &ptr, 0);
|
||||
CU_ASSERT (ll == 0 && ptr == str);
|
||||
|
||||
printf ("Starting os_strtoll_001c\n");
|
||||
str = "-gibberish";
|
||||
ll = os_strtoll(str, &ptr, 0);
|
||||
CU_ASSERT (ll == 0 && ptr == str);
|
||||
|
||||
printf ("Starting os_strtoll_001d\n");
|
||||
str = "gibberish";
|
||||
ptr = NULL;
|
||||
errno=0;
|
||||
ll = os_strtoll(str, &ptr, 36);
|
||||
CU_ASSERT (ll == 46572948005345 && errno == 0 && ptr && *ptr == '\0');
|
||||
|
||||
printf ("Starting os_strtoll_001e\n");
|
||||
str = "1050505055";
|
||||
ptr = NULL;
|
||||
errno = 0;
|
||||
ll = os_strtoll(str, &ptr, 37);
|
||||
CU_ASSERT (ll == 0LL && errno == EINVAL && ptr == str);
|
||||
|
||||
printf ("Starting os_strtoll_001f\n");
|
||||
str = " \t \n 1050505055";
|
||||
ll = os_strtoll(str, NULL, 10);
|
||||
CU_ASSERT (ll == 1050505055LL);
|
||||
|
||||
printf ("Starting os_strtoll_001g\n");
|
||||
str = " \t \n -1050505055";
|
||||
ptr = NULL;
|
||||
ll = os_strtoll(str, &ptr, 10);
|
||||
CU_ASSERT (ll == -1050505055LL);
|
||||
|
||||
printf ("Starting os_strtoll_001h\n");
|
||||
str = " \t \n - \t \n 1050505055";
|
||||
ptr = NULL;
|
||||
ll = os_strtoll(str, &ptr, 10);
|
||||
CU_ASSERT (ll == 0LL && ptr == str);
|
||||
|
||||
printf ("Starting os_strtoll_002a\n");
|
||||
str = "10x";
|
||||
ptr = NULL;
|
||||
ll = os_strtoll(str, &ptr, 10);
|
||||
CU_ASSERT (ll == 10LL && ptr && *ptr == 'x');
|
||||
|
||||
printf ("Starting os_strtoll_002b\n");
|
||||
str = "+10x";
|
||||
ll = os_strtoll(str, &ptr, 10);
|
||||
CU_ASSERT (ll == 10LL && ptr && *ptr == 'x');
|
||||
|
||||
printf ("Starting os_strtoll_002c\n");
|
||||
str = "-10x";
|
||||
ll = os_strtoll(str, &ptr, 10);
|
||||
CU_ASSERT (ll == -10LL && ptr && *ptr == 'x');
|
||||
|
||||
printf ("Starting os_strtoll_002d\n");
|
||||
str = (const char *)str_llmax;
|
||||
ll = os_strtoll(str, NULL, 10);
|
||||
CU_ASSERT (ll == llmax);
|
||||
|
||||
printf ("Starting os_strtoll_002e\n");
|
||||
str = (const char *)str_llmin;
|
||||
ll = os_strtoll(str, NULL, 10);
|
||||
CU_ASSERT (ll == llmin);
|
||||
|
||||
printf ("Starting os_strtoll_002f\n");
|
||||
str = (const char *)str_llrange;
|
||||
ll = os_strtoll(str, &ptr, 10);
|
||||
CU_ASSERT (ll == llmax && *ptr == '1');
|
||||
|
||||
printf ("Starting os_strtoll_003a\n");
|
||||
str = "0x100";
|
||||
ll = os_strtoll(str, NULL, 16);
|
||||
CU_ASSERT (ll == 0x100LL);
|
||||
|
||||
printf ("Starting os_strtoll_003b\n");
|
||||
str = "0X100";
|
||||
ll = os_strtoll(str, NULL, 16);
|
||||
CU_ASSERT (ll == 0x100LL);
|
||||
|
||||
printf ("Starting os_strtoll_003c\n");
|
||||
str = "0x1DEFCAB";
|
||||
ll = os_strtoll(str, NULL, 16);
|
||||
CU_ASSERT (ll == 0x1DEFCABLL);
|
||||
|
||||
printf ("Starting os_strtoll_003d\n");
|
||||
str = "0x1defcab";
|
||||
ll = os_strtoll(str, NULL, 16);
|
||||
CU_ASSERT (ll == 0x1DEFCABLL);
|
||||
|
||||
printf ("Starting os_strtoll_003e\n");
|
||||
str = (char *)str_xllmin;
|
||||
ll = os_strtoll(str, NULL, 16);
|
||||
CU_ASSERT (ll == llmin);
|
||||
|
||||
printf ("Starting os_strtoll_003f\n");
|
||||
str = (char *)str_xllmax;
|
||||
ll = os_strtoll(str, NULL, 16);
|
||||
CU_ASSERT (ll == llmax);
|
||||
|
||||
printf ("Starting os_strtoll_003g\n");
|
||||
str = "0x100";
|
||||
ll = os_strtoll(str, NULL, 0);
|
||||
CU_ASSERT (ll == 0x100LL);
|
||||
|
||||
printf ("Starting os_strtoll_003h\n");
|
||||
str = "100";
|
||||
ll = os_strtoll(str, NULL, 16);
|
||||
CU_ASSERT (ll == 0x100LL);
|
||||
|
||||
printf ("Starting os_strtoll_003i\n");
|
||||
/* calling os_strtoll with \"%s\" and base 10, expected result 0 */
|
||||
str = "0x100";
|
||||
ll = os_strtoll(str, &ptr, 10);
|
||||
CU_ASSERT (ll == 0 && ptr && *ptr == 'x');
|
||||
|
||||
printf ("Starting os_strtoll_003j\n");
|
||||
/* calling os_strtoll with \"%s\" and base 0, expected result 256 */
|
||||
str = "0x100g";
|
||||
ll = os_strtoll(str, &ptr, 0);
|
||||
CU_ASSERT (ll == 256 && ptr && *ptr == 'g');
|
||||
|
||||
printf ("Starting os_strtoll_004a\n");
|
||||
str = "0100";
|
||||
ll = os_strtoll(str, NULL, 0);
|
||||
CU_ASSERT(ll == 64LL);
|
||||
|
||||
printf ("Starting os_strtoll_004b\n");
|
||||
str = "0100";
|
||||
ll = os_strtoll(str, NULL, 8);
|
||||
CU_ASSERT(ll == 64LL);
|
||||
|
||||
printf ("Starting os_strtoll_004c\n");
|
||||
str = "100";
|
||||
ll = os_strtoll(str, NULL, 8);
|
||||
CU_ASSERT(ll == 64LL);
|
||||
|
||||
printf ("Starting os_strtoll_004d\n");
|
||||
/* calling os_strtoll with \"%s\" and base 10, expected result 100 */
|
||||
str = "0100";
|
||||
ll = os_strtoll(str, &ptr, 10);
|
||||
CU_ASSERT(ll == 100);
|
||||
|
||||
printf ("Starting os_strtoll_004e\n");
|
||||
/* calling os_strtoll with \"%s\" and base 0, expected result 64 */
|
||||
str = "01008";
|
||||
ll = os_strtoll(str, &ptr, 8);
|
||||
CU_ASSERT(ll == 64LL && ptr && *ptr == '8');
|
||||
|
||||
printf ("Starting os_strtoll_004f\n");
|
||||
str = "00001010";
|
||||
ll = os_strtoll(str, NULL, 2);
|
||||
CU_ASSERT(ll == 10LL);
|
||||
|
||||
printf ("Ending os_strtoll\n");
|
||||
}
|
||||
|
||||
CUnit_Test(os_str_convert, strtoull)
|
||||
{
|
||||
printf ("Starting os_strtoull_001a\n");
|
||||
str = "0xffffffffffffffff";
|
||||
ull = os_strtoull(str, NULL, 0);
|
||||
CU_ASSERT(ull == ullmax);
|
||||
|
||||
printf ("Starting os_strtoull_001b\n");
|
||||
str = "-1";
|
||||
ull = os_strtoull(str, NULL, 0);
|
||||
CU_ASSERT(ull == ullmax);
|
||||
|
||||
printf ("Starting os_strtoull_001c\n");
|
||||
str = "-2";
|
||||
ull = os_strtoull(str, NULL, 0);
|
||||
CU_ASSERT(ull == (ullmax - 1));
|
||||
|
||||
printf ("Ending os_strtoull\n");
|
||||
}
|
||||
|
||||
CUnit_Test(os_str_convert, atoll)
|
||||
{
|
||||
printf ("Starting os_atoll_001\n");
|
||||
str = "10";
|
||||
ll = os_atoll(str);
|
||||
CU_ASSERT(ll == 10);
|
||||
|
||||
printf ("Ending os_atoll\n");
|
||||
}
|
||||
|
||||
CUnit_Test(os_str_convert, atoull)
|
||||
{
|
||||
printf ("Starting os_atoull_001\n");
|
||||
str = "10";
|
||||
ull = os_atoull(str);
|
||||
CU_ASSERT(ull == 10);
|
||||
|
||||
printf ("Ending tc_os_atoull\n");
|
||||
}
|
||||
|
||||
CUnit_Test(os_str_convert, lltostr)
|
||||
{
|
||||
printf ("Starting os_lltostr_001\n");
|
||||
ll = llmax;
|
||||
ptr = os_lltostr(ll, buf, 0, NULL);
|
||||
CU_ASSERT(ptr == NULL);
|
||||
|
||||
printf ("Starting os_lltostr_002\n");
|
||||
/* calling os_lltostr with %lld with buffer size of 5, expected result \"5432\" */
|
||||
ll = 54321;
|
||||
ptr = os_lltostr(ll, buf, 5, NULL);
|
||||
CU_ASSERT(strcmp(ptr, "5432") == 0);
|
||||
|
||||
printf ("Starting os_lltostr_003a\n");
|
||||
ll = llmax;
|
||||
ptr = os_lltostr(ll, buf, sizeof(buf), NULL);
|
||||
CU_ASSERT(strcmp(ptr, str_llmax) == 0);
|
||||
|
||||
printf ("Starting os_lltostr_003b\n");
|
||||
ll = llmin;
|
||||
ptr = os_lltostr(ll, buf, sizeof(buf), NULL);
|
||||
CU_ASSERT(strcmp(ptr, str_llmin) == 0);
|
||||
|
||||
printf ("Starting os_lltostr_004\n");
|
||||
ll = 1;
|
||||
ptr = os_lltostr(ll, buf, sizeof(buf), NULL);
|
||||
CU_ASSERT(strcmp(ptr, "1") == 0);
|
||||
|
||||
printf ("Starting os_lltostr_005\n");
|
||||
ll = 0;
|
||||
ptr = os_lltostr(ll, buf, sizeof(buf), NULL);
|
||||
CU_ASSERT(strcmp(ptr, "0") == 0);
|
||||
|
||||
printf ("Starting os_lltostr_006\n");
|
||||
ll = -1;
|
||||
ptr = os_lltostr(ll, buf, sizeof(buf), NULL);
|
||||
CU_ASSERT(strcmp(ptr, "-1") == 0);
|
||||
|
||||
printf ("Ending os_lltostr\n");
|
||||
}
|
||||
|
||||
CUnit_Test(os_str_convert, ulltostr)
|
||||
{
|
||||
printf ("Starting os_ulltostr_001\n");
|
||||
ull = ullmax;
|
||||
ptr = os_ulltostr(ull, buf, sizeof(buf), NULL);
|
||||
CU_ASSERT(strcmp(ptr, str_ullmax) == 0);
|
||||
|
||||
printf ("Starting os_ulltostr_002\n");
|
||||
ull = 0ULL;
|
||||
ptr = os_ulltostr(ull, buf, sizeof(buf), NULL);
|
||||
CU_ASSERT(strcmp(ptr, "0") == 0);
|
||||
|
||||
printf ("Ending os_ulltostr\n");
|
||||
}
|
||||
|
842
src/os/tests/thread.c
Normal file
842
src/os/tests/thread.c
Normal file
|
@ -0,0 +1,842 @@
|
|||
/*
|
||||
* Copyright(c) 2006 to 2018 ADLINK Technology Limited and others
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License v. 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
|
||||
* v. 1.0 which is available at
|
||||
* http://www.eclipse.org/org/documents/edl-v10.php.
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
|
||||
*/
|
||||
#include "CUnit/Runner.h"
|
||||
#include "os/os.h"
|
||||
#include "assert.h"
|
||||
|
||||
#define ENABLE_TRACING 0
|
||||
|
||||
char arg_result[30];
|
||||
int threadCalled;
|
||||
int startCallbackCount;
|
||||
int stopCallbackCount;
|
||||
void *returnval;
|
||||
|
||||
static void
|
||||
sleepMsec(int32_t msec)
|
||||
{
|
||||
os_time delay;
|
||||
|
||||
assert(msec > 0);
|
||||
assert(msec < 1000);
|
||||
|
||||
delay.tv_sec = 0;
|
||||
delay.tv_nsec = msec*1000*1000;
|
||||
|
||||
os_nanoSleep(delay);
|
||||
}
|
||||
|
||||
uint32_t new_thread (_In_ void *args)
|
||||
{
|
||||
(void)snprintf (arg_result, sizeof (arg_result), "%s", (char *)args);
|
||||
sleepMsec (500);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static uintmax_t thread_id_from_thread;
|
||||
|
||||
uint32_t threadId_thread (_In_opt_ void *args)
|
||||
{
|
||||
if (args != NULL) {
|
||||
sleepMsec (500);
|
||||
}
|
||||
thread_id_from_thread = os_threadIdToInteger (os_threadIdSelf ());
|
||||
return (uint32_t)thread_id_from_thread; /* Truncates potentially; just used for checking passing a result-value. */
|
||||
}
|
||||
|
||||
uint32_t get_threadExit_thread (void *args)
|
||||
{
|
||||
os_threadId * threadId = args;
|
||||
uint32_t id;
|
||||
os_result ret = os_threadWaitExit (*threadId, &id);
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
uint32_t threadIdentity_thread (_In_ void *args)
|
||||
{
|
||||
char *identity = args;
|
||||
os_threadFigureIdentity (identity, 512);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static uint32_t threadMain(_In_opt_ void *args)
|
||||
{
|
||||
OS_UNUSED_ARG(args);
|
||||
threadCalled = 1;
|
||||
sleepMsec(500);
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32_t threadMemory_thread (_In_opt_ void *args)
|
||||
{
|
||||
OS_UNUSED_ARG(args);
|
||||
|
||||
/* Check os_threadMemMalloc with success result for child thread */
|
||||
printf("Starting os_threadMemMalloc_003\n");
|
||||
returnval = os_threadMemMalloc (3, 100);
|
||||
CU_ASSERT (returnval != NULL);
|
||||
|
||||
/* Check os_threadMemMalloc with fail result for child thread for index already in use */
|
||||
printf("Starting os_threadMemMalloc_004\n");
|
||||
returnval = os_threadMemMalloc (3, 100);
|
||||
CU_ASSERT (returnval == NULL);
|
||||
|
||||
/* Check os_threadMemGet for child thread and non allocated index */
|
||||
printf("Starting os_threadMemGet_003\n");
|
||||
returnval = os_threadMemGet (OS_THREAD_WARNING);
|
||||
CU_ASSERT (returnval == NULL);
|
||||
|
||||
/* Check os_threadMemGet for child thread and allocated index */
|
||||
printf("Starting os_threadMemGet_004\n");
|
||||
returnval = os_threadMemGet (3);
|
||||
CU_ASSERT (returnval != NULL);
|
||||
|
||||
/* Check os_threadMemFree for child thread and non allocated index */
|
||||
printf("Starting os_threadMemFree_003\n");
|
||||
os_threadMemFree (OS_THREAD_WARNING);
|
||||
returnval = os_threadMemGet (OS_THREAD_WARNING);
|
||||
CU_ASSERT (returnval == NULL);
|
||||
|
||||
/* Check os_threadMemFree for child thread and allocated index */
|
||||
printf("Starting os_threadMemFree_004\n");
|
||||
os_threadMemFree (3);
|
||||
returnval = os_threadMemGet (3);
|
||||
CU_ASSERT (returnval == NULL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
CUnit_Suite_Initialize(os_thread)
|
||||
{
|
||||
int result = 0;
|
||||
os_osInit();
|
||||
printf("Run os_thread_Initialize\n");
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
CUnit_Suite_Cleanup(os_thread)
|
||||
{
|
||||
int result = 0;
|
||||
|
||||
printf("Run os_thread_Cleanup\n");
|
||||
os_osExit();
|
||||
return result;
|
||||
}
|
||||
|
||||
CUnit_Test(os_thread, create)
|
||||
{
|
||||
int result;
|
||||
os_threadId thread_os_threadId;
|
||||
os_threadAttr thread_os_threadAttr;
|
||||
#ifndef WIN32
|
||||
int result_int;
|
||||
#endif
|
||||
|
||||
/* Check os_threadCreate with Success result\n\t\t
|
||||
(check thread creation and check argument passing) */
|
||||
printf ("Starting os_thread_create_001\n");
|
||||
os_threadAttrInit (&thread_os_threadAttr);
|
||||
result = os_threadCreate (&thread_os_threadId, "ThreadCreate1", &thread_os_threadAttr, &new_thread, "os_threadCreate");
|
||||
CU_ASSERT (result == os_resultSuccess);
|
||||
if (result == os_resultSuccess) {
|
||||
#ifdef _WRS_KERNEL
|
||||
taskDelay(1 * sysClkRateGet());
|
||||
#endif
|
||||
result = os_threadWaitExit (thread_os_threadId, NULL);
|
||||
CU_ASSERT (result == os_resultSuccess);
|
||||
|
||||
if (result == os_resultSuccess) {
|
||||
result = strcmp (arg_result, "os_threadCreate");
|
||||
CU_ASSERT (result == 0);
|
||||
if (result == 0)
|
||||
printf("Thread created and argument correctly passed.\n");
|
||||
else
|
||||
printf("Thread created but argument incorrectly passed.\n");
|
||||
} else {
|
||||
printf("os_threadCreate success, failed os_threadWaitExit.\n");
|
||||
}
|
||||
}
|
||||
|
||||
/* Check os_threadCreate with Failed result */
|
||||
printf ("Starting os_thread_create_002\n");
|
||||
printf ("N.A - Failure cannot be forced\n");
|
||||
|
||||
/* Check os_threadCreate with scheduling class SCHED_DEFAULT */
|
||||
printf ("Starting s_thread_create_003\n");
|
||||
os_threadAttrInit (&thread_os_threadAttr);
|
||||
thread_os_threadAttr.schedClass = OS_SCHED_DEFAULT;
|
||||
result = os_threadCreate (&thread_os_threadId, "ThreadCreate3", &thread_os_threadAttr, &new_thread, "os_threadCreate");
|
||||
CU_ASSERT (result == os_resultSuccess);
|
||||
|
||||
#if !(defined _WRS_KERNEL || defined WIN32)
|
||||
if (result == os_resultSuccess) {
|
||||
int policy;
|
||||
struct sched_param sched_param;
|
||||
|
||||
result_int = pthread_getschedparam (thread_os_threadId.v, &policy, &sched_param);
|
||||
CU_ASSERT (result_int == 0);
|
||||
|
||||
if (result_int != 0) {
|
||||
printf ("pthread_getschedparam failed");
|
||||
} else {
|
||||
CU_ASSERT (policy == SCHED_OTHER);
|
||||
}
|
||||
result = os_threadWaitExit (thread_os_threadId, NULL);
|
||||
CU_ASSERT (result == os_resultSuccess);
|
||||
} else {
|
||||
printf ("os_threadCreate failed.\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
/* SCHED_TIMESHARE not supported by vxworks kernel */
|
||||
#ifndef _WRS_KERNEL
|
||||
/* Check os_threadCreate with scheduling class SCHED_TIMESHARE */
|
||||
printf ("Starting os_thread_create_004\n");
|
||||
os_threadAttrInit (&thread_os_threadAttr);
|
||||
thread_os_threadAttr.schedClass = OS_SCHED_TIMESHARE;
|
||||
result = os_threadCreate (&thread_os_threadId, "ThreadCreate4", &thread_os_threadAttr, &new_thread, "os_threadCreate");
|
||||
CU_ASSERT (result == os_resultSuccess);
|
||||
if (result == os_resultSuccess) {
|
||||
#ifndef WIN32
|
||||
int policy;
|
||||
struct sched_param sched_param;
|
||||
|
||||
result_int = pthread_getschedparam (thread_os_threadId.v, &policy, &sched_param);
|
||||
CU_ASSERT (result_int == 0);
|
||||
|
||||
if (result_int != 0) {
|
||||
printf ("pthread_getschedparam failed");
|
||||
} else {
|
||||
CU_ASSERT (policy == SCHED_OTHER);
|
||||
}
|
||||
#endif /* WIN32 */
|
||||
|
||||
result = os_threadWaitExit (thread_os_threadId, NULL);
|
||||
} else {
|
||||
printf ("os_threadCreate failed.\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Check os_threadCreate with scheduling class SCHED_REALTIME */
|
||||
printf ("Starting tc_os_thread_create_005\n");
|
||||
#if ! defined WIN32 && ! defined _WRS_KERNEL
|
||||
#ifndef VXWORKS_RTP
|
||||
if (getuid() != 0 && geteuid() != 0) {
|
||||
printf ("N.A - Need root privileges to do the test\n");
|
||||
}
|
||||
else
|
||||
#endif /* VXWORKS_RTP */
|
||||
{
|
||||
os_threadAttrInit (&thread_os_threadAttr);
|
||||
thread_os_threadAttr.schedClass = OS_SCHED_REALTIME;
|
||||
thread_os_threadAttr.schedPriority = sched_get_priority_min (SCHED_FIFO);
|
||||
result = os_threadCreate (&thread_os_threadId, "ThreadCreate5", &thread_os_threadAttr, &new_thread, "os_threadCreate");
|
||||
CU_ASSERT (result == os_resultSuccess);
|
||||
if (result == os_resultSuccess) {
|
||||
int policy;
|
||||
struct sched_param sched_param;
|
||||
|
||||
result_int = pthread_getschedparam (thread_os_threadId.v, &policy, &sched_param);
|
||||
CU_ASSERT (result_int == 0);
|
||||
|
||||
if (result_int == 0) {
|
||||
CU_ASSERT (policy == SCHED_FIFO);
|
||||
} else {
|
||||
printf ("pthread_getschedparam failed\n");
|
||||
}
|
||||
result = os_threadWaitExit (thread_os_threadId, NULL);
|
||||
} else {
|
||||
printf ("os_threadCreate failed\n");
|
||||
}
|
||||
}
|
||||
#else /* WIN32 */
|
||||
printf ("N.A - Not tested on Windows or vxworks kernel\n");
|
||||
#endif
|
||||
|
||||
/* Check os_threadCreate with scheduling class SCHED_TIMESHARE and min priority */
|
||||
printf ("Starting os_thread_create_006\n");
|
||||
#ifndef WIN32
|
||||
os_threadAttrInit (&thread_os_threadAttr);
|
||||
thread_os_threadAttr.schedClass = OS_SCHED_TIMESHARE;
|
||||
#ifdef _WRS_KERNEL
|
||||
thread_os_threadAttr.schedPriority = 250;
|
||||
#else
|
||||
thread_os_threadAttr.schedPriority = sched_get_priority_min (SCHED_OTHER);
|
||||
#endif
|
||||
result = os_threadCreate (&thread_os_threadId, "ThreadCreate6", &thread_os_threadAttr, &new_thread, "os_threadCreate");
|
||||
#ifdef _WRS_KERNEL
|
||||
if (result == os_resultSuccess)
|
||||
printf ("os_threadCreate failed - Expected failure from VXWORKS\n");
|
||||
else
|
||||
printf ("OS_SCHED_TIMESHARE not supported\n");
|
||||
#else
|
||||
CU_ASSERT (result == os_resultSuccess);
|
||||
|
||||
if (result == os_resultSuccess) {
|
||||
int policy;
|
||||
struct sched_param sched_param;
|
||||
|
||||
result_int = pthread_getschedparam (thread_os_threadId.v, &policy, &sched_param);
|
||||
CU_ASSERT (result_int == 0);
|
||||
|
||||
if (result_int == 0) {
|
||||
CU_ASSERT (sched_param.sched_priority == sched_get_priority_min (SCHED_OTHER));
|
||||
} else {
|
||||
printf ("pthread_getschedparam failed\n");
|
||||
}
|
||||
result = os_threadWaitExit (thread_os_threadId, NULL);
|
||||
} else {
|
||||
printf ("os_threadCreate failed.\n");
|
||||
}
|
||||
#endif /* _WRS_KERNEL */
|
||||
#else
|
||||
printf ("N.A - Not tested on Windows.\n");
|
||||
#endif /* WIN32 */
|
||||
|
||||
/* Check os_threadCreate with scheduling class SCHED_TIMESHARE and max priority */
|
||||
printf ("Starting os_thread_create_007\n");
|
||||
#ifndef WIN32
|
||||
os_threadAttrInit (&thread_os_threadAttr);
|
||||
thread_os_threadAttr.schedClass = OS_SCHED_TIMESHARE;
|
||||
#ifdef _WRS_KERNEL
|
||||
thread_os_threadAttr.schedPriority = 60;
|
||||
#else
|
||||
thread_os_threadAttr.schedPriority = sched_get_priority_max (SCHED_OTHER);
|
||||
#endif
|
||||
result = os_threadCreate (&thread_os_threadId, "ThreadCreate7", &thread_os_threadAttr, &new_thread, "os_threadCreate");
|
||||
#ifdef _WRS_KERNEL
|
||||
if (result == os_resultSuccess) {
|
||||
printf ("os_threadCreate failed - Expected failure from VXWORKS\n");
|
||||
} else {
|
||||
printf ("OS_SCHED_TIMESHARE not supported\n");
|
||||
}
|
||||
#else
|
||||
CU_ASSERT (result == os_resultSuccess);
|
||||
|
||||
if (result == os_resultSuccess) {
|
||||
int policy;
|
||||
struct sched_param sched_param;
|
||||
|
||||
result_int = pthread_getschedparam (thread_os_threadId.v, &policy, &sched_param);
|
||||
CU_ASSERT (result_int == 0);
|
||||
|
||||
if (result_int == 0) {
|
||||
CU_ASSERT (sched_param.sched_priority == sched_get_priority_max (SCHED_OTHER));
|
||||
} else {
|
||||
printf ("pthread_getschedparam failed\n");
|
||||
}
|
||||
result = os_threadWaitExit (thread_os_threadId, NULL);
|
||||
} else {
|
||||
printf ("os_threadCreate failed.\n");
|
||||
}
|
||||
#endif /* _WRS_KERNEL */
|
||||
#else
|
||||
printf ("N.A - Not tested on Windows.\n");
|
||||
#endif /* WIN32 */
|
||||
|
||||
/* Check os_threadCreate with scheduling class SCHED_REALTIME and min priority */
|
||||
printf ("Starting os_thread_create_008\n");
|
||||
#ifndef WIN32
|
||||
#ifndef VXWORKS_RTP
|
||||
if (getuid() != 0 && geteuid() != 0)
|
||||
{
|
||||
printf ("N.A - Need root privileges to do the test\n");
|
||||
}
|
||||
else
|
||||
#endif /* VXWORKS_RTP */
|
||||
{
|
||||
os_threadAttrInit (&thread_os_threadAttr);
|
||||
thread_os_threadAttr.schedClass = OS_SCHED_REALTIME;
|
||||
#ifdef _WRS_KERNEL
|
||||
thread_os_threadAttr.schedPriority = 250;
|
||||
#else
|
||||
thread_os_threadAttr.schedPriority = sched_get_priority_min (SCHED_FIFO);
|
||||
#endif
|
||||
result = os_threadCreate (&thread_os_threadId, "ThreadCreate8", &thread_os_threadAttr, &new_thread, "os_threadCreate");
|
||||
CU_ASSERT (result == os_resultSuccess);
|
||||
|
||||
if (result == os_resultSuccess) {
|
||||
#ifdef _WRS_KERNEL
|
||||
TASK_ID id;
|
||||
int pri;
|
||||
STATUS status;
|
||||
sleepSeconds (2);
|
||||
pri = 0;
|
||||
id = taskNameToId("ThreadCreate8");
|
||||
status = taskPriorityGet(id,&pri);
|
||||
CU_ASSERT (status == OK);
|
||||
CU_ASSERT (pri == 250);
|
||||
#else
|
||||
int policy;
|
||||
struct sched_param sched_param;
|
||||
|
||||
result_int = pthread_getschedparam (thread_os_threadId.v, &policy, &sched_param);
|
||||
CU_ASSERT (result_int == 0);
|
||||
|
||||
if (result_int == 0) {
|
||||
CU_ASSERT (sched_param.sched_priority == sched_get_priority_min (SCHED_FIFO));
|
||||
} else {
|
||||
printf ("pthread_getschedparam failed.\n");
|
||||
}
|
||||
#endif /* _WRS_KERNEL */
|
||||
result = os_threadWaitExit (thread_os_threadId, NULL);
|
||||
} else {
|
||||
printf ("os_threadCreate failed.\n");
|
||||
}
|
||||
}
|
||||
#else /* WIN32 */
|
||||
printf ("N.A - Not tested on Windows\n");
|
||||
#endif
|
||||
|
||||
/* Check os_threadCreate with scheduling class SCHED_REALTIME and max priority */
|
||||
printf ("Starting os_thread_create_009\n");
|
||||
#ifndef WIN32
|
||||
#ifndef VXWORKS_RTP
|
||||
if (getuid() != 0 && geteuid() != 0)
|
||||
{
|
||||
printf ("N.A - Need root privileges to do the test\n");
|
||||
}
|
||||
else
|
||||
#endif /* VXWORKS_RTP */
|
||||
{
|
||||
os_threadAttrInit (&thread_os_threadAttr);
|
||||
thread_os_threadAttr.schedClass = OS_SCHED_REALTIME;
|
||||
#ifdef _WRS_KERNEL
|
||||
thread_os_threadAttr.schedPriority = 250;
|
||||
#else
|
||||
thread_os_threadAttr.schedPriority = sched_get_priority_max (SCHED_FIFO);
|
||||
#endif
|
||||
result = os_threadCreate (&thread_os_threadId, "ThreadCreate9", &thread_os_threadAttr, &new_thread, "os_threadCreate");
|
||||
CU_ASSERT (result == os_resultSuccess);
|
||||
|
||||
if (result == os_resultSuccess) {
|
||||
#ifdef _WRS_KERNEL
|
||||
int status;
|
||||
sleepSeconds (2);
|
||||
status = 0;
|
||||
taskPriorityGet(taskNameToId("ThreadCreate9"),&status);
|
||||
CU_ASSERT (status == 250);
|
||||
#else
|
||||
int policy;
|
||||
struct sched_param sched_param;
|
||||
|
||||
result_int = pthread_getschedparam (thread_os_threadId.v, &policy, &sched_param);
|
||||
CU_ASSERT (result_int == 0);
|
||||
|
||||
if (result_int == 0) {
|
||||
CU_ASSERT (sched_param.sched_priority == sched_get_priority_max (SCHED_FIFO));
|
||||
} else {
|
||||
printf ("pthread_getschedparam failed.\n");
|
||||
}
|
||||
#endif
|
||||
result = os_threadWaitExit (thread_os_threadId, NULL);
|
||||
} else {
|
||||
printf ("os_threadCreate failed.\n");
|
||||
}
|
||||
}
|
||||
#else /* WIN32 */
|
||||
printf ("N.A - Not tested on Windows\n");
|
||||
#endif
|
||||
|
||||
/* Check os_threadCreate by checking scheduling scope PTHREAD_SCOPE_SYSTEM */
|
||||
printf ("Starting os_thread_create_010\n");
|
||||
printf ("N.A - No way to queuery scope from running thread");
|
||||
|
||||
/* Check os_threadCreate and stacksize sttribute */
|
||||
printf ("Starting os_thread_create_011\n");
|
||||
printf ("N.A - No way to queuery scope from running thread");
|
||||
|
||||
printf ("Ending os_thread_create\n");
|
||||
}
|
||||
|
||||
CUnit_Test(os_thread, idself)
|
||||
{
|
||||
os_threadId thread_os_threadId;
|
||||
os_threadAttr thread_os_threadAttr;
|
||||
int result;
|
||||
uint32_t result_from_thread;
|
||||
|
||||
/* Check if own thread ID is correctly provided */
|
||||
printf ("Starting tc_os_threadIdSelf_001\n");
|
||||
os_threadAttrInit (&thread_os_threadAttr);
|
||||
result = os_threadCreate (&thread_os_threadId, "OwnThreadId", &thread_os_threadAttr, &threadId_thread, NULL);
|
||||
CU_ASSERT (result == os_resultSuccess);
|
||||
|
||||
if (result == os_resultSuccess) {
|
||||
#ifdef _WRS_KERNEL
|
||||
sleepSeconds(1);
|
||||
#endif
|
||||
result = os_threadWaitExit (thread_os_threadId, &result_from_thread);
|
||||
CU_ASSERT (result == os_resultSuccess);
|
||||
|
||||
if (result == os_resultSuccess) {
|
||||
uintmax_t tmp_thread_os_threadId = os_threadIdToInteger(thread_os_threadId);
|
||||
CU_ASSERT (thread_id_from_thread == tmp_thread_os_threadId);
|
||||
CU_ASSERT (result_from_thread == (uint32_t)tmp_thread_os_threadId);
|
||||
} else {
|
||||
printf ("os_threadWaitExit failed.\n");
|
||||
}
|
||||
} else {
|
||||
printf ("os_threadCreate failed.\n");
|
||||
}
|
||||
|
||||
printf ("Ending tc_threadIdSelf\n");
|
||||
}
|
||||
|
||||
CUnit_Test(os_thread, join)
|
||||
{
|
||||
os_threadId thread_os_threadId;
|
||||
os_threadAttr thread_os_threadAttr;
|
||||
int result;
|
||||
uint32_t result_from_thread;
|
||||
|
||||
/* Wait for thread to terminate and get the return value with Success result,
|
||||
while thread is still running */
|
||||
printf("Starting os_thread_join_001\n");
|
||||
os_threadAttrInit (&thread_os_threadAttr);
|
||||
result = os_threadCreate (&thread_os_threadId, "threadWaitExit", &thread_os_threadAttr, &threadId_thread, (void *)1);
|
||||
CU_ASSERT (result == os_resultSuccess);
|
||||
|
||||
if (result == os_resultSuccess) {
|
||||
#ifdef _WRS_KERNEL
|
||||
sleepSeconds(1);
|
||||
#endif
|
||||
result = os_threadWaitExit (thread_os_threadId, &result_from_thread);
|
||||
CU_ASSERT (result == os_resultSuccess);
|
||||
|
||||
if (result == os_resultSuccess) {
|
||||
CU_ASSERT (thread_id_from_thread == os_threadIdToInteger(thread_os_threadId));
|
||||
CU_ASSERT (result_from_thread == (uint32_t)thread_id_from_thread);
|
||||
} else {
|
||||
printf ("os_threadWaitExit failed.\n");
|
||||
}
|
||||
} else {
|
||||
printf ("os_threadCreate failed.\n");
|
||||
}
|
||||
|
||||
/* Wait for thread to terminate and get the return value with Success result,
|
||||
while thread is already terminated */
|
||||
printf ("Starting os_thread_join_002\n");
|
||||
os_threadAttrInit (&thread_os_threadAttr);
|
||||
result = os_threadCreate (&thread_os_threadId, "threadWaitExit", &thread_os_threadAttr, &threadId_thread, NULL);
|
||||
CU_ASSERT (result == os_resultSuccess);
|
||||
|
||||
if (result == os_resultSuccess) {
|
||||
#ifdef _WRS_KERNEL
|
||||
sleepSeconds(1);
|
||||
#endif
|
||||
result = os_threadWaitExit (thread_os_threadId, &result_from_thread);
|
||||
CU_ASSERT(result == os_resultSuccess);
|
||||
|
||||
if (result == os_resultSuccess) {
|
||||
CU_ASSERT (thread_id_from_thread == os_threadIdToInteger(thread_os_threadId));
|
||||
CU_ASSERT (result_from_thread == (uint32_t)thread_id_from_thread);
|
||||
} else {
|
||||
printf ("os_threadWaitExit failed.\n");
|
||||
}
|
||||
} else {
|
||||
printf ("os_threadCreate failed.\n");
|
||||
}
|
||||
|
||||
/* Get thread return value with Fail result because result is already read */
|
||||
printf ("Starting tc_os_thread_join_003\n");
|
||||
os_threadAttrInit (&thread_os_threadAttr);
|
||||
result = os_threadCreate (&thread_os_threadId, "threadWaitExit", &thread_os_threadAttr, &threadId_thread, NULL);
|
||||
CU_ASSERT (result == os_resultSuccess);
|
||||
|
||||
if (result == os_resultSuccess) {
|
||||
#ifdef _WRS_KERNEL
|
||||
sleepSeconds(1);
|
||||
#endif
|
||||
result = os_threadWaitExit (thread_os_threadId, NULL);
|
||||
CU_ASSERT (result == os_resultSuccess);
|
||||
} else {
|
||||
printf ("os_threadCreate failed.\n");
|
||||
}
|
||||
|
||||
/* Wait for thread to terminate and get the return value by multiple threads,
|
||||
one thread gets Success other Fail */
|
||||
printf ("Starting tc_os_thread_join_004\n");
|
||||
#ifndef WIN32
|
||||
os_threadAttrInit (&thread_os_threadAttr);
|
||||
{
|
||||
os_threadId threadWait1;
|
||||
os_result result1;
|
||||
|
||||
result = os_threadCreate (&thread_os_threadId, "threadToWaitFor", &thread_os_threadAttr, &threadId_thread, (void*) 1);
|
||||
CU_ASSERT (result == os_resultSuccess);
|
||||
result1 = os_threadCreate (&threadWait1, "waitingThread1", &thread_os_threadAttr, &get_threadExit_thread, &thread_os_threadId);
|
||||
CU_ASSERT (result1 == os_resultSuccess);
|
||||
|
||||
if (result == os_resultSuccess && result1 == os_resultSuccess)
|
||||
{
|
||||
#ifdef _WRS_KERNEL
|
||||
sleepSeconds(1);
|
||||
#endif
|
||||
result1 = os_threadWaitExit (threadWait1, NULL);
|
||||
|
||||
if (result1 != os_resultSuccess) {
|
||||
printf ("os_threadWaitExit 1 failed\n");
|
||||
CU_ASSERT (result1 == os_resultSuccess);
|
||||
}
|
||||
} else {
|
||||
printf ("os_threadCreate failed.\n");
|
||||
}
|
||||
}
|
||||
#else /* WIN32 */
|
||||
printf ("N.A - Not tested on Windows.\n");
|
||||
#endif
|
||||
|
||||
/* Wait for thread to terminate and pass NULL for the
|
||||
return value address - not interrested */
|
||||
printf ("Starting tc_os_threadWaitExit_005\n");
|
||||
os_threadAttrInit (&thread_os_threadAttr);
|
||||
result = os_threadCreate (&thread_os_threadId, "threadWaitExit", &thread_os_threadAttr, &threadId_thread, NULL);
|
||||
CU_ASSERT (result == os_resultSuccess);
|
||||
|
||||
if (result == os_resultSuccess) {
|
||||
#ifdef _WRS_KERNEL
|
||||
sleepSeconds(1);
|
||||
#endif
|
||||
result = os_threadWaitExit (thread_os_threadId, NULL);
|
||||
CU_ASSERT (result == os_resultSuccess);
|
||||
if (result != os_resultSuccess)
|
||||
printf ("os_threadWaitExit failed.\n");
|
||||
} else {
|
||||
printf ("os_threadCreate failed.\n");
|
||||
}
|
||||
|
||||
printf ("Ending tc_threadWaitExit\n");
|
||||
}
|
||||
|
||||
CUnit_Test(os_thread, figure_identity)
|
||||
{
|
||||
#if !defined(_WIN32)
|
||||
os_threadId thread_os_threadId;
|
||||
os_threadAttr thread_os_threadAttr;
|
||||
char threadId[512];
|
||||
char thread_name[512];
|
||||
int result;
|
||||
#endif /* WIN32 */
|
||||
|
||||
/* Figure out the identity of the thread, where it's name is known */
|
||||
printf ("Starting os_thread_figure_identity_001\n");
|
||||
#ifdef WIN32
|
||||
/* Untested because the identifier does not contain the name on Windows */
|
||||
#else
|
||||
os_threadAttrInit (&thread_os_threadAttr);
|
||||
result = os_threadCreate (&thread_os_threadId, "threadFigureIdentity", &thread_os_threadAttr, &threadIdentity_thread, threadId);
|
||||
CU_ASSERT (result == os_resultSuccess);
|
||||
|
||||
if (result == os_resultSuccess) {
|
||||
#ifdef _WRS_KERNEL
|
||||
sleepSeconds(1);
|
||||
#endif
|
||||
result = os_threadWaitExit (thread_os_threadId, NULL);
|
||||
CU_ASSERT (result == os_resultSuccess);
|
||||
|
||||
if (result == os_resultSuccess) {
|
||||
uintmax_t threadNumeric = 0;
|
||||
#ifdef _WRS_KERNEL
|
||||
int dum;
|
||||
(void)sscanf (threadId, "%s (%d %d)", thread_name, &threadNumeric, &dum);
|
||||
#else
|
||||
(void)sscanf (threadId, "%s 0x%"SCNxMAX, thread_name, &threadNumeric);
|
||||
#endif
|
||||
CU_ASSERT (strcmp (thread_name, "threadFigureIdentity") == 0 && threadNumeric == os_threadIdToInteger(thread_os_threadId));
|
||||
} else {
|
||||
printf ("os_threadWaitExit failed.\n");
|
||||
}
|
||||
} else {
|
||||
printf ("os_threadCreate failed.\n");
|
||||
}
|
||||
#endif /* WIN32 */
|
||||
|
||||
/* Figure out the identity of the thread, where it's name is unknown */
|
||||
printf ("Starting os_thread_figure_identity_002\n");
|
||||
#if (defined _WRS_KERNEL || defined WIN32)
|
||||
{
|
||||
char threadId[512];
|
||||
int threadNumeric;
|
||||
|
||||
os_threadFigureIdentity (threadId, sizeof(threadId));
|
||||
#if defined WIN32
|
||||
(void)sscanf (threadId, "%"PRIx32, &threadNumeric);
|
||||
#else /* VXWORKS */
|
||||
(void)sscanf (index(threadId,'(') + 1, "%"PRIx32, &threadNumeric);
|
||||
#endif
|
||||
CU_ASSERT (threadNumeric == os_threadIdToInteger(os_threadIdSelf()));
|
||||
}
|
||||
#else
|
||||
{
|
||||
char threadId[512];
|
||||
uintptr_t threadNumeric;
|
||||
|
||||
os_threadFigureIdentity (threadId, sizeof(threadId));
|
||||
|
||||
#ifdef WIN32
|
||||
(void)sscanf (threadId, "%"PRIxPTR, &threadNumeric);
|
||||
#else
|
||||
(void)sscanf (threadId, "%"PRIxPTR, &threadNumeric);
|
||||
#endif
|
||||
|
||||
#ifndef INTEGRITY
|
||||
CU_ASSERT (threadNumeric == (uintptr_t)os_threadIdToInteger(os_threadIdSelf()));
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Figure out the identity of the thread, check the return parameter */
|
||||
printf ("Starting os_thread_figure_identity_003\n");
|
||||
#ifdef _WRS_KERNEL
|
||||
{
|
||||
char threadId[512];
|
||||
char threadIdString[512];
|
||||
int threadNumeric;
|
||||
int threadIdLen;
|
||||
|
||||
snprintf (threadIdString, sizeof(threadIdString), "%s (%d %d)", taskName(taskIdSelf()),os_threadIdSelf(),taskIdSelf());
|
||||
threadIdLen = os_threadFigureIdentity (threadId, sizeof(threadId));
|
||||
CU_ASSERT (threadIdLen == strlen(threadIdString));
|
||||
}
|
||||
#else
|
||||
{
|
||||
char threadId[512];
|
||||
char threadIdString[512];
|
||||
unsigned int threadIdLen;
|
||||
|
||||
(void)snprintf (threadIdString, sizeof(threadIdString), "0x%"PRIxMAX, os_threadIdToInteger(os_threadIdSelf()));
|
||||
threadIdLen = os_threadFigureIdentity (threadId, sizeof(threadId));
|
||||
|
||||
CU_ASSERT (threadIdLen == strlen(threadIdString));
|
||||
}
|
||||
#endif
|
||||
|
||||
printf ("Ending os_thread_figure_identity\n");
|
||||
}
|
||||
|
||||
CUnit_Test(os_thread, attr_init)
|
||||
{
|
||||
os_threadAttr thread_os_threadAttr;
|
||||
/* Check default attributes: schedClass */
|
||||
printf ("Starting os_thread_attr_init_001\n");
|
||||
os_threadAttrInit (&thread_os_threadAttr);
|
||||
CU_ASSERT (thread_os_threadAttr.schedClass == OS_SCHED_DEFAULT);
|
||||
|
||||
/* Check default attributes: schedPriority */
|
||||
printf ("Starting os_thread_attr_init_002\n");
|
||||
#if !(defined _WRS_KERNEL || defined WIN32 || defined __APPLE__)
|
||||
os_threadAttrInit (&thread_os_threadAttr);
|
||||
CU_ASSERT (thread_os_threadAttr.schedPriority == ((sched_get_priority_min (SCHED_OTHER) + sched_get_priority_max (SCHED_OTHER)) / 2 ));
|
||||
#else
|
||||
/* OSX priorities are different (min=15 and max=47) */
|
||||
printf ("N.A - Not tested for VxWorks, Windows and OSX\n");
|
||||
#endif
|
||||
|
||||
/* Check default attributes: stacksize */
|
||||
printf ("Starting os_thread_attr_init_003\n");
|
||||
os_threadAttrInit (&thread_os_threadAttr);
|
||||
CU_ASSERT (thread_os_threadAttr.stackSize == 0);
|
||||
|
||||
printf ("Ending os_thread_attr_init\n");
|
||||
}
|
||||
|
||||
CUnit_Test(os_thread, memmalloc)
|
||||
{
|
||||
/* Check os_threadMemMalloc with success result for main thread */
|
||||
printf ("Starting os_thread_memmalloc_001\n");
|
||||
returnval = os_threadMemMalloc (3, 100);
|
||||
CU_ASSERT (returnval != NULL);
|
||||
|
||||
/* Check os_threadMemMalloc with fail result for main thread
|
||||
for index already in use */
|
||||
printf ("Starting os_thread_memmalloc_002\n");
|
||||
returnval = os_threadMemMalloc (3, 100);
|
||||
CU_ASSERT (returnval == NULL);
|
||||
|
||||
/* Check os_threadMemMalloc with fail result for main thread
|
||||
for index < 0 */
|
||||
printf ("Starting os_thread_memmalloc_003\n");
|
||||
returnval = os_threadMemMalloc (-1, 100);
|
||||
CU_ASSERT (returnval == NULL);
|
||||
|
||||
/* Check os_threadMemMalloc with fail result for main thread
|
||||
for index >= OS_THREAD_MEM_ARRAY_SIZE */
|
||||
printf ("Starting os_thread_memmalloc_004\n");
|
||||
returnval = os_threadMemMalloc (OS_THREAD_MEM_ARRAY_SIZE, 100);
|
||||
CU_ASSERT (returnval == NULL);
|
||||
|
||||
printf ("Ending tc_thread_memmalloc\n");
|
||||
}
|
||||
|
||||
CUnit_Test(os_thread, memget)
|
||||
{
|
||||
/* Check os_threadMemGet for main thread and non allocated index */
|
||||
printf ("Starting os_thread_memget_001\n");
|
||||
returnval = os_threadMemGet (OS_THREAD_WARNING);
|
||||
CU_ASSERT (returnval == NULL);
|
||||
|
||||
/* Check os_threadMemGet for main thread and allocated index */
|
||||
printf ("Starting os_thread_memget_002\n");
|
||||
/* FIXME: This test is no good. Apart from the fact that a valid thread
|
||||
memory index should be used (os_threadMemoryIndex), this also
|
||||
does not work if the test is executed in a self-contained
|
||||
manner using the CUnit runner. For now just work around it by
|
||||
first doing a os_threadMemMalloc. */
|
||||
(void)os_threadMemMalloc(3, 100);
|
||||
returnval = os_threadMemGet (3);
|
||||
CU_ASSERT (returnval != NULL);
|
||||
|
||||
printf ("Ending tc_thread_memget\n");
|
||||
}
|
||||
|
||||
CUnit_Test(os_thread, memfree)
|
||||
{
|
||||
/* Check os_threadMemFree for main thread and non allocated index */
|
||||
printf ("Starting os_thread_memfree_001\n");
|
||||
os_threadMemFree (OS_THREAD_WARNING);
|
||||
returnval = os_threadMemGet (OS_THREAD_WARNING);
|
||||
CU_ASSERT (returnval == NULL);
|
||||
|
||||
/* Check os_threadMemFree for main thread and allocated index */
|
||||
printf ("Starting os_thread_memfree_002\n");
|
||||
/* FIXME: See comments on memget test. */
|
||||
(void)os_threadMemMalloc(3, 100);
|
||||
returnval = os_threadMemGet(3);
|
||||
CU_ASSERT(returnval != NULL);
|
||||
os_threadMemFree (3);
|
||||
returnval = os_threadMemGet (3);
|
||||
CU_ASSERT (returnval == NULL);
|
||||
|
||||
printf ("Ending os_thread_memfree\n");
|
||||
}
|
||||
|
||||
CUnit_Test(os_thread, module)
|
||||
{
|
||||
os_threadId tid;
|
||||
os_threadAttr tattr;
|
||||
os_result res;
|
||||
|
||||
os_threadAttrInit (&tattr);
|
||||
/* Run the following tests for child thread */
|
||||
res = os_threadCreate (&tid, "ThreadMemory", &tattr, &threadMemory_thread, NULL);
|
||||
CU_ASSERT_EQUAL(res, os_resultSuccess);
|
||||
if (res == os_resultSuccess) {
|
||||
#ifdef _WRS_KERNEL
|
||||
sleepSeconds(1);
|
||||
#endif
|
||||
res = os_threadWaitExit (tid, NULL);
|
||||
CU_ASSERT_EQUAL(res, os_resultSuccess);
|
||||
}
|
||||
}
|
283
src/os/tests/thread_cleanup.c
Normal file
283
src/os/tests/thread_cleanup.c
Normal file
|
@ -0,0 +1,283 @@
|
|||
/*
|
||||
* Copyright(c) 2006 to 2018 ADLINK Technology Limited and others
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License v. 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
|
||||
* v. 1.0 which is available at
|
||||
* http://www.eclipse.org/org/documents/edl-v10.php.
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
|
||||
*/
|
||||
#include <assert.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "os/os.h"
|
||||
#include "CUnit/Runner.h"
|
||||
|
||||
CUnit_Suite_Initialize(os_thread_cleanup)
|
||||
{
|
||||
os_osInit();
|
||||
return 0;
|
||||
}
|
||||
|
||||
CUnit_Suite_Cleanup(os_thread_cleanup)
|
||||
{
|
||||
os_osExit();
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define THREAD_RESET_1 (1<<0)
|
||||
#define THREAD_RESET_2 (1<<1)
|
||||
#define THREAD_RUN_OFFSET (4)
|
||||
#define THREAD_RUN_1 (1<<(THREAD_RUN_OFFSET))
|
||||
#define THREAD_RUN_2 (1<<(THREAD_RUN_OFFSET + 1))
|
||||
|
||||
struct thread_argument {
|
||||
int flags;
|
||||
int pop;
|
||||
int one;
|
||||
int two;
|
||||
int executed;
|
||||
int cancelled;
|
||||
int block;
|
||||
os_mutex *mutex;
|
||||
os_threadId thread;
|
||||
};
|
||||
|
||||
static struct thread_argument *
|
||||
make_thread_argument(
|
||||
int flags, int pop, int one, int two)
|
||||
{
|
||||
struct thread_argument *targ = os_malloc(sizeof(*targ));
|
||||
memset(targ, 0, sizeof(*targ));
|
||||
targ->flags = flags;
|
||||
targ->pop = pop;
|
||||
targ->one = one;
|
||||
targ->two = two;
|
||||
|
||||
return targ;
|
||||
}
|
||||
|
||||
static void
|
||||
reset_one(
|
||||
void *arg)
|
||||
{
|
||||
struct thread_argument *targ = (struct thread_argument *)arg;
|
||||
targ->one = 0;
|
||||
targ->executed++;
|
||||
}
|
||||
|
||||
static void
|
||||
reset_two(
|
||||
void *arg)
|
||||
{
|
||||
struct thread_argument *targ = (struct thread_argument *)arg;
|
||||
targ->two = 0;
|
||||
targ->executed++;
|
||||
}
|
||||
|
||||
static uint32_t
|
||||
thread_main(
|
||||
void *arg)
|
||||
{
|
||||
int pushed = 0;
|
||||
int popped = 0;
|
||||
int execute = 0;
|
||||
struct thread_argument *targ = (struct thread_argument *)arg;
|
||||
|
||||
if (targ->flags & THREAD_RESET_1) {
|
||||
os_threadCleanupPush(&reset_one, arg);
|
||||
pushed++;
|
||||
}
|
||||
if (targ->flags & THREAD_RESET_2) {
|
||||
os_threadCleanupPush(&reset_two, arg);
|
||||
pushed++;
|
||||
}
|
||||
|
||||
assert(targ->pop <= pushed);
|
||||
|
||||
if (targ->block) {
|
||||
os_mutexLock(targ->mutex);
|
||||
}
|
||||
|
||||
while (popped < targ->pop) {
|
||||
execute = 1 << (THREAD_RUN_OFFSET + (targ->pop - (popped + 1)));
|
||||
os_threadCleanupPop(targ->flags & execute);
|
||||
targ->cancelled++;
|
||||
popped++;
|
||||
}
|
||||
|
||||
if (targ->block) {
|
||||
os_mutexUnlock(targ->mutex);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
setup(
|
||||
struct thread_argument *targ)
|
||||
{
|
||||
os_result res;
|
||||
os_threadId tid;
|
||||
os_threadAttr tattr;
|
||||
|
||||
uint32_t tres = 0;
|
||||
|
||||
os_threadAttrInit(&tattr);
|
||||
res = os_threadCreate(&tid, "", &tattr, &thread_main, (void *)targ);
|
||||
CU_ASSERT_EQUAL_FATAL(res, os_resultSuccess);
|
||||
|
||||
targ->thread = tid;
|
||||
if (!targ->block) {
|
||||
res = os_threadWaitExit(tid, &tres);
|
||||
CU_ASSERT_EQUAL_FATAL(res, os_resultSuccess);
|
||||
}
|
||||
}
|
||||
|
||||
/* verify the cleanup routine is called */
|
||||
CUnit_Test(os_thread_cleanup, push_one)
|
||||
{
|
||||
int flags = THREAD_RESET_1;
|
||||
struct thread_argument *targ = make_thread_argument(flags, 0, 1, 2);
|
||||
setup(targ);
|
||||
|
||||
CU_ASSERT_EQUAL(targ->one, 0);
|
||||
CU_ASSERT_EQUAL(targ->two, 2);
|
||||
CU_ASSERT_EQUAL(targ->executed, 1);
|
||||
CU_ASSERT_EQUAL(targ->cancelled, 0);
|
||||
|
||||
free(targ);
|
||||
}
|
||||
|
||||
/* verify all cleanup routines are called if multiple are registered */
|
||||
CUnit_Test(os_thread_cleanup, push_two)
|
||||
{
|
||||
int flags = THREAD_RESET_1 | THREAD_RESET_2;
|
||||
struct thread_argument *targ = make_thread_argument(flags, 0, 1, 2);
|
||||
setup(targ);
|
||||
|
||||
CU_ASSERT_EQUAL(targ->one, 0);
|
||||
CU_ASSERT_EQUAL(targ->two, 0);
|
||||
CU_ASSERT_EQUAL(targ->executed, 2);
|
||||
CU_ASSERT_EQUAL(targ->cancelled, 0);
|
||||
|
||||
free(targ);
|
||||
}
|
||||
|
||||
/* verify the first cleanup routine is still called if second got popped */
|
||||
CUnit_Test(os_thread_cleanup, push_two_pop_one_no_exec)
|
||||
{
|
||||
int flags = THREAD_RESET_1 | THREAD_RESET_2;
|
||||
struct thread_argument *targ = make_thread_argument(flags, 1, 1, 2);
|
||||
setup(targ);
|
||||
|
||||
CU_ASSERT_EQUAL(targ->one, 0);
|
||||
CU_ASSERT_EQUAL(targ->two, 2);
|
||||
CU_ASSERT_EQUAL(targ->executed, 1);
|
||||
CU_ASSERT_EQUAL(targ->cancelled, 1);
|
||||
|
||||
free(targ);
|
||||
}
|
||||
|
||||
CUnit_Test(os_thread_cleanup, push_two_pop_one_exec)
|
||||
{
|
||||
int flags = THREAD_RESET_1 | THREAD_RESET_2 | THREAD_RUN_1;
|
||||
struct thread_argument *targ = make_thread_argument(flags, 1, 1, 2);
|
||||
setup(targ);
|
||||
|
||||
CU_ASSERT_EQUAL(targ->one, 0);
|
||||
CU_ASSERT_EQUAL(targ->two, 0);
|
||||
CU_ASSERT_EQUAL(targ->executed, 2);
|
||||
CU_ASSERT_EQUAL(targ->cancelled, 1);
|
||||
|
||||
free(targ);
|
||||
}
|
||||
|
||||
/* verify no cleanup routines are called if all got popped */
|
||||
CUnit_Test(os_thread_cleanup, push_two_pop_two_no_exec)
|
||||
{
|
||||
int flags = THREAD_RESET_1 | THREAD_RESET_2;
|
||||
struct thread_argument *targ = make_thread_argument(flags, 2, 1, 2);
|
||||
setup(targ);
|
||||
|
||||
CU_ASSERT_EQUAL(targ->one, 1);
|
||||
CU_ASSERT_EQUAL(targ->two, 2);
|
||||
CU_ASSERT_EQUAL(targ->executed, 0);
|
||||
CU_ASSERT_EQUAL(targ->cancelled, 2);
|
||||
|
||||
free(targ);
|
||||
}
|
||||
|
||||
CUnit_Test(os_thread_cleanup, push_two_pop_two_exec_one)
|
||||
{
|
||||
int flags = THREAD_RESET_1 | THREAD_RESET_2 | THREAD_RUN_1;
|
||||
struct thread_argument *targ = make_thread_argument(flags, 2, 1, 2);
|
||||
setup(targ);
|
||||
|
||||
CU_ASSERT_EQUAL(targ->one, 0);
|
||||
CU_ASSERT_EQUAL(targ->two, 2);
|
||||
CU_ASSERT_EQUAL(targ->executed, 1);
|
||||
CU_ASSERT_EQUAL(targ->cancelled, 2);
|
||||
|
||||
free(targ);
|
||||
}
|
||||
|
||||
CUnit_Test(os_thread_cleanup, push_two_pop_two_exec_both)
|
||||
{
|
||||
int flags = THREAD_RESET_1 | THREAD_RESET_2 | THREAD_RUN_1 | THREAD_RUN_2;
|
||||
struct thread_argument *targ = make_thread_argument(flags, 2, 1, 2);
|
||||
setup(targ);
|
||||
|
||||
CU_ASSERT_EQUAL(targ->one, 0);
|
||||
CU_ASSERT_EQUAL(targ->two, 0);
|
||||
CU_ASSERT_EQUAL(targ->executed, 2);
|
||||
CU_ASSERT_EQUAL(targ->cancelled, 2);
|
||||
|
||||
free(targ);
|
||||
}
|
||||
|
||||
CUnit_Test(os_thread_cleanup, no_interference)
|
||||
{
|
||||
int flags = THREAD_RESET_1 | THREAD_RESET_2;
|
||||
struct thread_argument *targ1 = make_thread_argument(flags, 0, 1, 2);
|
||||
struct thread_argument *targ2 = make_thread_argument(flags, 2, 1, 2);
|
||||
os_mutex mutex1, mutex2;
|
||||
|
||||
os_mutexInit(&mutex1);
|
||||
os_mutexInit(&mutex2);
|
||||
os_mutexLock(&mutex1);
|
||||
os_mutexLock(&mutex2);
|
||||
|
||||
targ1->mutex = &mutex1;
|
||||
targ1->block = 1;
|
||||
targ2->mutex = &mutex2;
|
||||
targ2->block = 1;
|
||||
|
||||
setup(targ1);
|
||||
setup(targ2);
|
||||
|
||||
/* ensure thread 2 pops it's cleanup routines while thread 1 blocks */
|
||||
os_mutexUnlock(&mutex2);
|
||||
os_threadWaitExit(targ2->thread, NULL);
|
||||
|
||||
CU_ASSERT_EQUAL(targ2->one, 1);
|
||||
CU_ASSERT_EQUAL(targ2->two, 2);
|
||||
CU_ASSERT_EQUAL(targ2->executed, 0);
|
||||
CU_ASSERT_EQUAL(targ2->cancelled, 2);
|
||||
|
||||
/* instruct thread 1 to continue */
|
||||
os_mutexUnlock(&mutex1);
|
||||
os_threadWaitExit(targ1->thread, NULL);
|
||||
|
||||
CU_ASSERT_EQUAL(targ1->one, 0);
|
||||
CU_ASSERT_EQUAL(targ1->two, 0);
|
||||
CU_ASSERT_EQUAL(targ1->executed, 2);
|
||||
CU_ASSERT_EQUAL(targ1->cancelled, 0);
|
||||
|
||||
os_mutexDestroy(&mutex1);
|
||||
os_mutexDestroy(&mutex2);
|
||||
free(targ1);
|
||||
free(targ2);
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue