Blame winpr/include/winpr/interlocked.h

Packit 1fb8d4
/**
Packit 1fb8d4
 * WinPR: Windows Portable Runtime
Packit 1fb8d4
 * Interlocked Singly-Linked Lists
Packit 1fb8d4
 *
Packit 1fb8d4
 * Copyright 2012 Marc-Andre Moreau <marcandre.moreau@gmail.com>
Packit 1fb8d4
 *
Packit 1fb8d4
 * Licensed under the Apache License, Version 2.0 (the "License");
Packit 1fb8d4
 * you may not use this file except in compliance with the License.
Packit 1fb8d4
 * You may obtain a copy of the License at
Packit 1fb8d4
 *
Packit 1fb8d4
 *     http://www.apache.org/licenses/LICENSE-2.0
Packit 1fb8d4
 *
Packit 1fb8d4
 * Unless required by applicable law or agreed to in writing, software
Packit 1fb8d4
 * distributed under the License is distributed on an "AS IS" BASIS,
Packit 1fb8d4
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
Packit 1fb8d4
 * See the License for the specific language governing permissions and
Packit 1fb8d4
 * limitations under the License.
Packit 1fb8d4
 */
Packit 1fb8d4
Packit 1fb8d4
#ifndef WINPR_INTERLOCKED_H
Packit 1fb8d4
#define WINPR_INTERLOCKED_H
Packit 1fb8d4
Packit 1fb8d4
#include <winpr/spec.h>
Packit 1fb8d4
#include <winpr/winpr.h>
Packit 1fb8d4
#include <winpr/wtypes.h>
Packit 1fb8d4
#include <winpr/platform.h>
Packit 1fb8d4
Packit 1fb8d4
#ifdef __cplusplus
Packit Service 5a9772
extern "C"
Packit Service 5a9772
{
Packit 1fb8d4
#endif
Packit 1fb8d4
Packit 1fb8d4
#ifndef _WIN32
Packit 1fb8d4
Packit 1fb8d4
#ifndef CONTAINING_RECORD
Packit 1fb8d4
#define CONTAINING_RECORD(address, type, field) \
Packit Service 5a9772
	((type*)(((ULONG_PTR)address) - (ULONG_PTR)(&(((type*)0)->field))))
Packit 1fb8d4
#endif
Packit 1fb8d4
Packit Service 5a9772
	typedef struct _WINPR_LIST_ENTRY WINPR_LIST_ENTRY;
Packit Service 5a9772
	typedef struct _WINPR_LIST_ENTRY* WINPR_PLIST_ENTRY;
Packit 1fb8d4
Packit Service 5a9772
	struct _WINPR_LIST_ENTRY
Packit Service 5a9772
	{
Packit 1fb8d4
		WINPR_PLIST_ENTRY Flink;
Packit 1fb8d4
		WINPR_PLIST_ENTRY Blink;
Packit Service 5a9772
	};
Packit 1fb8d4
Packit Service 5a9772
	typedef struct _WINPR_SINGLE_LIST_ENTRY WINPR_SINGLE_LIST_ENTRY;
Packit Service 5a9772
	typedef struct _WINPR_SINGLE_LIST_ENTRY* WINPR_PSINGLE_LIST_ENTRY;
Packit 1fb8d4
Packit Service 5a9772
	struct _WINPR_SINGLE_LIST_ENTRY
Packit Service 5a9772
	{
Packit 1fb8d4
		WINPR_PSINGLE_LIST_ENTRY Next;
Packit Service 5a9772
	};
Packit 1fb8d4
Packit Service 5a9772
	typedef struct WINPR_LIST_ENTRY32
Packit Service 5a9772
	{
Packit Service 5a9772
		DWORD Flink;
Packit Service 5a9772
		DWORD Blink;
Packit Service 5a9772
	} WINPR_LIST_ENTRY32;
Packit Service 5a9772
	typedef WINPR_LIST_ENTRY32* WINPR_PLIST_ENTRY32;
Packit 1fb8d4
Packit Service 5a9772
	typedef struct WINPR_LIST_ENTRY64
Packit Service 5a9772
	{
Packit Service 5a9772
		ULONGLONG Flink;
Packit Service 5a9772
		ULONGLONG Blink;
Packit Service 5a9772
	} WINPR_LIST_ENTRY64;
Packit Service 5a9772
	typedef WINPR_LIST_ENTRY64* WINPR_PLIST_ENTRY64;
Packit 1fb8d4
Packit 1fb8d4
#ifdef _WIN64
Packit 1fb8d4
Packit Service 5a9772
	typedef struct _WINPR_SLIST_ENTRY* WINPR_PSLIST_ENTRY;
Packit Service 5a9772
	typedef struct DECLSPEC_ALIGN(16) _WINPR_SLIST_ENTRY
Packit Service 5a9772
	{
Packit Service 5a9772
		WINPR_PSLIST_ENTRY Next;
Packit Service 5a9772
	} WINPR_SLIST_ENTRY;
Packit 1fb8d4
Packit Service 5a9772
#else /* _WIN64 */
Packit 1fb8d4
Packit 1fb8d4
#define WINPR_SLIST_ENTRY WINPR_SINGLE_LIST_ENTRY
Packit 1fb8d4
#define _WINPR_SLIST_ENTRY _WINPR_SINGLE_LIST_ENTRY
Packit 1fb8d4
#define WINPR_PSLIST_ENTRY WINPR_PSINGLE_LIST_ENTRY
Packit 1fb8d4
Packit 1fb8d4
#endif /* _WIN64 */
Packit 1fb8d4
Packit 1fb8d4
#ifdef _WIN64
Packit 1fb8d4
Packit Service 5a9772
	typedef union DECLSPEC_ALIGN(16) _WINPR_SLIST_HEADER {
Packit Service 5a9772
		struct
Packit Service 5a9772
		{
Packit Service 5a9772
			ULONGLONG Alignment;
Packit Service 5a9772
			ULONGLONG Region;
Packit Service 5a9772
		} DUMMYSTRUCTNAME;
Packit Service 5a9772
Packit Service 5a9772
		struct
Packit Service 5a9772
		{
Packit Service 5a9772
			ULONGLONG Depth : 16;
Packit Service 5a9772
			ULONGLONG Sequence : 9;
Packit Service 5a9772
			ULONGLONG NextEntry : 39;
Packit Service 5a9772
			ULONGLONG HeaderType : 1;
Packit Service 5a9772
			ULONGLONG Init : 1;
Packit Service 5a9772
			ULONGLONG Reserved : 59;
Packit Service 5a9772
			ULONGLONG Region : 3;
Packit Service 5a9772
		} Header8;
Packit Service 5a9772
Packit Service 5a9772
		struct
Packit Service 5a9772
		{
Packit Service 5a9772
			ULONGLONG Depth : 16;
Packit Service 5a9772
			ULONGLONG Sequence : 48;
Packit Service 5a9772
			ULONGLONG HeaderType : 1;
Packit Service 5a9772
			ULONGLONG Reserved : 3;
Packit Service 5a9772
			ULONGLONG NextEntry : 60;
Packit Service 5a9772
		} HeaderX64;
Packit Service 5a9772
	} WINPR_SLIST_HEADER, *WINPR_PSLIST_HEADER;
Packit Service 5a9772
Packit Service 5a9772
#else /* _WIN64 */
Packit Service 5a9772
Packit Service 5a9772
	typedef union _WINPR_SLIST_HEADER {
Packit 1fb8d4
		ULONGLONG Alignment;
Packit 1fb8d4
Packit Service 5a9772
		struct
Packit Service 5a9772
		{
Packit Service 5a9772
			WINPR_SLIST_ENTRY Next;
Packit Service 5a9772
			WORD Depth;
Packit Service 5a9772
			WORD Sequence;
Packit Service 5a9772
		} DUMMYSTRUCTNAME;
Packit Service 5a9772
	} WINPR_SLIST_HEADER, *WINPR_PSLIST_HEADER;
Packit 1fb8d4
Packit 1fb8d4
#endif /* _WIN64 */
Packit 1fb8d4
Packit Service 5a9772
	/* Singly-Linked List */
Packit 1fb8d4
Packit Service 5a9772
	WINPR_API VOID InitializeSListHead(WINPR_PSLIST_HEADER ListHead);
Packit 1fb8d4
Packit Service 5a9772
	WINPR_API WINPR_PSLIST_ENTRY InterlockedPushEntrySList(WINPR_PSLIST_HEADER ListHead,
Packit Service 5a9772
	                                                       WINPR_PSLIST_ENTRY ListEntry);
Packit Service 5a9772
	WINPR_API WINPR_PSLIST_ENTRY InterlockedPushListSListEx(WINPR_PSLIST_HEADER ListHead,
Packit Service 5a9772
	                                                        WINPR_PSLIST_ENTRY List,
Packit Service 5a9772
	                                                        WINPR_PSLIST_ENTRY ListEnd,
Packit Service 5a9772
	                                                        ULONG Count);
Packit Service 5a9772
	WINPR_API WINPR_PSLIST_ENTRY InterlockedPopEntrySList(WINPR_PSLIST_HEADER ListHead);
Packit Service 5a9772
	WINPR_API WINPR_PSLIST_ENTRY InterlockedFlushSList(WINPR_PSLIST_HEADER ListHead);
Packit 1fb8d4
Packit Service 5a9772
	WINPR_API USHORT QueryDepthSList(WINPR_PSLIST_HEADER ListHead);
Packit 1fb8d4
Packit Service 5a9772
	WINPR_API LONG InterlockedIncrement(LONG volatile* Addend);
Packit Service 5a9772
	WINPR_API LONG InterlockedDecrement(LONG volatile* Addend);
Packit 1fb8d4
Packit Service 5a9772
	WINPR_API LONG InterlockedExchange(LONG volatile* Target, LONG Value);
Packit Service 5a9772
	WINPR_API LONG InterlockedExchangeAdd(LONG volatile* Addend, LONG Value);
Packit 1fb8d4
Packit Service 5a9772
	WINPR_API LONG InterlockedCompareExchange(LONG volatile* Destination, LONG Exchange,
Packit Service 5a9772
	                                          LONG Comperand);
Packit 1fb8d4
Packit Service 5a9772
	WINPR_API PVOID InterlockedCompareExchangePointer(PVOID volatile* Destination, PVOID Exchange,
Packit Service 5a9772
	                                                  PVOID Comperand);
Packit 1fb8d4
Packit 1fb8d4
#else /* _WIN32 */
Packit 1fb8d4
#define WINPR_LIST_ENTRY LIST_ENTRY
Packit 1fb8d4
#define _WINPR_LIST_ENTRY _LIST_ENTRY
Packit 1fb8d4
#define WINPR_PLIST_ENTRY PLIST_ENTRY
Packit 1fb8d4
Packit 1fb8d4
#define WINPR_SINGLE_LIST_ENTRY SINGLE_LIST_ENTRY
Packit 1fb8d4
#define _WINPR_SINGLE_LIST_ENTRY _SINGLE_LIST_ENTRY
Packit 1fb8d4
#define WINPR_PSINGLE_LIST_ENTRY PSINGLE_LIST_ENTRY
Packit 1fb8d4
Packit 1fb8d4
#define WINPR_SLIST_ENTRY SLIST_ENTRY
Packit 1fb8d4
#define _WINPR_SLIST_ENTRY _SLIST_ENTRY
Packit 1fb8d4
#define WINPR_PSLIST_ENTRY PSLIST_ENTRY
Packit 1fb8d4
Packit 1fb8d4
#define WINPR_SLIST_HEADER SLIST_HEADER
Packit 1fb8d4
#define _WINPR_SLIST_HEADER _SLIST_HEADER
Packit 1fb8d4
#define WINPR_PSLIST_HEADER PSLIST_HEADER
Packit 1fb8d4
Packit 1fb8d4
#endif /* _WIN32 */
Packit 1fb8d4
Packit Service 5a9772
#if (!defined(_WIN32) || \
Packit Service 5a9772
     (defined(_WIN32) && (_WIN32_WINNT < 0x0502) && !defined(InterlockedCompareExchange64)))
Packit Service 5a9772
#define WINPR_INTERLOCKED_COMPARE_EXCHANGE64 1
Packit 1fb8d4
#endif
Packit 1fb8d4
Packit 1fb8d4
#ifdef WINPR_INTERLOCKED_COMPARE_EXCHANGE64
Packit 1fb8d4
Packit Service 5a9772
	WINPR_API LONGLONG InterlockedCompareExchange64(LONGLONG volatile* Destination,
Packit Service 5a9772
	                                                LONGLONG Exchange, LONGLONG Comperand);
Packit 1fb8d4
Packit 1fb8d4
#endif
Packit 1fb8d4
Packit Service 5a9772
	/* Doubly-Linked List */
Packit 1fb8d4
Packit Service 5a9772
	WINPR_API VOID InitializeListHead(WINPR_PLIST_ENTRY ListHead);
Packit 1fb8d4
Packit Service 5a9772
	WINPR_API BOOL IsListEmpty(const WINPR_LIST_ENTRY* ListHead);
Packit 1fb8d4
Packit Service 5a9772
	WINPR_API BOOL RemoveEntryList(WINPR_PLIST_ENTRY Entry);
Packit 1fb8d4
Packit Service 5a9772
	WINPR_API VOID InsertHeadList(WINPR_PLIST_ENTRY ListHead, WINPR_PLIST_ENTRY Entry);
Packit Service 5a9772
	WINPR_API WINPR_PLIST_ENTRY RemoveHeadList(WINPR_PLIST_ENTRY ListHead);
Packit 1fb8d4
Packit Service 5a9772
	WINPR_API VOID InsertTailList(WINPR_PLIST_ENTRY ListHead, WINPR_PLIST_ENTRY Entry);
Packit Service 5a9772
	WINPR_API WINPR_PLIST_ENTRY RemoveTailList(WINPR_PLIST_ENTRY ListHead);
Packit Service 5a9772
	WINPR_API VOID AppendTailList(WINPR_PLIST_ENTRY ListHead, WINPR_PLIST_ENTRY ListToAppend);
Packit 1fb8d4
Packit Service 5a9772
	WINPR_API VOID PushEntryList(WINPR_PSINGLE_LIST_ENTRY ListHead, WINPR_PSINGLE_LIST_ENTRY Entry);
Packit Service 5a9772
	WINPR_API WINPR_PSINGLE_LIST_ENTRY PopEntryList(WINPR_PSINGLE_LIST_ENTRY ListHead);
Packit 1fb8d4
Packit 1fb8d4
#ifdef __cplusplus
Packit 1fb8d4
}
Packit 1fb8d4
#endif
Packit 1fb8d4
Packit 1fb8d4
#endif /* WINPR_INTERLOCKED_H */