blob: b7536531435406232e9c37d1a4f73e4019440ff9 (
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
88
89
90
91
92
93
94
95
96
97
98
|
// 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;
// Create WDF spinlock for the queue, parent to the queue's WDF handle
{
WDF_OBJECT_ATTRIBUTES attributes;
WDF_OBJECT_ATTRIBUTES_INIT(&attributes);
status = WdfSpinLockCreate(&attributes, &m_spinLock);
NT_ASSERT(NT_SUCCESS(status));
}
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
)
{
WdfSpinLockAcquire(m_spinLock);
if (m_lastBufferToUse == 0)
{
WdfSpinLockRelease(m_spinLock);
return nullptr;
}
auto returnbuffer = m_buffersReadyToUse[--m_lastBufferToUse];
WdfSpinLockRelease(m_spinLock);
return returnbuffer;
}
void
Memory::ReturnBuffer(
MemoryBuffer* Buffer
)
{
WdfSpinLockAcquire(m_spinLock);
NT_FRE_ASSERT(m_lastBufferToUse < PREALLOCATED_BUFFERS_COUNT);
m_buffersReadyToUse[m_lastBufferToUse++] = Buffer;
WdfSpinLockRelease(m_spinLock);
}
#endif //NETCX 2.6 only
// for wil::make_unique_nothrow
void*
operator new(size_t s, std::nothrow_t const&)
{
return operator new(s);
}
|