• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2009 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 
18 #ifndef GRALLOC_ALLOCATOR_H_
19 #define GRALLOC_ALLOCATOR_H_
20 
21 #include <stdint.h>
22 #include <sys/types.h>
23 
24 #include "gr.h"
25 #include "pmemalloc.h"
26 
27 // ----------------------------------------------------------------------------
28 
29 /*
30  * A simple templatized doubly linked-list implementation
31  */
32 
33 template <typename NODE>
34 class LinkedList
35 {
36     NODE*  mFirst;
37     NODE*  mLast;
38 
39 public:
LinkedList()40                 LinkedList() : mFirst(0), mLast(0) { }
isEmpty()41     bool        isEmpty() const { return mFirst == 0; }
head()42     NODE const* head() const { return mFirst; }
head()43     NODE*       head() { return mFirst; }
tail()44     NODE const* tail() const { return mLast; }
tail()45     NODE*       tail() { return mLast; }
46 
insertAfter(NODE * node,NODE * newNode)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 
insertBefore(NODE * node,NODE * newNode)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 
insertHead(NODE * newNode)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 
insertTail(NODE * newNode)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 
remove(NODE * node)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 
95 class SimpleBestFitAllocator : public PmemUserspaceAllocator::Deps::Allocator
96 {
97 public:
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 
109 private:
110     struct chunk_t {
chunk_tchunk_t111         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 
130 #endif /* GRALLOC_ALLOCATOR_H_ */
131