diff options
Diffstat (limited to 'winpr/libwinpr/interlocked/test')
4 files changed, 392 insertions, 0 deletions
diff --git a/winpr/libwinpr/interlocked/test/CMakeLists.txt b/winpr/libwinpr/interlocked/test/CMakeLists.txt new file mode 100644 index 0000000..1166410 --- /dev/null +++ b/winpr/libwinpr/interlocked/test/CMakeLists.txt @@ -0,0 +1,28 @@ + +set(MODULE_NAME "TestInterlocked") +set(MODULE_PREFIX "TEST_INTERLOCKED") + +set(${MODULE_PREFIX}_DRIVER ${MODULE_NAME}.c) + +set(${MODULE_PREFIX}_TESTS + TestInterlockedAccess.c + TestInterlockedSList.c + TestInterlockedDList.c) + +create_test_sourcelist(${MODULE_PREFIX}_SRCS + ${${MODULE_PREFIX}_DRIVER} + ${${MODULE_PREFIX}_TESTS}) + +add_executable(${MODULE_NAME} ${${MODULE_PREFIX}_SRCS}) + +target_link_libraries(${MODULE_NAME} winpr) + +set_target_properties(${MODULE_NAME} PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${TESTING_OUTPUT_DIRECTORY}") + +foreach(test ${${MODULE_PREFIX}_TESTS}) + get_filename_component(TestName ${test} NAME_WE) + add_test(${TestName} ${TESTING_OUTPUT_DIRECTORY}/${MODULE_NAME} ${TestName}) +endforeach() + +set_property(TARGET ${MODULE_NAME} PROPERTY FOLDER "WinPR/Test") + diff --git a/winpr/libwinpr/interlocked/test/TestInterlockedAccess.c b/winpr/libwinpr/interlocked/test/TestInterlockedAccess.c new file mode 100644 index 0000000..0ecd850 --- /dev/null +++ b/winpr/libwinpr/interlocked/test/TestInterlockedAccess.c @@ -0,0 +1,200 @@ +#include <stdio.h> +#include <winpr/crt.h> +#include <winpr/windows.h> +#include <winpr/interlocked.h> + +int TestInterlockedAccess(int argc, char* argv[]) +{ + LONG* Addend = NULL; + LONG* Target = NULL; + LONG oldValue = 0; + LONG* Destination = NULL; + LONGLONG oldValue64 = 0; + LONGLONG* Destination64 = NULL; + WINPR_UNUSED(argc); + WINPR_UNUSED(argv); + /* InterlockedIncrement */ + + Addend = winpr_aligned_malloc(sizeof(LONG), sizeof(LONG)); + if (!Addend) + { + printf("Failed to allocate memory\n"); + return -1; + } + + *Addend = 0; + + for (int index = 0; index < 10; index++) + InterlockedIncrement(Addend); + + if (*Addend != 10) + { + printf("InterlockedIncrement failure: Actual: %" PRId32 ", Expected: 10\n", *Addend); + return -1; + } + + /* InterlockedDecrement */ + + for (int index = 0; index < 10; index++) + InterlockedDecrement(Addend); + + if (*Addend != 0) + { + printf("InterlockedDecrement failure: Actual: %" PRId32 ", Expected: 0\n", *Addend); + return -1; + } + + /* InterlockedExchange */ + + Target = winpr_aligned_malloc(sizeof(LONG), sizeof(LONG)); + + if (!Target) + { + printf("Failed to allocate memory\n"); + return -1; + } + + *Target = 0xAA; + + oldValue = InterlockedExchange(Target, 0xFF); + + if (oldValue != 0xAA) + { + printf("InterlockedExchange failure: Actual: 0x%08" PRIX32 ", Expected: 0xAA\n", oldValue); + return -1; + } + + if (*Target != 0xFF) + { + printf("InterlockedExchange failure: Actual: 0x%08" PRIX32 ", Expected: 0xFF\n", *Target); + return -1; + } + + /* InterlockedExchangeAdd */ + + *Addend = 25; + + oldValue = InterlockedExchangeAdd(Addend, 100); + + if (oldValue != 25) + { + printf("InterlockedExchangeAdd failure: Actual: %" PRId32 ", Expected: 25\n", oldValue); + return -1; + } + + if (*Addend != 125) + { + printf("InterlockedExchangeAdd failure: Actual: %" PRId32 ", Expected: 125\n", *Addend); + return -1; + } + + /* InterlockedCompareExchange (*Destination == Comparand) */ + + Destination = winpr_aligned_malloc(sizeof(LONG), sizeof(LONG)); + if (!Destination) + { + printf("Failed to allocate memory\n"); + return -1; + } + + *Destination = (LONG)0xAABBCCDDL; + + oldValue = InterlockedCompareExchange(Destination, (LONG)0xCCDDEEFFL, (LONG)0xAABBCCDDL); + + if (oldValue != (LONG)0xAABBCCDDL) + { + printf("InterlockedCompareExchange failure: Actual: 0x%08" PRIX32 + ", Expected: 0xAABBCCDD\n", + oldValue); + return -1; + } + + if ((*Destination) != (LONG)0xCCDDEEFFL) + { + printf("InterlockedCompareExchange failure: Actual: 0x%08" PRIX32 + ", Expected: 0xCCDDEEFF\n", + *Destination); + return -1; + } + + /* InterlockedCompareExchange (*Destination != Comparand) */ + + *Destination = (LONG)0xAABBCCDDL; + + oldValue = InterlockedCompareExchange(Destination, -857870593L, 0x66778899L); + + if (oldValue != (LONG)0xAABBCCDDL) + { + printf("InterlockedCompareExchange failure: Actual: 0x%08" PRIX32 + ", Expected: 0xAABBCCDD\n", + oldValue); + return -1; + } + + if ((*Destination) != (LONG)0xAABBCCDDL) + { + printf("InterlockedCompareExchange failure: Actual: 0x%08" PRIX32 + ", Expected: 0xAABBCCDD\n", + *Destination); + return -1; + } + + /* InterlockedCompareExchange64 (*Destination == Comparand) */ + + Destination64 = winpr_aligned_malloc(sizeof(LONGLONG), sizeof(LONGLONG)); + if (!Destination64) + { + printf("Failed to allocate memory\n"); + return -1; + } + + *Destination64 = 0x66778899AABBCCDD; + + oldValue64 = + InterlockedCompareExchange64(Destination64, 0x8899AABBCCDDEEFF, 0x66778899AABBCCDD); + + if (oldValue64 != 0x66778899AABBCCDD) + { + printf("InterlockedCompareExchange failure: Actual: 0x%016" PRIX64 + ", Expected: 0x66778899AABBCCDD\n", + oldValue64); + return -1; + } + + if ((*Destination64) != (LONGLONG)0x8899AABBCCDDEEFFLL) + { + printf("InterlockedCompareExchange failure: Actual: 0x%016" PRIX64 + ", Expected: 0x8899AABBCCDDEEFF\n", + *Destination64); + return -1; + } + + /* InterlockedCompareExchange64 (*Destination != Comparand) */ + + *Destination64 = 0x66778899AABBCCDDLL; + + oldValue64 = InterlockedCompareExchange64(Destination64, 0x8899AABBCCDDEEFFLL, 12345); + + if (oldValue64 != 0x66778899AABBCCDDLL) + { + printf("InterlockedCompareExchange failure: Actual: 0x%016" PRIX64 + ", Expected: 0x66778899AABBCCDD\n", + oldValue64); + return -1; + } + + if (*Destination64 != 0x66778899AABBCCDDLL) + { + printf("InterlockedCompareExchange failure: Actual: 0x%016" PRIX64 + ", Expected: 0x66778899AABBCCDD\n", + *Destination64); + return -1; + } + + winpr_aligned_free(Addend); + winpr_aligned_free(Target); + winpr_aligned_free(Destination); + winpr_aligned_free(Destination64); + + return 0; +} diff --git a/winpr/libwinpr/interlocked/test/TestInterlockedDList.c b/winpr/libwinpr/interlocked/test/TestInterlockedDList.c new file mode 100644 index 0000000..f49e37d --- /dev/null +++ b/winpr/libwinpr/interlocked/test/TestInterlockedDList.c @@ -0,0 +1,79 @@ + +#include <stdio.h> +#include <winpr/crt.h> +#include <winpr/windows.h> +#include <winpr/interlocked.h> + +typedef struct +{ + WINPR_LIST_ENTRY ItemEntry; + ULONG Signature; +} LIST_ITEM, *PLIST_ITEM; + +int TestInterlockedDList(int argc, char* argv[]) +{ + ULONG Count = 0; + PLIST_ITEM pListItem = NULL; + WINPR_PLIST_ENTRY pListHead = NULL; + WINPR_PLIST_ENTRY pListEntry = NULL; + WINPR_UNUSED(argc); + WINPR_UNUSED(argv); + pListHead = (WINPR_PLIST_ENTRY)winpr_aligned_malloc(sizeof(WINPR_LIST_ENTRY), + MEMORY_ALLOCATION_ALIGNMENT); + + if (!pListHead) + { + printf("Memory allocation failed.\n"); + return -1; + } + + InitializeListHead(pListHead); + + if (!IsListEmpty(pListHead)) + { + printf("Expected empty list\n"); + return -1; + } + + /* InsertHeadList / RemoveHeadList */ + + printf("InsertHeadList / RemoveHeadList\n"); + + for (Count = 1; Count <= 10; Count += 1) + { + pListItem = + (PLIST_ITEM)winpr_aligned_malloc(sizeof(LIST_ITEM), MEMORY_ALLOCATION_ALIGNMENT); + pListItem->Signature = Count; + InsertHeadList(pListHead, &(pListItem->ItemEntry)); + } + + for (Count = 10; Count >= 1; Count -= 1) + { + pListEntry = RemoveHeadList(pListHead); + pListItem = (PLIST_ITEM)pListEntry; + winpr_aligned_free(pListItem); + } + + /* InsertTailList / RemoveTailList */ + + printf("InsertTailList / RemoveTailList\n"); + + for (Count = 1; Count <= 10; Count += 1) + { + pListItem = + (PLIST_ITEM)winpr_aligned_malloc(sizeof(LIST_ITEM), MEMORY_ALLOCATION_ALIGNMENT); + pListItem->Signature = Count; + InsertTailList(pListHead, &(pListItem->ItemEntry)); + } + + for (Count = 10; Count >= 1; Count -= 1) + { + pListEntry = RemoveTailList(pListHead); + pListItem = (PLIST_ITEM)pListEntry; + winpr_aligned_free(pListItem); + } + + winpr_aligned_free(pListHead); + + return 0; +} diff --git a/winpr/libwinpr/interlocked/test/TestInterlockedSList.c b/winpr/libwinpr/interlocked/test/TestInterlockedSList.c new file mode 100644 index 0000000..71ac8bc --- /dev/null +++ b/winpr/libwinpr/interlocked/test/TestInterlockedSList.c @@ -0,0 +1,85 @@ + +#include <stdio.h> +#include <winpr/crt.h> +#include <winpr/windows.h> +#include <winpr/interlocked.h> + +typedef struct +{ + WINPR_SLIST_ENTRY ItemEntry; + ULONG Signature; +} PROGRAM_ITEM, *PPROGRAM_ITEM; + +int TestInterlockedSList(int argc, char* argv[]) +{ + ULONG Count = 0; + WINPR_PSLIST_ENTRY pFirstEntry = NULL; + WINPR_PSLIST_HEADER pListHead = NULL; + WINPR_UNUSED(argc); + WINPR_UNUSED(argv); + /* Initialize the list header to a MEMORY_ALLOCATION_ALIGNMENT boundary. */ + pListHead = (WINPR_PSLIST_HEADER)winpr_aligned_malloc(sizeof(WINPR_SLIST_HEADER), + MEMORY_ALLOCATION_ALIGNMENT); + + if (!pListHead) + { + printf("Memory allocation failed.\n"); + return -1; + } + + InitializeSListHead(pListHead); + + /* Insert 10 items into the list. */ + for (Count = 1; Count <= 10; Count += 1) + { + PPROGRAM_ITEM pProgramItem = + (PPROGRAM_ITEM)winpr_aligned_malloc(sizeof(PROGRAM_ITEM), MEMORY_ALLOCATION_ALIGNMENT); + + if (!pProgramItem) + { + printf("Memory allocation failed.\n"); + return -1; + } + + pProgramItem->Signature = Count; + pFirstEntry = InterlockedPushEntrySList(pListHead, &(pProgramItem->ItemEntry)); + } + + /* Remove 10 items from the list and display the signature. */ + for (Count = 10; Count >= 1; Count -= 1) + { + PPROGRAM_ITEM pProgramItem = NULL; + WINPR_PSLIST_ENTRY pListEntry = InterlockedPopEntrySList(pListHead); + + if (!pListEntry) + { + printf("List is empty.\n"); + return -1; + } + + pProgramItem = (PPROGRAM_ITEM)pListEntry; + printf("Signature is %" PRIu32 "\n", pProgramItem->Signature); + + /* + * This example assumes that the SLIST_ENTRY structure is the + * first member of the structure. If your structure does not + * follow this convention, you must compute the starting address + * of the structure before calling the free function. + */ + + winpr_aligned_free(pListEntry); + } + + /* Flush the list and verify that the items are gone. */ + pFirstEntry = InterlockedPopEntrySList(pListHead); + + if (pFirstEntry) + { + printf("Error: List is not empty.\n"); + return -1; + } + + winpr_aligned_free(pListHead); + + return 0; +} |