Skip to content

Commit 39a10e0

Browse files
Merge pull request #1 from robertosfield/allocator
Allocator
2 parents a408ca1 + cc8beac commit 39a10e0

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

57 files changed

+416
-161
lines changed

include/vsg/core/Allocator.h

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
#pragma once
2+
3+
/* <editor-fold desc="MIT License">
4+
5+
Copyright(c) 2018 Robert Osfield
6+
7+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
8+
9+
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
10+
11+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
12+
13+
</editor-fold> */
14+
15+
#include <vsg/core/Inherit.h>
16+
#include <vsg/core/ref_ptr.h>
17+
#include <vsg/utils/stream.h>
18+
19+
namespace vsg
20+
{
21+
22+
class Allocator : public Inherit<Object, Allocator>
23+
{
24+
public:
25+
virtual void* allocate(std::size_t n, const void* hint );
26+
27+
virtual void* allocate(std::size_t size);
28+
29+
virtual void deallocate(const void* ptr, std::size_t size=0);
30+
31+
Auxiliary* getOrCreateSharedAuxiliary();
32+
33+
void detachSharedAuxiliary(Auxiliary* auxiliary);
34+
35+
template<typename T, typename... Args>
36+
ref_ptr<T> create(Args&&... args)
37+
{
38+
// need to think about alignment...
39+
std::size_t size = sizeof(T);
40+
void* ptr = allocate(size);
41+
T* object = new (ptr) T(std::forward<Args>(args)...);
42+
object->setAuxiliary(getOrCreateSharedAuxiliary());
43+
44+
std::size_t new_size = object->getSizeOf();
45+
if (new_size != size)
46+
{
47+
throw make_string("Warning: Allocator::create(",typeid(T).name(),") mismatch sizeof() = ",size,", ",new_size);
48+
}
49+
return object;
50+
}
51+
52+
protected:
53+
virtual ~Allocator();
54+
55+
Auxiliary* _sharedAuxiliary = nullptr;
56+
std::size_t _bytesAllocated = 0;
57+
std::size_t _countAllocated = 0;
58+
std::size_t _bytesDeallocated = 0;
59+
std::size_t _countDeallocated = 0;
60+
};
61+
62+
}

include/vsg/core/Array.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@ namespace vsg
3535
Array(std::initializer_list<value_type> l) : _size(l.size()), _data(new value_type[l.size()]) { value_type* ptr = _data; for (value_type const & v : l) { (*ptr++) = v; } }
3636
Array(const Array& rhs) : _data(rhs.data) {}
3737

38+
std::size_t getSizeOf() const noexcept override { return sizeof(Data); }
39+
3840
// implementation provided by Visitor.h
3941
void accept(Visitor& visitor) override ;
4042

include/vsg/core/Auxiliary.h

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,10 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
1212
1313
</editor-fold> */
1414

15-
#include <vsg/core/Object.h>
15+
#include <vsg/core/Allocator.h>
1616
#include <vsg/core/ref_ptr.h>
1717

1818
#include <map>
19-
#include <algorithm>
2019

2120
namespace vsg
2221
{
@@ -25,11 +24,11 @@ namespace vsg
2524
class VSG_EXPORT Auxiliary
2625
{
2726
public:
28-
Auxiliary();
29-
3027
Object* getConnectedObject() { return _connectedObject; }
3128
const Object* getConnectedObject() const { return _connectedObject; }
3229

30+
virtual std::size_t getSizeOf() const { return sizeof(Auxiliary); }
31+
3332
void ref() const;
3433
void unref() const;
3534
void unref_nodelete() const;
@@ -43,23 +42,29 @@ namespace vsg
4342
ObjectMap& getObjectMap() { return _objectMap; }
4443
const ObjectMap& getObjectMap() const { return _objectMap; }
4544

45+
void setAllocator(Allocator* allocator) { _allocator = allocator; }
46+
Allocator* getAllocator() { return _allocator; }
47+
4648
protected:
4749

48-
virtual ~Auxiliary();
50+
Auxiliary(Allocator* allocator);
51+
Auxiliary(Object* object, Allocator* allocator=nullptr);
4952

50-
void setConnectedObject(Object* object);
53+
virtual ~Auxiliary();
5154

5255
/// reset the ConnectedObject pointer to 0 unless the ConnectedObject referenceCount goes back above 0,
5356
/// return true if ConnectedObject should still be deleted, or false if the object should be kept.
5457
bool signalConnectedObjectToBeDeleted();
5558

56-
friend class Object;
57-
58-
mutable std::atomic_uint _referenceCount;
59+
void resetConnectedObject();
5960

60-
std::atomic<Object*> _connectedObject;
61+
friend class Object;
62+
friend class Allocator;
6163

62-
ObjectMap _objectMap;
64+
mutable std::atomic_uint _referenceCount;
65+
std::atomic<Object*> _connectedObject;
66+
ref_ptr<Allocator> _allocator;
67+
ObjectMap _objectMap;
6368

6469
};
6570

include/vsg/core/Data.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ namespace vsg
2222

2323
Data() {};
2424

25+
std::size_t getSizeOf() const noexcept override { return sizeof(Data); }
26+
2527
virtual std::size_t valueSize() const = 0;
2628
virtual std::size_t valueCount() const = 0;
2729

include/vsg/core/Inherit.h

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
#pragma once
2+
3+
/* <editor-fold desc="MIT License">
4+
5+
Copyright(c) 2018 Robert Osfield
6+
7+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
8+
9+
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
10+
11+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
12+
13+
</editor-fold> */
14+
15+
#include <vsg/core/Visitor.h>
16+
#include <vsg/traversals/DispatchTraversal.h>
17+
18+
namespace vsg
19+
{
20+
21+
// Use the Curiously Reacurring Template Pattern
22+
// to provide the classes versions of accept(..) and getSizeOf()
23+
template<class ParentClass, class Subclass>
24+
class Inherit : public ParentClass
25+
{
26+
public:
27+
template<typename... Args>
28+
Inherit(Args&&... args) : ParentClass(std::forward<Args>(args)...) {}
29+
30+
void accept(Visitor& visitor) override { visitor.apply(static_cast<Subclass&>(*this)); }
31+
void accept(DispatchTraversal& visitor) const override { visitor.apply(static_cast<const Subclass&>(*this)); }
32+
std::size_t getSizeOf() const noexcept override { return sizeof(Subclass); }
33+
};
34+
35+
}

include/vsg/core/Object.h

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ namespace vsg
2626
class Auxiliary;
2727
class Visitor;
2828
class DispatchTraversal;
29+
class Allocator;
2930

3031
class VSG_EXPORT Object
3132
{
@@ -35,6 +36,8 @@ namespace vsg
3536
Object(const Object&) = delete;
3637
Object& operator = (const Object&) = delete;
3738

39+
virtual std::size_t getSizeOf() const noexcept { return sizeof(Object); }
40+
3841
virtual void accept(Visitor& visitor);
3942
virtual void traverse(Visitor&) {}
4043

@@ -78,16 +81,23 @@ namespace vsg
7881
Object* getObject(const Key& key);
7982
const Object* getObject(const Key& key) const;
8083

81-
Auxiliary* getOrCreateAuxiliary();
84+
Auxiliary* getOrCreateUniqueAuxiliary();
8285
Auxiliary* getAuxiliary() { return _auxiliary; }
8386
const Auxiliary* getAuxiliary() const { return _auxiliary; }
8487

88+
Allocator* getAllocator() const;
89+
8590
protected:
8691
virtual ~Object();
8792

8893
private:
8994
virtual void _delete() const;
9095

96+
void setAuxiliary(Auxiliary* auxiliary);
97+
98+
friend class Allocator;
99+
friend class Auxiliary;
100+
91101
mutable std::atomic_uint _referenceCount;
92102

93103
Auxiliary* _auxiliary;

include/vsg/core/Value.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ namespace vsg
3131
Value(const value_type& in_value) : _value(in_value) {}
3232
Value(const Value& rhs) : _value(rhs._value) {}
3333

34+
std::size_t getSizeOf() const noexcept override { return sizeof(Value); }
35+
3436
// implementation provided by Visitor.h
3537
void accept(Visitor& visitor) override;
3638

include/vsg/core/observer_ptr.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ namespace vsg
3131

3232
template<class R>
3333
observer_ptr(R* ptr):
34-
_auxiliary(ptr ? ptr->getOrCreateAuxiliary() : nullptr)
34+
_auxiliary(ptr ? ptr->getOrCreateUniqueAuxiliary() : nullptr)
3535
{
3636
}
3737

@@ -43,7 +43,7 @@ namespace vsg
4343

4444
template<class R>
4545
observer_ptr(const ref_ptr<R>& ptr):
46-
_auxiliary(ptr.valid() ? ptr->getOrCreateAuxiliary() : nullptr)
46+
_auxiliary(ptr.valid() ? ptr->getOrCreateUniqueAuxiliary() : nullptr)
4747
{
4848
}
4949

@@ -54,7 +54,7 @@ namespace vsg
5454
template<class R>
5555
observer_ptr& operator = (R* ptr)
5656
{
57-
_auxiliary = ptr ? ptr->getOrCreateAuxiliary() : nullptr;
57+
_auxiliary = ptr ? ptr->getOrCreateUniqueAuxiliary() : nullptr;
5858
return *this;
5959
}
6060

@@ -74,7 +74,7 @@ namespace vsg
7474
template<class R>
7575
observer_ptr& operator = (const ref_ptr<R>& rhs)
7676
{
77-
_auxiliary = rhs.valid() ? rhs->getOrCreateAuxiliary() : nullptr;
77+
_auxiliary = rhs.valid() ? rhs->getOrCreateUniqueAuxiliary() : nullptr;
7878
return *this;
7979
}
8080

include/vsg/nodes/FixedGroup.h

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,17 +21,14 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
2121
namespace vsg
2222
{
2323
template<int NUM_CHILDREN>
24-
class FixedGroup : public vsg::Node
24+
class FixedGroup : public Inherit<Node, FixedGroup<NUM_CHILDREN>>
2525
{
2626
public:
2727
FixedGroup() {}
2828

2929
template<class N, class V> static void t_traverse(N& node, V& visitor) { for (auto& child : node._children) child->accept(visitor); }
3030

31-
void accept(Visitor& visitor) override { visitor.apply(*this); }
3231
void traverse(Visitor& visitor) override { t_traverse(*this, visitor); }
33-
34-
void accept(DispatchTraversal& visitor) const override { visitor.apply(*this); }
3532
void traverse(DispatchTraversal& visitor) const override { t_traverse(*this, visitor); }
3633

3734
void setChild(std::size_t pos, vsg::Node* node) { _children[pos] = node; }

include/vsg/nodes/Group.h

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,17 +21,14 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
2121

2222
namespace vsg
2323
{
24-
class VSG_EXPORT Group : public vsg::Node
24+
class VSG_EXPORT Group : public Inherit<Node, Group>
2525
{
2626
public:
2727
Group(size_t numChildren=0);
2828

2929
template<class N, class V> static void t_traverse(N& node, V& visitor) { for (auto& child : node._children) child->accept(visitor); }
3030

31-
void accept(Visitor& visitor) override { visitor.apply(*this); }
3231
void traverse(Visitor& visitor) override { t_traverse(*this, visitor); }
33-
34-
void accept(DispatchTraversal& visitor) const override { visitor.apply(*this); }
3532
void traverse(DispatchTraversal& visitor) const override { t_traverse(*this, visitor); }
3633

3734
std::size_t addChild(vsg::Node* child) { std::size_t pos = _children.size(); _children.push_back(child); return pos; }
@@ -55,4 +52,5 @@ namespace vsg
5552

5653
Children _children;
5754
};
55+
5856
}

0 commit comments

Comments
 (0)