Skip to content

Commit

Permalink
Use a homemade implementation of linked-list
Browse files Browse the repository at this point in the history
  • Loading branch information
gleocadie committed Mar 7, 2024
1 parent 2842207 commit e9d9646
Show file tree
Hide file tree
Showing 9 changed files with 490 additions and 25 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ class CollectorBase

void Add(TRawSample&& sample) override
{
_collectedSamples.Add(std::forward<TRawSample>(sample));
_collectedSamples.Add(std::move(sample));
}

void TransformRawSample(const TRawSample& rawSample, std::shared_ptr<Sample>& sample)
Expand Down Expand Up @@ -150,9 +150,8 @@ class CollectorBase
{
public:
SamplesEnumeratorImpl(RawSamples<TRawSample> rawSamples, CollectorBase<TRawSample>* collector) :
_rawSamples{std::move(rawSamples)}, _collector{collector}
_rawSamples{std::move(rawSamples)}, _collector{collector}, _currentRawSample{_rawSamples.begin()}
{
_currentRawSample = _rawSamples.cbegin();
}

// Inherited via SamplesEnumerator
Expand All @@ -163,7 +162,7 @@ class CollectorBase

bool MoveNext(std::shared_ptr<Sample>& sample) override
{
if (_currentRawSample == _rawSamples.cend())
if (_currentRawSample == _rawSamples.end())
return false;

_collector->TransformRawSample(*_currentRawSample, sample);
Expand All @@ -175,7 +174,7 @@ class CollectorBase
private:
RawSamples<TRawSample> _rawSamples;
CollectorBase<TRawSample>* _collector;
typename RawSamples<TRawSample>::const_iterator _currentRawSample;
typename RawSamples<TRawSample>::iterator _currentRawSample;
};

private:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,7 @@
<ClInclude Include="ExporterBuilder.h" />
<ClInclude Include="FileHelper.h" />
<ClInclude Include="FrameworkThreadInfo.h" />
<ClInclude Include="LinkedList.hpp" />
<ClInclude Include="RawSamples.hpp" />
<ClInclude Include="SamplesEnumerator.h" />
<ClInclude Include="Success.h" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -431,9 +431,9 @@
<ClInclude Include="FrameworkThreadInfo.h">
<Filter>Threads</Filter>
</ClInclude>
<ClInclude Include="SampleEnumerator.h">
<Filter>Utils</Filter>
</ClInclude>
<ClInclude Include="RawSamples.hpp" />
<ClInclude Include="SamplesEnumerator.h" />
<ClInclude Include="LinkedList.hpp" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="OpSysTools.cpp">
Expand Down Expand Up @@ -653,4 +653,4 @@
<ItemGroup>
<None Include="packages.config" />
</ItemGroup>
</Project>
</Project>
209 changes: 209 additions & 0 deletions profiler/src/ProfilerEngine/Datadog.Profiler.Native/LinkedList.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,209 @@
// Unless explicitly stated otherwise all files in this repository are licensed under the Apache 2 License.
// This product includes software developed at Datadog (https://www.datadoghq.com/). Copyright 2022 Datadog, Inc.

#pragma once

#ifdef __has_include // Check if __has_include is present
#if __has_include(<memory_resource>) // Check for a standard library
#include <memory_resource>
namespace pmr {
using namespace std::pmr;
}
#elif __has_include(<experimental/memory_resource>) // Check for an experimental version
#include <experimental/memory_resource>
namespace pmr {
using namespace std::experimental::pmr;
}
#else // Not found at all
#error "Missing <memory_resource>"
#endif
#endif

#include <cassert>
#include <cstdlib>
#include <memory>
#include <utility>
#include <stdexcept>


template <class T>
class LinkedList
{
private:
struct Node;
using node_type = Node;

public:
LinkedList(pmr::memory_resource* allocator = pmr::get_default_resource()) noexcept :
_head{nullptr}, _tail{&_head}, _nbElements{0}, _allocator{allocator}
{
}

~LinkedList()
{
auto* current = std::exchange(_head, nullptr);

while (current != nullptr)
{
auto* next = current->Next;
std::destroy_at(current);
_allocator->deallocate(current, sizeof(Node));
current = next;
}
}

LinkedList(LinkedList const&) = delete;
LinkedList& operator=(LinkedList const&) = delete;

LinkedList(LinkedList&& other) noexcept :
LinkedList() // should we use the default allocator ? or allow an allocator to the move ctor ?
{
*this = std::move(other);
}

LinkedList& operator=(LinkedList&& other) noexcept
{
if (this == &other)
{
return *this;
}

_head = std::exchange(other._head, nullptr);
_tail = _head == nullptr ? &_head : std::exchange(other._tail, nullptr);

#ifdef DD_TEST
if (_head == nullptr && _tail != &_head)
{
throw std::exception("_tail must have the address of _head");
}
#endif
std::swap(_nbElements, other._nbElements);
std::swap(_allocator, other._allocator);

return *this;
}

void swap(LinkedList& other)
{
if (this == &other)
{
return;
}

_head = std::exchange(other._head, _head);
_tail = _head == nullptr ? &_head : other._tail;
other._tail = other._head == nullptr ? &other._head : _tail;

#ifdef DD_TEST
if (_head == nullptr && _tail != &_head)
{
throw std::exception("_tail must have the address of _head");
}

if (other._head == nullptr && other._tail != &other._head)
{
throw std::exception("other._tail must have the address of other._head");
}
#endif

std::swap(_nbElements, other._nbElements);
std::swap(_allocator, other._allocator);
}

bool append(T&& v)
{
auto ptr = _allocator->allocate(sizeof(Node));

if (ptr == nullptr)
{
return false;
}

*_tail = new (ptr) Node(std::move(v), nullptr);
_tail = &((*_tail)->Next);

_nbElements++;

return true;
}

std::size_t size() const
{
return _nbElements;
}

class iterator;

iterator begin()
{
return iterator(_head);
}

iterator end()
{
return iterator(nullptr);
}

class iterator
{
public:
iterator(Node* node) :
_Ptr{node}
{
}

T& operator*() const
{
return _Ptr->Value;
}

iterator operator++(int)
{
auto tmp = *this;
++*this;
return tmp;
}

iterator& operator++()
{
_Ptr = _Ptr->Next;
return *this;
}

bool operator==(iterator const& other) const
{
return _Ptr == other._Ptr;
}

bool operator!=(iterator const& other) const
{
return !(*this == other);
}

private:
Node* _Ptr;
};

private:
struct Node
{
public:
T Value;
Node* Next;

template <class Ty>
Node(Ty&& v, Node* next) :
Value(std::forward<Ty>(v)), Next{next}
{
}

Node(Node const&) = delete;
Node& operator=(Node const&) = delete;
};

Node* _head;
Node** _tail;
std::size_t _nbElements;

pmr::memory_resource* _allocator;
};
Original file line number Diff line number Diff line change
Expand Up @@ -414,4 +414,4 @@ inline void ManagedThreadInfo::SetSharedMemory(volatile int* memoryArea)
{
_sharedMemoryArea = memoryArea;
}
#endif
#endif
21 changes: 11 additions & 10 deletions profiler/src/ProfilerEngine/Datadog.Profiler.Native/RawSamples.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,14 @@
// This product includes software developed at Datadog (https://www.datadoghq.com/). Copyright 2022 Datadog, Inc.

#pragma once
#include <list>

#include "LinkedList.hpp"

template <class TRawSample>
class RawSamples
{
public:
using const_iterator = typename std::list<TRawSample>::const_iterator;
using iterator = typename LinkedList<TRawSample>::iterator;

RawSamples() = default;

Expand All @@ -31,7 +32,7 @@ class RawSamples
{
std::lock_guard<std::mutex> lock(_lock);

std::list<TRawSample> result;
LinkedList<TRawSample> result;
_samples.swap(result);

return RawSamples(std::move(result));
Expand All @@ -40,17 +41,17 @@ class RawSamples
void Add(TRawSample&& sample)
{
std::lock_guard<std::mutex> lock(_lock);
_samples.push_back(std::forward<TRawSample>(sample));
_samples.append(std::forward<TRawSample>(sample));
}

auto cbegin() const
auto begin()
{
return _samples.cbegin();
return _samples.begin();
}

auto cend() const
auto end()
{
return _samples.cend();
return _samples.end();
}

std::size_t size() const
Expand All @@ -59,11 +60,11 @@ class RawSamples
}

private:
RawSamples(std::list<TRawSample> samples) :
RawSamples(LinkedList<TRawSample> samples) :
_samples{std::move(samples)}
{
}

std::mutex _lock;
std::list<TRawSample> _samples;
LinkedList<TRawSample> _samples;
};
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@
<ClCompile Include="FakeSamples.cpp" />
<ClCompile Include="FrameStoreHelper.cpp" />
<ClCompile Include="IMetricsSenderFactoryTest.cpp" />
<ClCompile Include="LinkedListTest.cpp" />
<ClCompile Include="ProfileExporterTest.cpp" />
<ClCompile Include="LinuxStackFramesCollectorTest.cpp" />
<ClCompile Include="LogTest.cpp" />
Expand Down Expand Up @@ -113,7 +114,7 @@
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>_SILENCE_STDEXT_ARR_ITERS_DEPRECATION_WARNING;WIN32;_DEBUG;_CONSOLE;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions>_SILENCE_STDEXT_ARR_ITERS_DEPRECATION_WARNING;DD_TEST;WIN32;_DEBUG;_CONSOLE;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<WarningLevel>Level3</WarningLevel>
Expand All @@ -136,7 +137,7 @@
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>_SILENCE_STDEXT_ARR_ITERS_DEPRECATION_WARNING;X64;_DEBUG;_CONSOLE;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions>_SILENCE_STDEXT_ARR_ITERS_DEPRECATION_WARNING;DD_TEST;X64;_DEBUG;_CONSOLE;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<WarningLevel>Level3</WarningLevel>
Expand All @@ -157,7 +158,7 @@
<ClCompile>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
<PreprocessorDefinitions>_SILENCE_STDEXT_ARR_ITERS_DEPRECATION_WARNING;WIN32;NDEBUG;_CONSOLE;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions>_SILENCE_STDEXT_ARR_ITERS_DEPRECATION_WARNING;DD_TEST;WIN32;NDEBUG;_CONSOLE;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
Expand All @@ -180,7 +181,7 @@
<ClCompile>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
<PreprocessorDefinitions>_SILENCE_STDEXT_ARR_ITERS_DEPRECATION_WARNING;X64;NDEBUG;_CONSOLE;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions>_SILENCE_STDEXT_ARR_ITERS_DEPRECATION_WARNING;DD_TEST;X64;NDEBUG;_CONSOLE;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
Expand Down
Loading

0 comments on commit e9d9646

Please sign in to comment.