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

Side by Side Diff: mojo/services/media/common/cpp/fifo_allocator.h

Issue 1460693004: Add helper classes to for managing shared buffers. (Closed) Base URL: https://github.com/domokit/mojo.git@master
Patch Set: sync Created 4 years, 11 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 2015 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 #ifndef MOJO_SERVICES_MEDIA_COMMON_CPP_FIFO_ALLOCATOR_H_
6 #define MOJO_SERVICES_MEDIA_COMMON_CPP_FIFO_ALLOCATOR_H_
7
8 #include <cstdint>
9 #include <limits>
10
11 namespace mojo {
12 namespace media {
13
14 // FifoAllocator implements heap semantics on a single contiguous buffer using
15 // a strategy that is especially suited to streaming. Allocations can vary in
16 // size, but the expectation is that regions will be released in roughly the
17 // order they were allocated (hence 'Fifo'). It's important that FifoAllocator
18 // be used in this way. FifoAllocator can deal with regions that don't get
19 // released in the order they were allocated, but they can potentially fragment
20 // the buffer and impact performance.
21 //
22 // FifoAllocator doesn't actually deal with any particular region of memory. It
23 // simply does the bookkeeping regarding how a buffer of a given size is
24 // allocated into regions.
25 //
26 // DESIGN:
27 //
28 // FifoAllocator maintains an ordered list of regions that partition the buffer.
29 // Some regions are allocated and some are free. Free regions are always
30 // coalesced, so there are no two adjacent free regions. Allocated regions are
31 // not coalesced. There is always at least one free region.
32 //
33 // One free region is distinguished as the 'active' region. New allocations are
34 // taken from the front of the active region. If the active region is too small
35 // to accommodate a requested allocation, FifoAllocator walks the list looking
36 // for an unallocated region that's large enough. The old active region becomes
37 // an unused scrap that is recovered when the active region catches up to it
38 // again. In some cases, the active region has a length of zero.
39 //
40 // The allocation strategy that emerges from all this is well-suited to many
41 // streaming scenarios in which packets vary in size. If packets are of
42 // consistent size, this strategy will still work, but is overkill given that
43 // a fixed set of regions can be preallocated from the buffer.
44 //
45 // An internal region structure is employed to represent the list of regions.
46 // FifoAllocator keeps unused region structures in a lookaside and never deletes
47 // them until the FifoAllocator is deleted. This could cause a large number of
48 // region structures to sit unused if the number of regions ever gets large.
49 // This is generally not an issue for the streaming scenarios for which the
50 // class is intended.
51 //
52 // Deallocations (releases) employ a sequential search for a matching
53 // region. The search is done starting immediately after the active region, so
54 // it typically finds the desired region immediately. If the number of regions
55 // is very large and deallocation is frequently done out of order, the
56 // sequential searches may be a performance issue.
57 class FifoAllocator {
58 public:
59 // Returned by AllocatedRegion when the requested allocation cannot be
60 // performed.
61 static const uint64_t kNullOffset = std::numeric_limits<uint64_t>::max();
62
63 FifoAllocator(uint64_t size);
64
65 ~FifoAllocator();
66
67 // Returns the size of the entire buffer as determined by the call to the
68 // constructor or the most recent call to Reset.
69 uint64_t size() const {
70 return size_;
71 }
72
73 // Resets the buffer manager to its initial state (no regions allocated)
74 // with a new buffer size. Also deletes all the regions in the lookaside.
75 void Reset(uint64_t size);
76
77 // Allocates a region and returns its offset or kNullOffset if the allocation
78 // could not be performed.
79 uint64_t AllocateRegion(uint64_t size);
80
81 // Releases a previously-allocated region.
82 void ReleaseRegion(uint64_t size, uint64_t offset);
83
84 private:
85 // List element to track allocated and free regions.
86 struct Region {
87 bool allocated;
88 uint64_t size;
89 uint64_t offset;
90
91 // Intrusive list pointers.
92 Region* prev;
93 Region* next;
94 };
95
96 // Releases the specified region if it's found between begin (inclusive) and
97 // end (exclusive).
98 bool Release(uint64_t size, uint64_t offset, Region* begin, Region* end);
99
100 // Advances the active region to one that's at least the specified size.
101 // Returns false if none could be found.
102 bool AdvanceActive(uint64_t size);
103
104 // Does the above for the interval between begin (inclusive) and end
105 // (exclusive).
106 bool AdvanceActive(uint64_t size, Region* begin, Region* end);
107
108 // Inserts a zero-sized region after active_ and makes that the active region.
109 void MakeActivePlaceholder();
110
111 // Deletes a list of regions by following their next pointers.
112 void DeleteFrontToBack(Region* region);
113
114 // Removes a region from the list.
115 void remove(Region* region);
116
117 // Inserts a region into the list before the specified region.
118 void insert_before(Region* region, Region* before_this);
119
120 // gets a free region structure, checking the lookaside first.
121 Region* get_free(bool allocated, uint64_t size, uint64_t offset);
122
123 // Saves a unused region structure to the lookaside.
124 void put_free(Region* region) {
125 region->next = free_;
126 free_ = region;
127 }
128
129 // Total size of the buffer to be managed. The sum of the sizes of all the
130 // regions in the list should equal size_.
131 uint64_t size_;
132
133 // Doubly-linked intrusive list of current regions in offset order.
134 Region* front_;
135 Region* back_;
136
137 // Lookaside for free region objects.
138 Region* free_;
139
140 // Unallocated region from which allocations are currently being made.
141 Region* active_;
142 };
143
144 } // namespace media
145 } // namespace mojo
146
147 #endif // MOJO_SERVICES_MEDIA_COMMON_CPP_FIFO_ALLOCATOR_H_
OLDNEW
« no previous file with comments | « mojo/services/media/common/cpp/BUILD.gn ('k') | mojo/services/media/common/cpp/fifo_allocator.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698