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

/*==========================================================================
*
* Copyright (C) 2001-2002 Microsoft Corporation. All Rights Reserved.
*
* File: dnslist.h
* Content: DirectPlay implementations of OS SLIST functions
*
* History:
* Date By Reason
* ==== == ======
* 10/30/2001 masonb Created
* 11/07/2001 vanceo Added InterlockedPushListSList and made DNInitializeSListHead return value on Win64
*
***************************************************************************/
#ifndef __DNSLIST_H__
#define __DNSLIST_H__
// We build separate NT and 9x binaries, but even in the NT binary we can't be sure the system has the
// SLIST functions available since they weren't on Win2k. The only place we can be sure that the SLIST
// functions are available is on 64-bit NT platforms.
// We don't supply a DNQueryDepthSList method because not all platforms can support it.
// SINGLE_LIST_ENTRY is defined in winnt.h and contains only a Next pointer
// to another SINGLE_LIST_ENTRY
#if defined(WINCE) || defined(DPNBUILD_ONLYONETHREAD)
#define SLIST_ENTRY SINGLE_LIST_ENTRY
#endif // WINCE or DPNBUILD_ONLYONETHREAD
#define DNSLIST_ENTRY SLIST_ENTRY
#ifdef DPNBUILD_ONLYONETHREAD
#ifndef XBOX_ON_DESKTOP
typedef struct _SLIST_HEADER
{
DNSLIST_ENTRY Next;
} SLIST_HEADER;
#endif // ! XBOX_ON_DESKTOP
#else // ! DPNBUILD_ONLYONETHREAD
#ifdef WINCE
#ifdef _X86_
typedef union _SLIST_HEADER {
ULONGLONG Alignment;
struct {
DNSLIST_ENTRY Next;
WORD Depth;
WORD Sequence;
};
} SLIST_HEADER;
#elif _ARM_
typedef struct _SLIST_HEADER
{
DNSLIST_ENTRY Next;
} SLIST_HEADER;
#endif // _X86_ or _ARM_
#endif // WINCE
#endif // ! DPNBUILD_ONLYONETHREAD
#define DNSLIST_HEADER SLIST_HEADER
#ifdef DPNBUILD_ONLYONETHREAD
// Single thread builds don't need the operations to be interlocked.
#define DNInitializeSListHead(head) (head)->Next.Next = NULL
inline DNSLIST_ENTRY* DNInterlockedPopEntrySList(DNSLIST_HEADER * ListHead)
{
DNSLIST_ENTRY* pslEntryReturn;
pslEntryReturn = ListHead->Next.Next;
if (pslEntryReturn != NULL)
{
ListHead->Next.Next = pslEntryReturn->Next;
}
return pslEntryReturn;
}
inline DNSLIST_ENTRY* DNInterlockedPushEntrySList(DNSLIST_HEADER * ListHead, DNSLIST_ENTRY * ListEntry)
{
DNSLIST_ENTRY* pslEntryReturn;
pslEntryReturn = ListHead->Next.Next;
ListEntry->Next = pslEntryReturn;
ListHead->Next.Next = ListEntry;
return pslEntryReturn;
}
inline DNSLIST_ENTRY* DNInterlockedFlushSList(DNSLIST_HEADER * ListHead)
{
DNSLIST_ENTRY* pslEntryReturn;
pslEntryReturn = ListHead->Next.Next;
ListHead->Next.Next = NULL;
return pslEntryReturn;
}
inline DNSLIST_ENTRY* DNInterlockedPushListSList(DNSLIST_HEADER * ListHead, DNSLIST_ENTRY * List, DNSLIST_ENTRY * ListEnd, USHORT Count)
{
DNSLIST_ENTRY* pslEntryReturn;
pslEntryReturn = ListHead->Next.Next;
ListEnd->Next = pslEntryReturn;
ListHead->Next.Next = List;
return pslEntryReturn;
}
#else // ! DPNBUILD_ONLYONETHREAD
#if defined(_WIN64)
// _WIN64 has always had these available, so just use them directly
#define DNInitializeSListHead InitializeSListHead
#define DNInterlockedPopEntrySList InterlockedPopEntrySList
#define DNInterlockedPushEntrySList InterlockedPushEntrySList
#define DNInterlockedFlushSList InterlockedFlushSList
#elif defined(WINCE) && defined(_ARM_)
#define InterlockedPushList \
((void *(*)(void *pHead, void *pItem))(PUserKData+0x398))
#define InterlockedPopList \
((void *(*)(void *pHead))(PUserKData+0x380))
#define DNInitializeSListHead(head) (head)->Next.Next = NULL
#define DNInterlockedPopEntrySList (DNSLIST_ENTRY*)InterlockedPopList
#define DNInterlockedPushEntrySList (DNSLIST_ENTRY*)InterlockedPushList
#define DNInterlockedFlushSList(head) (DNSLIST_ENTRY*)DNInterlockedExchange((LONG*)(head), 0)
#elif defined(_X86_)
#define DNInitializeSListHead(ListHead) (ListHead)->Alignment = 0
DNSLIST_ENTRY* WINAPI DNInterlockedPopEntrySList(DNSLIST_HEADER * ListHead);
DNSLIST_ENTRY* WINAPI DNInterlockedPushEntrySList(DNSLIST_HEADER * ListHead, DNSLIST_ENTRY * ListEntry);
DNSLIST_ENTRY* WINAPI DNInterlockedFlushSList(DNSLIST_HEADER * ListHead);
#else
#error("Unknown platform")
#endif // Platform
#endif // ! DPNBUILD_ONLYONETHREAD
// Unfortunately no platform has this exposed to user-mode.
//
// For now, ARM, IA64 and AMD64 do not have assembly versions of these, and it's important to
// note that while our custom implementation *is* interlocked on those platforms, it is *not* atomic.
// This means that the list won't get corrupted, but the items will not be transferred from the
// source list to the target list in a single interlocked operation. Additionally, the items from the
// source list will be added in reverse order.
DNSLIST_ENTRY* WINAPI DNInterlockedPushListSList(DNSLIST_HEADER * ListHead, DNSLIST_ENTRY * List, DNSLIST_ENTRY * ListEnd, USHORT Count);
#endif // __DNSLIST_H__