Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(240)

Side by Side Diff: services/blamer/shared_memory_heap.h

Issue 2885363004: [Hacky prototype] Create a shared-memory high-performance reporting service.
Patch Set: Created 3 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2017 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 // Defines a shared memory heap. One of these is created by each process
6 // using the blame service. This heap takes care of registering all of its slabs
7 // with the central blamer service, allowing it to iterate over all blame
8 // information across all processes.
9
10 #ifndef SERVICES_BLAMER_SHARED_MEMORY_HEAP_H_
11 #define SERVICES_BLAMER_SHARED_MEMORY_HEAP_H_
12
13 #include "base/metrics/persistent_memory_allocator.h"
14 #include "mojo/public/cpp/system/buffer.h"
15 #include "services/blamer/heap_object_types.h"
16 #include "services/blamer/public/interfaces/shared_memory_heap_registry.mojom.h"
17
18 namespace blamer {
19
20 // This class is thread safe. Most of the operations will actually be performed
21 // without using any locks, however occasionally a lock will need to be
22 // acquired in support of some operations.
23 class SharedMemoryHeap {
24 public:
25 static constexpr size_t kSlabSizeBits = 22;
26 static constexpr size_t kSlabSize = 1 << kSlabSizeBits;
27
28 // Represents a pointer in a process-portable way. This is what would be sent
29 // over IPC to communicate pointers between processes. Knowing the ID of the
30 // process owning the memory and the |raw_value| of the PortablePointer is
31 // sufficient to extract an actual pointer to the object in the process
32 // hosting the service.
33 struct PortablePointer {
34 union {
35 uint32_t raw_value;
36 struct {
37 unsigned int slab_id : 32 - kSlabSizeBits;
38 unsigned int slab_offset : kSlabSizeBits;
39 };
40 };
41 };
42 static_assert(sizeof(PortablePointer) == 4,
43 "unexpected PortablePointer size");
44
45 // Encapsulates pointers as they are doled out by this shared memory
46 // allocator. Dereferencing has a non-trivial cost so the result should
47 // ideally be cached by clients that need to do this often.
48 template<typename ObjectType>
49 struct TypedLocalPointer {
50 TypedLocalPointer(void* slab, PortablePointer pointer)
51 : slab(slab), pointer(pointer) {
52 }
53
54 ObjectType* Get() const {
55 auto* allocator = reinterpret_cast<base::PersistentMemoryAllocator*>(
56 slab);
57 base::PersistentMemoryAllocator::Reference ref = pointer.slab_offset;
58 return allocator->GetAsObject<ObjectType>(ref);
59 }
60 ObjectType* operator->() const { return Get(); }
61 ObjectType& operator*() const { return *Get(); }
62
63 void* slab;
64 PortablePointer pointer;
65 };
66
67 SharedMemoryHeap(mojom::SharedMemoryHeapRegistryPtr heap_registry);
68 ~SharedMemoryHeap();
69
70 // Allocates an object on the shared memory heap. Uses the actual object size.
71 template<typename ObjectType>
72 TypedLocalPointer<ObjectType> Allocate() {
73 return MakePointer<ObjectType>(Allocate(
74 ObjectType::kPersistentTypeId, sizeof(ObjectType)));
75 }
76
77 // Allocates an object on the shared memory heap. Uses the request object
78 // size.
79 template<typename ObjectType>
80 TypedLocalPointer<ObjectType> Allocate(size_t object_size) {
81 return MakePointer<ObjectType>(Allocate(
82 ObjectType::kPersistentTypeId, object_size));
83 }
84
85 // Frees an object. Once freed the object will no longer be visible to
86 // remote processes.
87 template<typename ObjectType>
88 void Free(const TypedLocalPointer<ObjectType>& pointer) {
89 Free(ObjectType::kPersistentTypeId, MakePointer(pointer));
90 }
91
92 private:
93 struct LocalPointer {
94 void* slab;
95 PortablePointer pointer;
96 };
97
98 struct Slab {
99 Slab();
100 Slab(Slab&& other);
101 ~Slab();
102
103 mojo::ScopedSharedBufferHandle buffer;
104 mojo::ScopedSharedBufferMapping mapping;
105 std::unique_ptr<base::PersistentMemoryAllocator> allocator;
106
107 private:
108 DISALLOW_COPY_AND_ASSIGN(Slab);
109 };
110
111 // Returns the current slab, creating one if none exists.
112 base::PersistentMemoryAllocator* GetCurrentSlab();
113
114 // Creates a new slab, and updates |current_slab_|. Returns a pointer to the
115 // newly created slab.
116 base::PersistentMemoryAllocator* CreateNewSlab(
117 base::PersistentMemoryAllocator* current_slab);
118
119 // Creates a TypedLocalPointer from an untyped LocalPointer.
120 template<typename ObjectType>
121 TypedLocalPointer<ObjectType> MakePointer(const LocalPointer& pointer) {
122 return TypedLocalPointer<ObjectType>(pointer.slab, pointer.pointer);
123 }
124
125 // Creates an untyped LocalPointer from a TypedLocalPointer.
126 template<typename ObjectType>
127 LocalPointer MakePointer(const TypedLocalPointer<ObjectType>& pointer) {
128 LocalPointer lp = {};
129 lp.slab = pointer.slab;
130 lp.slab = pointer.pointer = pointer.pointer;
131 return lp;
132 }
133
134 // Allocates an object from the current slab. Creates a new slab if the
135 // current slab fails to perform the allocation.
136 LocalPointer Allocate(HeapObjectType object_type, size_t object_size);
137
138 // Frees the provided object.
139 void Free(HeapObjectType object_type, const LocalPointer& pointer);
140
141 // Pointer to the heap registry to be notified of new slabs.
142 mojom::SharedMemoryHeapRegistryPtr heap_registry_;
143
144 // The current persistent memory allocator. This is updated in a lock-free
145 // manner. The common use case is to grab the current allocator and make an
146 // allocation, which is very fast.
147 std::atomic<base::PersistentMemoryAllocator*> current_slab_;
148
149 // |current_slab_| is used as a lock for modifying this safely.
150 std::vector<Slab> slabs_;
151 };
152
153 } // namespace blamer
154
155 #endif // SERVICES_BLAMER_SHARED_MEMORY_HEAP_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698