blob: 2ea84527a2b76d8d21bf6d15781d445399cb792d [file] [log] [blame]
Iliyan Malchev202a77d2012-06-11 14:41:12 -07001/*
2 * Copyright (C) 2009 The Android Open Source Project
3 * Copyright (c) 2011 Code Aurora Forum. All rights reserved.
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18
19#ifndef GRALLOC_ALLOCATOR_H_
20#define GRALLOC_ALLOCATOR_H_
21
22#include <stdint.h>
23#include <sys/types.h>
24
25#include "gr.h"
26#include "pmemalloc.h"
27
28// ----------------------------------------------------------------------------
29
30/*
31 * A simple templatized doubly linked-list implementation
32 */
33template <typename NODE>
34class LinkedList
35{
36 NODE* mFirst;
37 NODE* mLast;
38
39public:
40 LinkedList() : mFirst(0), mLast(0) { }
41 bool isEmpty() const { return mFirst == 0; }
42 NODE const* head() const { return mFirst; }
43 NODE* head() { return mFirst; }
44 NODE const* tail() const { return mLast; }
45 NODE* tail() { return mLast; }
46
47 void insertAfter(NODE* node, NODE* newNode) {
48 newNode->prev = node;
49 newNode->next = node->next;
50 if (node->next == 0) mLast = newNode;
51 else node->next->prev = newNode;
52 node->next = newNode;
53 }
54
55 void insertBefore(NODE* node, NODE* newNode) {
56 newNode->prev = node->prev;
57 newNode->next = node;
58 if (node->prev == 0) mFirst = newNode;
59 else node->prev->next = newNode;
60 node->prev = newNode;
61 }
62
63 void insertHead(NODE* newNode) {
64 if (mFirst == 0) {
65 mFirst = mLast = newNode;
66 newNode->prev = newNode->next = 0;
67 } else {
68 newNode->prev = 0;
69 newNode->next = mFirst;
70 mFirst->prev = newNode;
71 mFirst = newNode;
72 }
73 }
74
75 void insertTail(NODE* newNode) {
76 if (mLast == 0) {
77 insertHead(newNode);
78 } else {
79 newNode->prev = mLast;
80 newNode->next = 0;
81 mLast->next = newNode;
82 mLast = newNode;
83 }
84 }
85
86 NODE* remove(NODE* node) {
87 if (node->prev == 0) mFirst = node->next;
88 else node->prev->next = node->next;
89 if (node->next == 0) mLast = node->prev;
90 else node->next->prev = node->prev;
91 return node;
92 }
93};
94
95class SimpleBestFitAllocator : public gralloc::PmemUserspaceAlloc::Allocator
96{
97public:
98
99 SimpleBestFitAllocator();
100 SimpleBestFitAllocator(size_t size);
101 virtual ~SimpleBestFitAllocator();
102
103 virtual ssize_t setSize(size_t size);
104
105 virtual ssize_t allocate(size_t size, uint32_t flags = 0);
106 virtual ssize_t deallocate(size_t offset);
107 virtual size_t size() const;
108
109private:
110 struct chunk_t {
111 chunk_t(size_t start, size_t size)
112 : start(start), size(size), free(1), prev(0), next(0) {
113 }
114 size_t start;
115 size_t size : 28;
116 int free : 4;
117 mutable chunk_t* prev;
118 mutable chunk_t* next;
119 };
120
121 ssize_t alloc(size_t size, uint32_t flags);
122 chunk_t* dealloc(size_t start);
123
124 static const int kMemoryAlign;
125 mutable Locker mLock;
126 LinkedList<chunk_t> mList;
127 size_t mHeapSize;
128};
129#endif /* GRALLOC_ALLOCATOR_H_ */