interlocked.h (6198B)
1/** 2 * WinPR: Windows Portable Runtime 3 * Interlocked Singly-Linked Lists 4 * 5 * Copyright 2012 Marc-Andre Moreau <marcandre.moreau@gmail.com> 6 * 7 * Licensed under the Apache License, Version 2.0 (the "License"); 8 * you may not use this file except in compliance with the License. 9 * You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, software 14 * distributed under the License is distributed on an "AS IS" BASIS, 15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 * See the License for the specific language governing permissions and 17 * limitations under the License. 18 */ 19 20#ifndef WINPR_INTERLOCKED_H 21#define WINPR_INTERLOCKED_H 22 23#include <winpr/spec.h> 24#include <winpr/winpr.h> 25#include <winpr/wtypes.h> 26#include <winpr/platform.h> 27 28#ifdef __cplusplus 29extern "C" 30{ 31#endif 32 33#ifndef _WIN32 34 35#ifndef CONTAINING_RECORD 36#define CONTAINING_RECORD(address, type, field) \ 37 ((type*)(((ULONG_PTR)address) - (ULONG_PTR)(&(((type*)0)->field)))) 38#endif 39 40 typedef struct _WINPR_LIST_ENTRY WINPR_LIST_ENTRY; 41 typedef struct _WINPR_LIST_ENTRY* WINPR_PLIST_ENTRY; 42 43 struct _WINPR_LIST_ENTRY 44 { 45 WINPR_PLIST_ENTRY Flink; 46 WINPR_PLIST_ENTRY Blink; 47 }; 48 49 typedef struct _WINPR_SINGLE_LIST_ENTRY WINPR_SINGLE_LIST_ENTRY; 50 typedef struct _WINPR_SINGLE_LIST_ENTRY* WINPR_PSINGLE_LIST_ENTRY; 51 52 struct _WINPR_SINGLE_LIST_ENTRY 53 { 54 WINPR_PSINGLE_LIST_ENTRY Next; 55 }; 56 57 typedef struct WINPR_LIST_ENTRY32 58 { 59 DWORD Flink; 60 DWORD Blink; 61 } WINPR_LIST_ENTRY32; 62 typedef WINPR_LIST_ENTRY32* WINPR_PLIST_ENTRY32; 63 64 typedef struct WINPR_LIST_ENTRY64 65 { 66 ULONGLONG Flink; 67 ULONGLONG Blink; 68 } WINPR_LIST_ENTRY64; 69 typedef WINPR_LIST_ENTRY64* WINPR_PLIST_ENTRY64; 70 71#ifdef _WIN64 72 73 typedef struct _WINPR_SLIST_ENTRY* WINPR_PSLIST_ENTRY; 74 typedef struct DECLSPEC_ALIGN(16) _WINPR_SLIST_ENTRY 75 { 76 WINPR_PSLIST_ENTRY Next; 77 } WINPR_SLIST_ENTRY; 78 79#else /* _WIN64 */ 80 81#define WINPR_SLIST_ENTRY WINPR_SINGLE_LIST_ENTRY 82#define _WINPR_SLIST_ENTRY _WINPR_SINGLE_LIST_ENTRY 83#define WINPR_PSLIST_ENTRY WINPR_PSINGLE_LIST_ENTRY 84 85#endif /* _WIN64 */ 86 87#ifdef _WIN64 88 89 typedef union DECLSPEC_ALIGN(16) _WINPR_SLIST_HEADER { 90 struct 91 { 92 ULONGLONG Alignment; 93 ULONGLONG Region; 94 } DUMMYSTRUCTNAME; 95 96 struct 97 { 98 ULONGLONG Depth : 16; 99 ULONGLONG Sequence : 9; 100 ULONGLONG NextEntry : 39; 101 ULONGLONG HeaderType : 1; 102 ULONGLONG Init : 1; 103 ULONGLONG Reserved : 59; 104 ULONGLONG Region : 3; 105 } Header8; 106 107 struct 108 { 109 ULONGLONG Depth : 16; 110 ULONGLONG Sequence : 48; 111 ULONGLONG HeaderType : 1; 112 ULONGLONG Reserved : 3; 113 ULONGLONG NextEntry : 60; 114 } HeaderX64; 115 } WINPR_SLIST_HEADER, *WINPR_PSLIST_HEADER; 116 117#else /* _WIN64 */ 118 119 typedef union _WINPR_SLIST_HEADER { 120 ULONGLONG Alignment; 121 122 struct 123 { 124 WINPR_SLIST_ENTRY Next; 125 WORD Depth; 126 WORD Sequence; 127 } DUMMYSTRUCTNAME; 128 } WINPR_SLIST_HEADER, *WINPR_PSLIST_HEADER; 129 130#endif /* _WIN64 */ 131 132 /* Singly-Linked List */ 133 134 WINPR_API VOID InitializeSListHead(WINPR_PSLIST_HEADER ListHead); 135 136 WINPR_API WINPR_PSLIST_ENTRY InterlockedPushEntrySList(WINPR_PSLIST_HEADER ListHead, 137 WINPR_PSLIST_ENTRY ListEntry); 138 WINPR_API WINPR_PSLIST_ENTRY InterlockedPushListSListEx(WINPR_PSLIST_HEADER ListHead, 139 WINPR_PSLIST_ENTRY List, 140 WINPR_PSLIST_ENTRY ListEnd, 141 ULONG Count); 142 WINPR_API WINPR_PSLIST_ENTRY InterlockedPopEntrySList(WINPR_PSLIST_HEADER ListHead); 143 WINPR_API WINPR_PSLIST_ENTRY InterlockedFlushSList(WINPR_PSLIST_HEADER ListHead); 144 145 WINPR_API USHORT QueryDepthSList(WINPR_PSLIST_HEADER ListHead); 146 147 WINPR_API LONG InterlockedIncrement(LONG volatile* Addend); 148 WINPR_API LONG InterlockedDecrement(LONG volatile* Addend); 149 150 WINPR_API LONG InterlockedExchange(LONG volatile* Target, LONG Value); 151 WINPR_API LONG InterlockedExchangeAdd(LONG volatile* Addend, LONG Value); 152 153 WINPR_API LONG InterlockedCompareExchange(LONG volatile* Destination, LONG Exchange, 154 LONG Comperand); 155 156 WINPR_API PVOID InterlockedCompareExchangePointer(PVOID volatile* Destination, PVOID Exchange, 157 PVOID Comperand); 158 159#else /* _WIN32 */ 160#define WINPR_LIST_ENTRY LIST_ENTRY 161#define _WINPR_LIST_ENTRY _LIST_ENTRY 162#define WINPR_PLIST_ENTRY PLIST_ENTRY 163 164#define WINPR_SINGLE_LIST_ENTRY SINGLE_LIST_ENTRY 165#define _WINPR_SINGLE_LIST_ENTRY _SINGLE_LIST_ENTRY 166#define WINPR_PSINGLE_LIST_ENTRY PSINGLE_LIST_ENTRY 167 168#define WINPR_SLIST_ENTRY SLIST_ENTRY 169#define _WINPR_SLIST_ENTRY _SLIST_ENTRY 170#define WINPR_PSLIST_ENTRY PSLIST_ENTRY 171 172#define WINPR_SLIST_HEADER SLIST_HEADER 173#define _WINPR_SLIST_HEADER _SLIST_HEADER 174#define WINPR_PSLIST_HEADER PSLIST_HEADER 175 176#endif /* _WIN32 */ 177 178#if (!defined(_WIN32) || \ 179 (defined(_WIN32) && (_WIN32_WINNT < 0x0502) && !defined(InterlockedCompareExchange64))) 180#define WINPR_INTERLOCKED_COMPARE_EXCHANGE64 1 181#endif 182 183#ifdef WINPR_INTERLOCKED_COMPARE_EXCHANGE64 184 185 WINPR_API LONGLONG InterlockedCompareExchange64(LONGLONG volatile* Destination, 186 LONGLONG Exchange, LONGLONG Comperand); 187 188#endif 189 190 /* Doubly-Linked List */ 191 192 WINPR_API VOID InitializeListHead(WINPR_PLIST_ENTRY ListHead); 193 194 WINPR_API BOOL IsListEmpty(const WINPR_LIST_ENTRY* ListHead); 195 196 WINPR_API BOOL RemoveEntryList(WINPR_PLIST_ENTRY Entry); 197 198 WINPR_API VOID InsertHeadList(WINPR_PLIST_ENTRY ListHead, WINPR_PLIST_ENTRY Entry); 199 WINPR_API WINPR_PLIST_ENTRY RemoveHeadList(WINPR_PLIST_ENTRY ListHead); 200 201 WINPR_API VOID InsertTailList(WINPR_PLIST_ENTRY ListHead, WINPR_PLIST_ENTRY Entry); 202 WINPR_API WINPR_PLIST_ENTRY RemoveTailList(WINPR_PLIST_ENTRY ListHead); 203 WINPR_API VOID AppendTailList(WINPR_PLIST_ENTRY ListHead, WINPR_PLIST_ENTRY ListToAppend); 204 205 WINPR_API VOID PushEntryList(WINPR_PSINGLE_LIST_ENTRY ListHead, WINPR_PSINGLE_LIST_ENTRY Entry); 206 WINPR_API WINPR_PSINGLE_LIST_ENTRY PopEntryList(WINPR_PSINGLE_LIST_ENTRY ListHead); 207 208#ifdef __cplusplus 209} 210#endif 211 212#endif /* WINPR_INTERLOCKED_H */