FreeRDP
TestInterlockedSList.c
1 
2 #include <stdio.h>
3 #include <winpr/crt.h>
4 #include <winpr/windows.h>
5 #include <winpr/interlocked.h>
6 
7 #define ITEM_COUNT 23
8 
9 typedef struct
10 {
11  WINPR_SLIST_ENTRY ItemEntry;
12  ULONG Signature;
13 } PROGRAM_ITEM, *PPROGRAM_ITEM;
14 
15 int TestInterlockedSList(int argc, char* argv[])
16 {
17  int rc = -1;
18 
19  WINPR_UNUSED(argc);
20  WINPR_UNUSED(argv);
21 
22  /* Initialize the list header to a MEMORY_ALLOCATION_ALIGNMENT boundary. */
23  WINPR_PSLIST_HEADER pListHead = (WINPR_PSLIST_HEADER)winpr_aligned_malloc(
24  sizeof(WINPR_SLIST_HEADER), MEMORY_ALLOCATION_ALIGNMENT);
25 
26  if (!pListHead)
27  {
28  printf("Memory allocation failed.\n");
29  return -1;
30  }
31 
32  InitializeSListHead(pListHead);
33 
34  /* Insert 10 items into the list. */
35  for (ULONG Count = 0; Count < ITEM_COUNT; Count++)
36  {
37  PPROGRAM_ITEM pProgramItem =
38  (PPROGRAM_ITEM)winpr_aligned_malloc(sizeof(PROGRAM_ITEM), MEMORY_ALLOCATION_ALIGNMENT);
39 
40  if (!pProgramItem)
41  {
42  printf("Memory allocation failed.\n");
43  goto fail;
44  }
45 
46  pProgramItem->Signature = Count + 1UL;
47  WINPR_PSLIST_ENTRY pFirstEntry =
48  InterlockedPushEntrySList(pListHead, &(pProgramItem->ItemEntry));
49  if (((Count == 0) && pFirstEntry) || ((Count != 0) && !pFirstEntry))
50  {
51  printf("Error: List is empty.\n");
52  winpr_aligned_free(pProgramItem);
53  goto fail;
54  }
55  }
56 
57  /* Remove 10 items from the list and display the signature. */
58  for (ULONG Count = 0; Count < ITEM_COUNT; Count++)
59  {
60  WINPR_PSLIST_ENTRY pListEntry = InterlockedPopEntrySList(pListHead);
61 
62  if (!pListEntry)
63  {
64  printf("List is empty.\n");
65  goto fail;
66  }
67 
68  PPROGRAM_ITEM pProgramItem = (PPROGRAM_ITEM)pListEntry;
69  printf("Signature is %" PRIu32 "\n", pProgramItem->Signature);
70 
71  /*
72  * This example assumes that the SLIST_ENTRY structure is the
73  * first member of the structure. If your structure does not
74  * follow this convention, you must compute the starting address
75  * of the structure before calling the free function.
76  */
77 
78  winpr_aligned_free(pListEntry);
79  }
80 
81  /* Flush the list and verify that the items are gone. */
82  WINPR_PSLIST_ENTRY pFirstEntry = InterlockedPopEntrySList(pListHead);
83 
84  if (pFirstEntry)
85  {
86  printf("Error: List is not empty.\n");
87  goto fail;
88  }
89 
90  rc = 0;
91 fail:
92  winpr_aligned_free(pListHead);
93 
94  return rc;
95 }