summaryrefslogtreecommitdiff
path: root/network/netadaptercx/netvadapterlibrary/code/memory.cpp
blob: 0c010d59db3b0e1704ac9f52e24032f75c134a04 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
// Copyright (C) Microsoft Corporation. All rights reserved.
#include "pch.hpp"
#include "memory.h"
#include <netadaptercx.h>
#include "trace.h"
#include "memory.tmh"

#if ((NETADAPTER_VERSION_MAJOR == 2) && (NETADAPTER_VERSION_MINOR >= 6))

NTSTATUS
Memory::Initialize(
    NETMEMORYCOLLECTION MemoryCollection,
    size_t BufferSize
)
{
    m_memoryCollection = MemoryCollection;
    
    for (size_t i = 0; i < PREALLOCATED_BUFFERS_COUNT; i++)
    {
        NET_MEMORY_CONFIG memoryConfig{};
        NET_MEMORY_CONFIG_INIT(
            &memoryConfig,
            m_buffers[i].VirtualAddress,
            BufferSize);

        RETURN_IF_NOT_STATUS_SUCCESS(
            NetMemoryCreate(
                MemoryCollection,
                &memoryConfig,
                &m_buffers[i].MemoryId
            ));
         
        m_buffersReadyToUse[i] = &m_buffers[i];
    }

    m_lastBufferToUse = PREALLOCATED_BUFFERS_COUNT;
    return STATUS_SUCCESS;
}

void
Memory::ReleaseAllMappings(
    void
)
{
    for (size_t i = 0; i < PREALLOCATED_BUFFERS_COUNT; i++)
    {
        NetMemoryDestroy(m_memoryCollection, m_buffers[i].MemoryId);
    }

    m_lastBufferToUse = 0;
    RtlZeroMemory(m_buffersReadyToUse, sizeof(m_buffersReadyToUse));
}

MemoryBuffer*
Memory::PopAvailableBuffer(
    void
)
{
    KAcquireSpinLock lock{ m_spinLock };

    if (m_lastBufferToUse == 0)
    {
        return nullptr;
    }

    return m_buffersReadyToUse[--m_lastBufferToUse];
}

void
Memory::ReturnBuffer(
    MemoryBuffer* Buffer
)
{
    KAcquireSpinLock lock{ m_spinLock };

    NT_FRE_ASSERT(m_lastBufferToUse < PREALLOCATED_BUFFERS_COUNT);

    m_buffersReadyToUse[m_lastBufferToUse++] = Buffer;
}
#endif //NETCX 2.6 only

// for wil::make_unique_nothrow
void*
operator new(size_t s, std::nothrow_t const&)
{
    return operator new(s);
}