ExpMoveFreeHandles函数分析和备用空闲表的关系
- 软件开发
- 2025-09-19 19:09:02

第一部分:ExpMoveFreeHandles和备用空闲表的关系
ULONG ExpMoveFreeHandles ( IN PHANDLE_TABLE HandleTable ) { ULONG OldValue, NewValue; ULONG Index, OldIndex, NewIndex, FreeSize; PHANDLE_TABLE_ENTRY Entry, FirstEntry; EXHANDLE Handle; ULONG Idx; BOOLEAN StrictFIFO;
// // First remove all the handles from the free list so we can add them to the // list we use for allocates. //
OldValue = InterlockedExchange ((PLONG)&HandleTable->LastFree, 0); Index = OldValue; if (Index == 0) { // // There are no free handles. Nothing to do. // return OldValue; }
// // We are pushing old entries onto the free list. // We have the A-B-A problem here as these items may have been moved here because // another thread was using them in the pop code. // for (Idx = 1; Idx < HANDLE_TABLE_LOCKS; Idx++) { ExAcquireReleasePushLockExclusive (&HandleTable->HandleTableLock[Idx]); } StrictFIFO = HandleTable->StrictFIFO; //如果我们是严格的FIFO,那么反转列表以减少句柄重用。 // If we are strict FIFO then reverse the list to make handle reuse rare. //
if (!StrictFIFO) { // // We have a complete chain here. If there is no existing chain we // can just push this one without any hassles. If we can't then // we can just fall into the reversing code anyway as we need // to find the end of the chain to continue it. //
// // This is a push so create a new sequence number //
if (InterlockedCompareExchange ((PLONG)&HandleTable->FirstFree, OldValue + GetNextSeq(), 0) == 0) { return OldValue; } }
// // Loop over all the entries and reverse the chain. //遍历所有条目并反转链。 FreeSize = OldIndex = 0; FirstEntry = NULL; while (1) { FreeSize++; Handle.Value = Index; Entry = ExpLookupHandleTableEntry (HandleTable, Handle);
EXASSERT (Entry->Object == NULL);
NewIndex = Entry->NextFreeTableEntry; Entry->NextFreeTableEntry = OldIndex; if (OldIndex == 0) { FirstEntry = Entry; } OldIndex = Index; if (NewIndex == 0) { break; } Index = NewIndex; }
NewValue = ExpInterlockedExchange (&HandleTable->FirstFree, OldIndex, FirstEntry);
// // If we haven't got a pool of a few handles then force // table expansion to keep the free handle size high // if (FreeSize < 100 && StrictFIFO) { OldValue = 0; } return OldValue; }
FORCEINLINE ULONG ExpInterlockedExchange ( IN OUT PULONG Index, IN ULONG FirstIndex, IN PHANDLE_TABLE_ENTRY Entry ) /*++
Routine Description:
This performs the following steps: 1. Set Entry->NextFreeTableEntry = *Index 2. Loops until *Index == (the value of *Index when we entered the function) When they're equal, we set *Index = FirstIndex
Arguments:
Index - Points to the ULONG we want to set. FirstIndex - New value to set Index to.
Entry - TableEntry that will get the initial value of *Index before it's updated.
Return Value:
New value of *Index (i.e. FirstIndex).
--*/ { ULONG OldIndex, NewIndex;
EXASSERT (Entry->Object == NULL);
// // Load new value and generate the sequence number on pushes //
NewIndex = FirstIndex + GetNextSeq();
while (1) {
// // remember original value and // archive it in NextFreeTableEntry. //
OldIndex = *Index; Entry->NextFreeTableEntry = OldIndex;
// // Swap in the new value, and if the swap occurs // successfully, we're done. // if (OldIndex == (ULONG) InterlockedCompareExchange ((PLONG)Index, NewIndex, OldIndex)) { return OldIndex; } } }
第二部分:ExpMoveFreeHandles函数的调用时机 PHANDLE_TABLE_ENTRY ExpAllocateHandleTableEntry ( IN PHANDLE_TABLE HandleTable, OUT PEXHANDLE pHandle ) {
......
while (1) {
OldValue = HandleTable->FirstFree;
while (OldValue == 0) { // // Lock the handle table for exclusive access as we will be // allocating a new table level. // ExpLockHandleTableExclusive (HandleTable, CurrentThread);
// // If we have multiple threads trying to expand the table at // the same time then by just acquiring the table lock we // force those threads to complete their allocations and // populate the free list. We must check the free list here // so we don't expand the list twice without needing to. //
OldValue = HandleTable->FirstFree; if (OldValue != 0) { ExpUnlockHandleTableExclusive (HandleTable, CurrentThread); break; }
//看看我们在备用空闲列表上是否有句柄 // See if we have any handles on the alternate free list // These handles need some locking to move them over. // OldValue = ExpMoveFreeHandles (HandleTable); if (OldValue != 0) { ExpUnlockHandleTableExclusive (HandleTable, CurrentThread); break; }
ExpMoveFreeHandles函数分析和备用空闲表的关系由讯客互联软件开发栏目发布,感谢您对讯客互联的认可,以及对我们原创作品以及文章的青睐,非常欢迎各位朋友分享到个人网站或者朋友圈,但转载请说明文章出处“ExpMoveFreeHandles函数分析和备用空闲表的关系”