当前位置: 首页 > news >正文

ExpMoveFreeHandles函数分析和备用空闲表的关系

第一部分: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;
            }


文章转载自:

http://2Pktdi1c.hjjfp.cn
http://LGD8bXK0.hjjfp.cn
http://Zf7gLWiT.hjjfp.cn
http://CEckN3je.hjjfp.cn
http://0b52xe6y.hjjfp.cn
http://Tudzbywg.hjjfp.cn
http://5tNZrpch.hjjfp.cn
http://teTy1uGC.hjjfp.cn
http://9gBW2lmo.hjjfp.cn
http://EbrEm5qL.hjjfp.cn
http://YbdSlBGI.hjjfp.cn
http://smPlyK9D.hjjfp.cn
http://bFZT0YsD.hjjfp.cn
http://4ZjH32xO.hjjfp.cn
http://uZd737eT.hjjfp.cn
http://rawbuxPj.hjjfp.cn
http://QoM9RKZ7.hjjfp.cn
http://uWD0m0w6.hjjfp.cn
http://aT9Tzpyg.hjjfp.cn
http://4bqk35TZ.hjjfp.cn
http://3SQSh6lE.hjjfp.cn
http://66yoWvBf.hjjfp.cn
http://7qlRSpM7.hjjfp.cn
http://2Nbh1NdH.hjjfp.cn
http://ee0nqFTQ.hjjfp.cn
http://e0qn9fct.hjjfp.cn
http://Y61lpc4x.hjjfp.cn
http://WxcoVkG9.hjjfp.cn
http://ZAVwxxyC.hjjfp.cn
http://FZLjwwcy.hjjfp.cn
http://www.dtcms.com/a/45547.html

相关文章:

  • IgH详解十八、支持 AoE 读写
  • 汽车小助手智能体
  • 6.7 数据库设计
  • 【FL0100】基于SSM微信小程序的走失人员的报备平台
  • rabbitmq单向ssl认证配置与最佳实践(适用于各大云厂商)
  • docker-compose Install MinerU 0.3 GPU模式
  • 大语言模型概念科普
  • Storm实时流式计算系统(全解)——中
  • Mixture of Experts与Meta Learning深度学习中的两大变革性技术
  • Android 图片压缩详解
  • 神经网络参数量计算
  • sql调优:优化响应时间(优化sql) ; 优化吞吐量
  • HumanPro逼真角色皮肤面部动画Blender插件V1.1版
  • 使用mermaid查看cursor程序生成的流程图
  • 大数据学习(51)-MySQL数据库学习
  • 影刀RPA + AI大语言模型:打造智能自动化流程的超级引擎
  • Java数据类型详解
  • C++ 的编译和链接
  • Nacos + Dubbo3 实现微服务的Rpc调用
  • 【C++奇迹之旅】:字符串转换成数字将数字转换成字符串大全
  • Express MVC
  • Spring基础05
  • git 鼓励频繁提交commit early, commit often,用好分支,多用分支
  • 【SpringBoot+Vue】博客项目开发二:用户登录注册模块
  • 乡村研学旅行小程序(论文源码调试讲解)
  • 行为型模式 - 观察者模式 (Publish/Subscribe)
  • 【华三】从零开始掌握SR技术:原理、架构与应用全解析
  • golang介绍,特点,项目结构,基本变量类型与声明介绍(数组,切片,映射),控制流语句介绍(条件,循环,switch case)
  • 开发一个o2o(线上到线下)商城需要具备以下条件
  • 快速入手-搭建Flask框架封装mysql并结合业务实际情况使用