Aracılığıyla paylaş


Bellek AraBelleği Yaşam Döngüsü

Bellek arabelleğinin yaşam döngüsü, arabelleğin oluşturulduğu zamandan silindiği zamana kadar olan süreyi kapsıyor. Bu konu başlığında arabellek kullanım senaryoları ve arabellek silindiğinde bunların nasıl etkilediği açıklanmaktadır.

Çekirdek modu sürücü çerçevesinde (KMDF), istek nesnesi G/Ç isteğini temsil eder. Her istek nesnesi bir veya daha fazla bellek nesnesiyle ilişkilendirilir ve her bellek nesnesi istekteki giriş veya çıkış için kullanılan bir arabelleği temsil eder.

Çerçeve gelen G/Ç isteğini temsil eden istek ve bellek nesneleri oluşturduğunda, istek nesnesini ilişkili bellek nesnelerinin üst öğesi olarak ayarlar. Bu nedenle, bellek nesnesi istek nesnesinin ömründen daha uzun süre kalıcı olamaz. Çerçeve tabanlı sürücü G/Ç isteğini tamamladığında, çerçeve istek nesnesini ve bellek nesnesini siler, böylece bu iki nesnenin tanıtıcıları geçersiz hale gelir.

Ancak, altında yatan arabellek farklıdır. Arabelleği oluşturan bileşene ve arabelleği nasıl oluşturduğuna bağlı olarak, arabelleğin bir başvuru sayısı olabilir ve bellek nesnesine ait olabilir veya olmayabilir. Bellek nesnesi arabelleğe sahipse, arabelleğin bir başvuru sayısı vardır ve yaşam süresi bellek nesnesininkiyle belirlenmiştir. Arabelleği başka bir bileşen oluşturduysa, arabellek ve bellek nesnesinin yaşam süreleri birbiriyle ilişkili değildir.

Çerçeve tabanlı bir sürücü, G/Ç hedeflerine göndermek için kendi istek nesnelerini de oluşturabilir. Sürücü tarafından oluşturulan istek, sürücünün G/Ç isteğinde aldığı mevcut bir bellek nesnesini yeniden kullanabilir. G/Ç hedeflerine sık sık istek gönderen bir sürücü, oluşturduğu istek nesnelerini yeniden kullanabilir.

sürücünüzün geçersiz bir tanıtıcıya veya arabellek işaretçisine başvurmayı denemediğinden emin olmak için istek nesnesinin, bellek nesnesinin ve temel alınan arabelleğin kullanım ömrünü anlamak önemlidir.

Aşağıdaki kullanım senaryolarını göz önünde bulundurun:

Senaryo 1: Sürücü KMDF'den bir G/Ç isteği alır, bunu işler ve tamamlar.

En basit senaryoda KMDF sürücüye bir istek göndererek G/Ç gerçekleştirir ve isteği tamamlar. Bu durumda, temel alınan arabellek kullanıcı modu uygulaması, başka bir sürücü veya işletim sisteminin kendisi tarafından oluşturulmuş olabilir. Arabelleklere erişme hakkında bilgi için bkz. Framework-Based Sürücülerindeki Veri Arabelleklerine Erişme.

Sürücü isteği tamamladığında çerçeve bellek nesnesini siler. Arabellek işaretçisi daha sonra geçersiz.

Senaryo 2: Sürücü KMDF'den bir G/Ç isteği alır ve bunu bir G/Ç hedefine iletir.

Bu senaryoda, sürücü isteği bir G/Ç hedefine iletir . Aşağıdaki örnek kod, sürücünün gelen istek nesnesinden bellek nesnesine tanıtıcıyı nasıl alacağını, G/Ç hedefine göndermek için isteği nasıl biçimlendirip isteği gönderdiğini gösterir:

VOID
EvtIoRead(
    IN WDFQUEUE Queue,
    IN WDFREQUEST Request,
    IN size_t Length
    )
{
    NTSTATUS status;
    WDFMEMORY memory;
    WDFIOTARGET ioTarget;
    BOOLEAN ret;
    ioTarget = WdfDeviceGetIoTarget(WdfIoQueueGetDevice(Queue));

    status = WdfRequestRetrieveOutputMemory(Request, &memory);
    if (!NT_SUCCESS(status)) {
        goto End;
    }

    status = WdfIoTargetFormatRequestForRead(ioTarget,
                                    Request,
                                    memory,
                                    NULL,
                                    NULL);
    if (!NT_SUCCESS(status)) {
        goto End;
    }

    WdfRequestSetCompletionRoutine(Request,
                                    RequestCompletionRoutine,
                                    WDF_NO_CONTEXT);

    ret = WdfRequestSend (Request, ioTarget, WDF_NO_SEND_OPTIONS);
    if (!ret) {
        status = WdfRequestGetStatus (Request);
        goto End;
    }

    return;

End:
    WdfRequestComplete(Request, status);
    return;

}

G/Ç hedefi isteği tamamladığında, yapı, sürücünün istek için ayarladığı tamamlama geri çağrısını çağırır. Aşağıdaki kod basit bir tamamlama geri çağırmasını gösterir:

VOID
RequestCompletionRoutine(
    IN WDFREQUEST                  Request,
    IN WDFIOTARGET                 Target,
    PWDF_REQUEST_COMPLETION_PARAMS CompletionParams,
    IN WDFCONTEXT                  Context
    )
{
    UNREFERENCED_PARAMETER(Target);
    UNREFERENCED_PARAMETER(Context);

    WdfRequestComplete(Request, CompletionParams->IoStatus.Status);

    return;

}

Sürücü, tamamlanma geri çağırmasından WdfRequestComplete'i çağırdığında, çerçeve bellek nesnesini siler. Sürücünün edinmiş olduğu bellek nesnesi tanıtıcısı artık geçersiz.

Senaryo 3: Sürücü, var olan bir bellek nesnesini kullanan bir G/Ç isteğinde bulunur.

Bazı sürücüler kendi G/Ç isteklerini oluşturur ve bu istekleri, G/Ç hedef nesneleriyle temsil edilen G/Ç hedeflerine gönderir. Sürücü kendi istek nesnesini oluşturabilir veya çerçeve tarafından oluşturulan bir istek nesnesini yeniden kullanabilir. Bir sürücü, her iki teknikten birini kullanarak önceki bir istekte yer alan bir bellek nesnesini yeniden kullanabilir. Sürücü temel alınan arabelleği değiştirmemelidir, ancak yeni G/Ç isteğini biçimlendirirken arabellek uzaklığını geçirebilir.

Var olan bir bellek nesnesini kullanan yeni bir G/Ç isteğini biçimlendirme hakkında bilgi için bkz. Genel G/Ç Hedeflerine G/Ç İstekleri Gönderme.

Çerçeve, isteği G/Ç hedefine gönderecek şekilde biçimlendirdiğinde, G/Ç hedef nesnesi adına geri dönüştürülmüş bellek nesnesinden bir referans alır. Girdi/Çıktı hedef nesnesi, aşağıdaki durumlardan biri gerçekleşene kadar bu başvuruyu korur.

  • İstek tamamlandı.
  • Sürücü, WdfIoTargetFormatRequestXxx veya WdfIoTargetSendXxSynchronously yöntemlerinden birini çağırarak istek nesnesini yeniden biçimlendirir. Bu yöntemler hakkında daha fazla bilgi için bkz. Çerçeve G/Ç Hedef Nesne Yöntemleri.
  • Sürücü WdfRequestReuse'u çağırır.

Yeni G/Ç isteği tamamlandığında, çerçeve bu istek için sürücünün ayarlandığı G/Ç tamamlama geri çağırmasını çağırır. Bu noktada G/Ç hedef nesnesi hala bellek nesnesi üzerinde bir başvuru barındırıyor. Bu nedenle, G/Ç tamamlama geri çağırmasında, sürücünün bellek nesnesini aldığı özgün isteği tamamlamadan önce sürücü tarafından oluşturulan istek nesnesinde WdfRequestReuse çağrısı yapması gerekir. Sürücü WdfRequestReuse'u çağırmazsa, ek başvuru nedeniyle bir hata denetimi gerçekleşir.

Senaryo 4: Sürücü, yeni bir bellek nesnesi kullanan bir G/Ç isteğinde bulunur.

Çerçeve, temel alınan arabelleğin kaynağına bağlı olarak sürücülerin yeni bellek nesneleri oluşturması için üç yol sağlar. Daha fazla bilgi için bkz. Bellek Arabelleklerinin Kullanımı.

Arabellek, çerçeve veya sürücü tarafından oluşturulmuş bir lookaside listesi tarafından ayrılmışsa, bellek nesnesi arabelleğe sahip olur; bu nedenle, arabellek işaretçisi, bellek nesnesi var olduğu sürece geçerliliğini korur. Zaman uyumsuz G/Ç istekleri veren sürücüler, çerçevenin G/Ç isteği veren sürücüye geri dönene kadar arabelleklerin kalıcı olmasını sağlayabilmesi için her zaman bellek nesnelerine ait arabellekleri kullanmalıdır.

Sürücü WdfMemoryCreatePreallocated çağrısı yaparak yeni bir bellek nesnesine önceden ayrılmış bir arabellek atarsa, bellek nesnesi arabelleğe sahip değildir. Bu durumda, bellek nesnesinin ömrü ve temel alınan arabelleğin ömrü ilişkili değildir. Sürücünün arabellek ömrünü yönetmesi ve geçersiz bir arabellek işaretçisi kullanmayı denememesi gerekir.

Senaryo 5: Sürücü, oluşturduğu bir istek nesnesini yeniden kullanır.

Bir sürücü, oluşturduğu istek nesnelerini yeniden kullanabilir, ancak her yeniden kullanımdan önce WdfRequestReuse çağrısı yaparak bu tür her nesneyi yeniden başlatması gerekir. Daha fazla bilgi için bkz. Çerçeve İstek Nesnelerini Yeniden Kullanma.

İstek nesnesini yeniden başlatan örnek kod için bkz. KMDF sürümüyle birlikte sağlanan Toaster ve NdisEdge örnekleri.