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

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

Powered by Google App Engine
This is Rietveld 408576698