SylixOS磁盤高速傳輸

  1. SylixOS管線模型分析

    前文主要介紹了SylixOS中的塊設備CACHE管理,本章主要介紹磁盤高速傳輸。在CAHCE回寫中SyilxOS採起了兩種方式,即直接回寫和多管線併發回寫。併發寫管線經過多線程併發處理CACHE提交的寫請求,實現磁盤高速傳輸。緩存

    SylixOS中經過LW_DISKCACHE_WP結構體管理併發寫管線,該結構體的具體內容如程序清單 1-1所示。多線程

    程序清單 1-1併發

     

    typedef struct {
        BOOL                    DISKCWP_bExit;                      /*  是否須要退出                */
        BOOL                    DISKCWP_bCacheCoherence;            /*  CACHE 一致性標誌            */
        BOOL                    DISKCWP_bParallel;                  /*  並行化讀寫支持              */
        
        INT                     DISKCWP_iPipeline;                  /*  寫管線線程數                */
        INT                     DISKCWP_iMsgCount;                  /*  寫消息緩衝個數              */
        
        PVOID                   DISKCWP_pvRBurstBuffer;             /*  管線緩存                    */
        PVOID                   DISKCWP_pvWBurstBuffer;             /*  管線緩存                    */
        
        LW_OBJECT_HANDLE        DISKCWP_hMsgQueue;                  /*  管線刷新隊列                */
        LW_OBJECT_HANDLE        DISKCWP_hCounter;                   /*  計數信號量                  */
        LW_OBJECT_HANDLE        DISKCWP_hPart;                      /*  管線緩存管理                */
        LW_OBJECT_HANDLE        DISKCWP_hSync;                      /*  排空信號                    */
        LW_OBJECT_HANDLE        DISKCWP_hDev;                       /*  非併發設備鎖                */
        LW_OBJECT_HANDLE        DISKCWP_hWThread[LW_CFG_DISKCACHE_MAX_PIPELINE];
                                                                    /*  管線寫任務表                */
    } LW_DISKCACHE_WP;
    typedef LW_DISKCACHE_WP    *PLW_DISKCACHE_WP;

     

    DISKCWP_bExit:爲LW_TRUE時,寫管線線程將會退出;函數

    DISKCWP_bCacheCoherence:爲LW_TRUE時,管線緩存將使用非緩衝的內存;spa

    DISKCWP_bParallel:並行化讀寫支持,若是不支持則須要在操做設備前調用設備鎖,防止併發操做;線程

    DISKCWP_iPipeline:寫管線線程數,爲0時表示不是用併發寫管線;接口

    DISKCWP_iMsgCount:寫消息緩衝個數,最小爲DCATTR_iPipeline, 能夠爲 DCATTR_iPipeline 的2 ~ 8 倍;隊列

    DISKCWP_hMsgQueue:管線刷新隊列,上層經過發送一個消息,發起一個寫請求;ip

    DISKCWP_hCounter:計數信號量,用於計數當前緩衝塊,發起寫請求時申請,完成回寫時釋放;內存

    DISKCWP_hPart:經過定長內存管理管線緩存;

    DISKCWP_hDev:非併發設備鎖;

    DISKCWP_hWThread:管線寫任務表;

    DISKCWP_hSync:排空信號,用於回寫完成後同步。

  2. 寫管線建立

    寫管線的建立經過調用__diskCacheWpCreate函數來完成,其函數原型如程序清單 1-2所示。

    程序清單 1-2

     

    INT   __diskCacheWpCreate(PLW_DISKCACHE_CB  pdiskc,
                              PLW_DISKCACHE_WP  pwp, 
                              BOOL              bCacheCoherence,
                              BOOL              bParallel,
                              INT               iPipeline, 
                              INT               iMsgCount,
                              INT               iMaxRBurstSector,
                              INT               iMaxWBurstSector,
                              ULONG             ulBytesPerSector);

     

    函數__diskCacheWpCreate原型分析:

    pdiskc:                    緩衝控制塊

    pwp:                        併發寫管線控制塊

    bCacheCoherence:         CACHE 一致性需求

    bParallel:                併發讀寫支持

    iPipeline:                寫管線線程數

    iMsgCount:                管線總消息個數

    iMaxRBurstSector:        讀猝發長度

    iMaxWBurstSector:        寫猝發長度

    ulBytesPerSector:         每扇區大小

    函數__diskCacheWpCreate根據入參建立對應的寫管線,並填充相關信息到併發寫管線控制控制結構體,其建立流程以下所示。

    1. 建立管線緩存

    2. 建立管線刷新隊列

    3. 建立計數信號量

    4. 建立內存分區緩存管理

    5. 建立排空信號

    6. 建立非併發設備鎖

    7. 建立寫管線線程組

  3. 寫管線線程

    寫管線線程的函數原型如程序清單 1-3所示。

    程序清單 1-3

     

    static PVOID  __diskCacheWpThread (PVOID  pvArg)

     

    參數pvArg爲PLW_DISKCACHE_CB類型的磁盤緩衝控制塊。管線線程運行後,循環等待接收管線刷新消息。其中消息類型如程序清單 1-4所示。

    程序清單 1-4

     

    typedef struct {
        ULONG                   DISKCWPM_ulStartSector;             /*  起始扇區                    */
        ULONG                   DISKCWPM_ulNSector;                 /*  扇區數量                    */
        PVOID                   DISKCWPM_pvBuffer;                  /*  扇區緩衝                    */
    } LW_DISKCACHE_WPMSG;
    typedef LW_DISKCACHE_WPMSG *PLW_DISKCACHE_WPMSG;

     

    當線程接收到消息後,根據消息中的信息調用具體的硬件接口進行寫操做。完成寫操做後,須要釋放消息中的內存塊以及計數信號量和同步信號,接着進入下一次循環等待接收消息。

  4. SyilxOS管線使用

    當支持併發寫管線時,能夠經過調用__diskCacheWpGetBuffer函數在已初始化後的內存分區中申請一個內存塊,該函數的具體實現如程序清單 2-1所示。

    程序清單 2-1

     

    PVOID  __diskCacheWpGetBuffer (PLW_DISKCACHE_WP  pwp, BOOL bRead)
    {
        PVOID  pvRet;
    
        if (bRead) {
            return  (pwp->DISKCWP_pvRBurstBuffer);
        }
    
        if (pwp->DISKCWP_iPipeline == 0) {
            return  (pwp->DISKCWP_pvWBurstBuffer);
        }
        
        if (API_SemaphoreCPend(pwp->DISKCWP_hCounter, LW_OPTION_WAIT_INFINITE)) {
            _BugHandle(LW_TRUE, LW_TRUE, "diskcache pipeline error!\r\n");
        }
        
        pvRet = API_PartitionGet(pwp->DISKCWP_hPart);
        _BugHandle((pvRet == LW_NULL), LW_TRUE, "diskcache pipeline error!\r\n");
        
        return  (pvRet);
    }

     

    在申請內存塊前,須要先請求計數信號量,計數信號量與內存塊數量相等。當內存分區中已沒有剩餘的內存塊時,線程沒法得到計數信號量進入休眠。當管線線程完成寫操做後會釋放接收到的內存塊,並釋放計數信號量,此時休眠線程成功申請信號量進入就緒態,並順利得到內存塊。

    接着須要將CACHE中的緩衝數據拷貝到內存塊中,並提交一個寫請求。管線線程接收到消息後進行具體的寫操做和資源釋放。寫請求函數如程序清單 2-2所示。

    程序清單 2-2

     

    INT  __diskCacheWpWrite (PLW_DISKCACHE_CB  pdiskc,
                             PLW_BLK_DEV       pblkdDisk,
                             PVOID             pvBuffer,
                             ULONG             ulStartSector,
                             ULONG             ulNSector)
    {
        LW_DISKCACHE_WPMSG  diskcwpm;
        PLW_DISKCACHE_WP    pwp = &pdiskc->DISKC_wpWrite;
    
        if (pwp->DISKCWP_iPipeline == 0) {
            return  (pdiskc->DISKC_pblkdDisk->BLKD_pfuncBlkWrt(pblkdDisk, 
                                                               pvBuffer,
                                                               ulStartSector,
                                                               ulNSector));
        }
        
        diskcwpm.DISKCWPM_ulStartSector = ulStartSector;
        diskcwpm.DISKCWPM_ulNSector     = ulNSector;
        diskcwpm.DISKCWPM_pvBuffer      = pvBuffer;
        
        API_MsgQueueSend2(pwp->DISKCWP_hMsgQueue, &diskcwpm, 
                          sizeof(LW_DISKCACHE_WPMSG), LW_OPTION_WAIT_INFINITE);
    
        return  (ERROR_NONE);
    }

     

    發起寫請求後可經過調用__diskCacheWpSync函數進行寫同步,該函數經過寫管線控制塊中的DISKCWP_hSync信號量實現同步功能。

  5. 參考資料

相關文章
相關標籤/搜索