|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
#include <stdio.h>
|
|
Packit |
1fb8d4 |
#include <winpr/crt.h>
|
|
Packit |
1fb8d4 |
#include <winpr/windows.h>
|
|
Packit |
1fb8d4 |
#include <winpr/interlocked.h>
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
typedef struct _PROGRAM_ITEM
|
|
Packit |
1fb8d4 |
{
|
|
Packit Service |
5a9772 |
WINPR_SLIST_ENTRY ItemEntry;
|
|
Packit |
1fb8d4 |
ULONG Signature;
|
|
Packit |
1fb8d4 |
} PROGRAM_ITEM, *PPROGRAM_ITEM;
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
int TestInterlockedSList(int argc, char* argv[])
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
ULONG Count;
|
|
Packit |
1fb8d4 |
WINPR_PSLIST_ENTRY pFirstEntry;
|
|
Packit |
1fb8d4 |
WINPR_PSLIST_HEADER pListHead;
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
/* Initialize the list header to a MEMORY_ALLOCATION_ALIGNMENT boundary. */
|
|
Packit Service |
5a9772 |
pListHead = (WINPR_PSLIST_HEADER)_aligned_malloc(sizeof(WINPR_SLIST_HEADER),
|
|
Packit Service |
5a9772 |
MEMORY_ALLOCATION_ALIGNMENT);
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
if (!pListHead)
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
printf("Memory allocation failed.\n");
|
|
Packit |
1fb8d4 |
return -1;
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
InitializeSListHead(pListHead);
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
/* Insert 10 items into the list. */
|
|
Packit |
1fb8d4 |
for (Count = 1; Count <= 10; Count += 1)
|
|
Packit |
1fb8d4 |
{
|
|
Packit Service |
5a9772 |
PPROGRAM_ITEM pProgramItem =
|
|
Packit Service |
5a9772 |
(PPROGRAM_ITEM)_aligned_malloc(sizeof(PROGRAM_ITEM), MEMORY_ALLOCATION_ALIGNMENT);
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
if (!pProgramItem)
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
printf("Memory allocation failed.\n");
|
|
Packit |
1fb8d4 |
return -1;
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
pProgramItem->Signature = Count;
|
|
Packit |
1fb8d4 |
pFirstEntry = InterlockedPushEntrySList(pListHead, &(pProgramItem->ItemEntry));
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
/* Remove 10 items from the list and display the signature. */
|
|
Packit |
1fb8d4 |
for (Count = 10; Count >= 1; Count -= 1)
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
PPROGRAM_ITEM pProgramItem;
|
|
Packit |
1fb8d4 |
WINPR_PSLIST_ENTRY pListEntry = InterlockedPopEntrySList(pListHead);
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
if (!pListEntry)
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
printf("List is empty.\n");
|
|
Packit |
1fb8d4 |
return -1;
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit Service |
5a9772 |
pProgramItem = (PPROGRAM_ITEM)pListEntry;
|
|
Packit Service |
5a9772 |
printf("Signature is %" PRIu32 "\n", pProgramItem->Signature);
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
/*
|
|
Packit |
1fb8d4 |
* This example assumes that the SLIST_ENTRY structure is the
|
|
Packit |
1fb8d4 |
* first member of the structure. If your structure does not
|
|
Packit |
1fb8d4 |
* follow this convention, you must compute the starting address
|
|
Packit |
1fb8d4 |
* of the structure before calling the free function.
|
|
Packit |
1fb8d4 |
*/
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
_aligned_free(pListEntry);
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
/* Flush the list and verify that the items are gone. */
|
|
Packit |
1fb8d4 |
pFirstEntry = InterlockedPopEntrySList(pListHead);
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
if (pFirstEntry)
|
|
Packit |
1fb8d4 |
{
|
|
Packit |
1fb8d4 |
printf("Error: List is not empty.\n");
|
|
Packit |
1fb8d4 |
return -1;
|
|
Packit |
1fb8d4 |
}
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
_aligned_free(pListHead);
|
|
Packit |
1fb8d4 |
|
|
Packit |
1fb8d4 |
return 0;
|
|
Packit |
1fb8d4 |
}
|