Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

165 lines
5.0 KiB

  1. /*==========================================================================
  2. *
  3. * Copyright (C) 2001-2002 Microsoft Corporation. All Rights Reserved.
  4. *
  5. * File: dnslist.h
  6. * Content: DirectPlay implementations of OS SLIST functions
  7. *
  8. * History:
  9. * Date By Reason
  10. * ==== == ======
  11. * 10/30/2001 masonb Created
  12. * 11/07/2001 vanceo Added InterlockedPushListSList and made DNInitializeSListHead return value on Win64
  13. *
  14. ***************************************************************************/
  15. #ifndef __DNSLIST_H__
  16. #define __DNSLIST_H__
  17. // We build separate NT and 9x binaries, but even in the NT binary we can't be sure the system has the
  18. // SLIST functions available since they weren't on Win2k. The only place we can be sure that the SLIST
  19. // functions are available is on 64-bit NT platforms.
  20. // We don't supply a DNQueryDepthSList method because not all platforms can support it.
  21. // SINGLE_LIST_ENTRY is defined in winnt.h and contains only a Next pointer
  22. // to another SINGLE_LIST_ENTRY
  23. #if defined(WINCE) || defined(DPNBUILD_ONLYONETHREAD)
  24. #define SLIST_ENTRY SINGLE_LIST_ENTRY
  25. #endif // WINCE or DPNBUILD_ONLYONETHREAD
  26. #define DNSLIST_ENTRY SLIST_ENTRY
  27. #ifdef DPNBUILD_ONLYONETHREAD
  28. #ifndef XBOX_ON_DESKTOP
  29. typedef struct _SLIST_HEADER
  30. {
  31. DNSLIST_ENTRY Next;
  32. } SLIST_HEADER;
  33. #endif // ! XBOX_ON_DESKTOP
  34. #else // ! DPNBUILD_ONLYONETHREAD
  35. #ifdef WINCE
  36. #ifdef _X86_
  37. typedef union _SLIST_HEADER {
  38. ULONGLONG Alignment;
  39. struct {
  40. DNSLIST_ENTRY Next;
  41. WORD Depth;
  42. WORD Sequence;
  43. };
  44. } SLIST_HEADER;
  45. #elif _ARM_
  46. typedef struct _SLIST_HEADER
  47. {
  48. DNSLIST_ENTRY Next;
  49. } SLIST_HEADER;
  50. #endif // _X86_ or _ARM_
  51. #endif // WINCE
  52. #endif // ! DPNBUILD_ONLYONETHREAD
  53. #define DNSLIST_HEADER SLIST_HEADER
  54. #ifdef DPNBUILD_ONLYONETHREAD
  55. // Single thread builds don't need the operations to be interlocked.
  56. #define DNInitializeSListHead(head) (head)->Next.Next = NULL
  57. inline DNSLIST_ENTRY* DNInterlockedPopEntrySList(DNSLIST_HEADER * ListHead)
  58. {
  59. DNSLIST_ENTRY* pslEntryReturn;
  60. pslEntryReturn = ListHead->Next.Next;
  61. if (pslEntryReturn != NULL)
  62. {
  63. ListHead->Next.Next = pslEntryReturn->Next;
  64. }
  65. return pslEntryReturn;
  66. }
  67. inline DNSLIST_ENTRY* DNInterlockedPushEntrySList(DNSLIST_HEADER * ListHead, DNSLIST_ENTRY * ListEntry)
  68. {
  69. DNSLIST_ENTRY* pslEntryReturn;
  70. pslEntryReturn = ListHead->Next.Next;
  71. ListEntry->Next = pslEntryReturn;
  72. ListHead->Next.Next = ListEntry;
  73. return pslEntryReturn;
  74. }
  75. inline DNSLIST_ENTRY* DNInterlockedFlushSList(DNSLIST_HEADER * ListHead)
  76. {
  77. DNSLIST_ENTRY* pslEntryReturn;
  78. pslEntryReturn = ListHead->Next.Next;
  79. ListHead->Next.Next = NULL;
  80. return pslEntryReturn;
  81. }
  82. inline DNSLIST_ENTRY* DNInterlockedPushListSList(DNSLIST_HEADER * ListHead, DNSLIST_ENTRY * List, DNSLIST_ENTRY * ListEnd, USHORT Count)
  83. {
  84. DNSLIST_ENTRY* pslEntryReturn;
  85. pslEntryReturn = ListHead->Next.Next;
  86. ListEnd->Next = pslEntryReturn;
  87. ListHead->Next.Next = List;
  88. return pslEntryReturn;
  89. }
  90. #else // ! DPNBUILD_ONLYONETHREAD
  91. #if defined(_WIN64)
  92. // _WIN64 has always had these available, so just use them directly
  93. #define DNInitializeSListHead InitializeSListHead
  94. #define DNInterlockedPopEntrySList InterlockedPopEntrySList
  95. #define DNInterlockedPushEntrySList InterlockedPushEntrySList
  96. #define DNInterlockedFlushSList InterlockedFlushSList
  97. #elif defined(WINCE) && defined(_ARM_)
  98. #define InterlockedPushList \
  99. ((void *(*)(void *pHead, void *pItem))(PUserKData+0x398))
  100. #define InterlockedPopList \
  101. ((void *(*)(void *pHead))(PUserKData+0x380))
  102. #define DNInitializeSListHead(head) (head)->Next.Next = NULL
  103. #define DNInterlockedPopEntrySList (DNSLIST_ENTRY*)InterlockedPopList
  104. #define DNInterlockedPushEntrySList (DNSLIST_ENTRY*)InterlockedPushList
  105. #define DNInterlockedFlushSList(head) (DNSLIST_ENTRY*)DNInterlockedExchange((LONG*)(head), 0)
  106. #elif defined(_X86_)
  107. #define DNInitializeSListHead(ListHead) (ListHead)->Alignment = 0
  108. DNSLIST_ENTRY* WINAPI DNInterlockedPopEntrySList(DNSLIST_HEADER * ListHead);
  109. DNSLIST_ENTRY* WINAPI DNInterlockedPushEntrySList(DNSLIST_HEADER * ListHead, DNSLIST_ENTRY * ListEntry);
  110. DNSLIST_ENTRY* WINAPI DNInterlockedFlushSList(DNSLIST_HEADER * ListHead);
  111. #else
  112. #error("Unknown platform")
  113. #endif // Platform
  114. #endif // ! DPNBUILD_ONLYONETHREAD
  115. // Unfortunately no platform has this exposed to user-mode.
  116. //
  117. // For now, ARM, IA64 and AMD64 do not have assembly versions of these, and it's important to
  118. // note that while our custom implementation *is* interlocked on those platforms, it is *not* atomic.
  119. // This means that the list won't get corrupted, but the items will not be transferred from the
  120. // source list to the target list in a single interlocked operation. Additionally, the items from the
  121. // source list will be added in reverse order.
  122. DNSLIST_ENTRY* WINAPI DNInterlockedPushListSList(DNSLIST_HEADER * ListHead, DNSLIST_ENTRY * List, DNSLIST_ENTRY * ListEnd, USHORT Count);
  123. #endif // __DNSLIST_H__