Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add more ConsoleBench tests #17441

Merged
merged 1 commit into from
Jun 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 26 additions & 0 deletions src/tools/ConsoleBench/ConsoleBench.exe.manifest
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly
xmlns="urn:schemas-microsoft-com:asm.v1"
xmlns:asm3="urn:schemas-microsoft-com:asm.v3"
xmlns:cv1="urn:schemas-microsoft-com:compatibility.v1"
xmlns:ws="http://schemas.microsoft.com/SMI/2005/WindowsSettings"
xmlns:ws2="http://schemas.microsoft.com/SMI/2016/WindowsSettings"
xmlns:ws3="http://schemas.microsoft.com/SMI/2019/WindowsSettings"
manifestVersion="1.0">
<asm3:application>
<windowsSettings>
<ws2:longPathAware>true</ws2:longPathAware>
<ws3:activeCodePage>UTF-8</ws3:activeCodePage>
</windowsSettings>
</asm3:application>
<cv1:compatibility>
<application>
<supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}"/>
</application>
</cv1:compatibility>
<dependency>
<dependentAssembly>
<assemblyIdentity type="win32" name="Microsoft.Windows.Common-Controls" version="6.0.0.0" processorArchitecture="*" publicKeyToken="6595b64144ccf1df" language="*" />
</dependentAssembly>
</dependency>
</assembly>
3 changes: 3 additions & 0 deletions src/tools/ConsoleBench/ConsoleBench.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@
<ClInclude Include="pch.h" />
<ClInclude Include="utils.h" />
</ItemGroup>
<ItemGroup>
<Manifest Include="ConsoleBench.exe.manifest" />
</ItemGroup>
<ItemDefinitionGroup>
<ClCompile>
<ControlFlowGuard>false</ControlFlowGuard>
Expand Down
5 changes: 5 additions & 0 deletions src/tools/ConsoleBench/ConsoleBench.vcxproj.filters
Original file line number Diff line number Diff line change
Expand Up @@ -49,4 +49,9 @@
<Filter>Source Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<Manifest Include="ConsoleBench.exe.manifest">
<Filter>Source Files</Filter>
</Manifest>
</ItemGroup>
</Project>
20 changes: 16 additions & 4 deletions src/tools/ConsoleBench/arena.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ using namespace mem;

Arena::Arena(size_t bytes)
{
m_alloc = static_cast<uint8_t*>(THROW_IF_NULL_ALLOC(VirtualAlloc(nullptr, bytes, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE)));
m_alloc = static_cast<uint8_t*>(THROW_IF_NULL_ALLOC(VirtualAlloc(nullptr, bytes, MEM_RESERVE, PAGE_READWRITE)));
}

Arena::~Arena()
Expand Down Expand Up @@ -41,8 +41,18 @@ void* Arena::_push_raw(size_t bytes, size_t alignment)
{
const auto mask = alignment - 1;
const auto pos = (m_pos + mask) & ~mask;
const auto pos_new = pos + bytes;
const auto ptr = m_alloc + pos;
m_pos = pos + bytes;

if (pos_new > m_commit)
{
// Commit in 1MB chunks and pre-commit 1MiB in advance.
const auto commit_new = (pos_new + 0x1FFFFF) & ~0xFFFFF;
THROW_IF_NULL_ALLOC(VirtualAlloc(m_alloc + m_commit, commit_new - m_commit, MEM_COMMIT, PAGE_READWRITE));
m_commit = commit_new;
}

m_pos = pos_new;
return ptr;
}

Expand Down Expand Up @@ -76,8 +86,8 @@ ScopedArena::~ScopedArena()
static [[msvc::noinline]] std::array<Arena, 2> thread_arenas_init()
{
return {
Arena{ 64 * 1024 * 1024 },
Arena{ 64 * 1024 * 1024 },
Arena{ 1024 * 1024 * 1024 },
Arena{ 1024 * 1024 * 1024 },
};
}

Expand Down Expand Up @@ -166,7 +176,9 @@ std::wstring_view mem::format(Arena& arena, const wchar_t* fmt, va_list args)
return {};
}

// Make space for a terminating \0 character.
len++;

const auto buffer = arena.push_uninitialized<wchar_t>(len);

len = _vsnwprintf(buffer, len, fmt, args);
Expand Down
31 changes: 24 additions & 7 deletions src/tools/ConsoleBench/arena.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ namespace mem
void* _push_uninitialized(size_t bytes, size_t alignment = __STDCPP_DEFAULT_NEW_ALIGNMENT__);

uint8_t* m_alloc = nullptr;
size_t m_commit = 0;
size_t m_pos = 0;
};

Expand Down Expand Up @@ -96,16 +97,32 @@ namespace mem
}

template<typename T>
std::basic_string_view<T> repeat_string(Arena& arena, std::basic_string_view<T> in, size_t count)
auto repeat(Arena& arena, const T& in, size_t count) -> decltype(auto)
{
const auto len = count * in.size();
const auto buf = arena.push_uninitialized<T>(len);

for (size_t i = 0; i < count; ++i)
if constexpr (is_std_view<T>::value)
{
mem::copy(buf + i * in.size(), in.data(), in.size());
const auto data = in.data();
const auto size = in.size();
const auto len = count * size;
const auto buf = arena.push_uninitialized<typename T::value_type>(len);

for (size_t i = 0; i < count; ++i)
{
mem::copy(buf + i * size, data, size);
}

return T{ buf, len };
}
else
{
const auto buf = arena.push_uninitialized<T>(count);

for (size_t i = 0; i < count; ++i)
{
memcpy(buf + i, &in, sizeof(T));
}

return { buf, len };
return std::span{ buf, count };
}
}
}
36 changes: 34 additions & 2 deletions src/tools/ConsoleBench/conhost.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

#include <conmsgl1.h>
#include <winternl.h>
#include <wil/win32_helpers.h>

#include "arena.h"

Expand Down Expand Up @@ -46,12 +47,27 @@ static void conhostCopyToStringBuffer(USHORT& length, auto& buffer, const wchar_

ConhostHandle spawn_conhost(mem::Arena& arena, const wchar_t* path)
{
const auto pathLen = wcslen(path);
const auto isDLL = pathLen > 4 && wcscmp(&path[pathLen - 4], L".dll") == 0;

const auto scratch = mem::get_scratch_arena(arena);
const auto server = conhostCreateHandle(nullptr, L"\\Device\\ConDrv\\Server", true, false);
auto server = conhostCreateHandle(nullptr, L"\\Device\\ConDrv\\Server", true, false);
auto reference = conhostCreateHandle(server.get(), L"\\Reference", false, true);

{
const auto cmd = format(scratch.arena, LR"("%s" --server 0x%zx)", path, server.get());
const auto selfPath = scratch.arena.push_uninitialized<wchar_t>(64 * 1024);
GetModuleFileNameW(nullptr, selfPath, 64 * 1024);

std::wstring_view cmd;

if (isDLL)
{
cmd = format(scratch.arena, LR"("%s" host %zx "%s")", selfPath, server.get(), path);
}
else
{
cmd = format(scratch.arena, LR"("%s" --server 0x%zx)", path, server.get());
}

uint8_t attrListBuffer[64];

Expand Down Expand Up @@ -154,6 +170,22 @@ ConhostHandle spawn_conhost(mem::Arena& arena, const wchar_t* path)
};
}

// A continuation of spawn_conhost().
void check_spawn_conhost_dll(int argc, const wchar_t* argv[])
{
if (argc == 4 && wcscmp(argv[1], L"host") == 0)
{
const auto serverHandle = reinterpret_cast<HANDLE>(wcstoull(argv[2], nullptr, 16));
const auto path = argv[3];

using Entrypoint = NTSTATUS(NTAPI*)(HANDLE);
const auto h = THROW_LAST_ERROR_IF_NULL(LoadLibraryExW(path, nullptr, 0));
const auto f = THROW_LAST_ERROR_IF_NULL(reinterpret_cast<Entrypoint>(GetProcAddress(h, "ConsoleCreateIoThread")));
THROW_IF_NTSTATUS_FAILED(f(serverHandle));
ExitThread(S_OK);
}
}

HANDLE get_active_connection()
{
// (Not actually) FUN FACT! The handles don't mean anything and the cake is a lie!
Expand Down
1 change: 1 addition & 0 deletions src/tools/ConsoleBench/conhost.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,6 @@ struct ConhostHandle
};

ConhostHandle spawn_conhost(mem::Arena& arena, const wchar_t* path);
void check_spawn_conhost_dll(int argc, const wchar_t* argv[]);
HANDLE get_active_connection();
void set_active_connection(HANDLE connection);
Loading
Loading