OLD | NEW |
1 /* | 1 /* |
2 * Copyright (c) 2011 The Native Client Authors. All rights reserved. | 2 * Copyright (c) 2011 The Native Client Authors. All rights reserved. |
3 * Use of this source code is governed by a BSD-style license that can be | 3 * Use of this source code is governed by a BSD-style license that can be |
4 * found in the LICENSE file. | 4 * found in the LICENSE file. |
5 */ | 5 */ |
6 #ifndef PACKAGES_LIBRARIES_NACL_MOUNTS_UTIL_SLOTALLOCATOR_H_ | 6 #ifndef PACKAGES_LIBRARIES_NACL_MOUNTS_UTIL_SLOTALLOCATOR_H_ |
7 #define PACKAGES_LIBRARIES_NACL_MOUNTS_UTIL_SLOTALLOCATOR_H_ | 7 #define PACKAGES_LIBRARIES_NACL_MOUNTS_UTIL_SLOTALLOCATOR_H_ |
8 | 8 |
9 #include <stdint.h> | 9 #include <stdint.h> |
10 #include <algorithm> | 10 #include <algorithm> |
| 11 #include <set> |
11 #include <vector> | 12 #include <vector> |
12 #include "macros.h" | 13 #include "macros.h" |
13 | 14 |
14 // The slot allocator class is a memory management tool. | 15 // The slot allocator class is a memory management tool. |
15 // This class allocates memory for the templated class | 16 // This class allocates memory for the templated class |
16 // and uses a slot index to direct the user to that | 17 // and uses a slot index to direct the user to that |
17 // memory. | 18 // memory. |
18 template <class T> | 19 template <class T> |
19 class SlotAllocator { | 20 class SlotAllocator { |
20 public: | 21 public: |
21 SlotAllocator() {} | 22 SlotAllocator() {} |
22 // The destructor loops through each slot. If the slot | 23 // The destructor loops through each slot. If the slot |
23 // contains an object, that object is deleted (freeing | 24 // contains an object, that object is deleted (freeing |
24 // the memory). | 25 // the memory). |
25 virtual ~SlotAllocator(); | 26 virtual ~SlotAllocator(); |
26 | 27 |
27 // Alloc() allocates memory for an object of type T | 28 // Alloc() allocates memory for an object of type T |
28 // and returns the slot index in this SlotAllocator | 29 // and returns the slot index in this SlotAllocator |
29 // that corresponds to that memory. | 30 // that corresponds to that memory. |
30 int Alloc(); | 31 int Alloc(); |
31 | 32 |
| 33 // AllocAt() allocates memory for an object of type T |
| 34 // at specified index (this is required for dup2 syscall) |
| 35 // and returns the slot index in this SlotAllocator |
| 36 // that corresponds to that memory. |
| 37 // Returns -1 on error. |
| 38 int AllocAt(int fd); |
| 39 |
32 // Free() frees the memory in the given slot. If | 40 // Free() frees the memory in the given slot. If |
33 // no memory has been allocated to the slot, this | 41 // no memory has been allocated to the slot, this |
34 // method does nothing. | 42 // method does nothing. |
35 void Free(int slot); | 43 void Free(int slot); |
36 | 44 |
37 // At() returns the pointer to the allocated memory | 45 // At() returns the pointer to the allocated memory |
38 // at the given slot. At() returns NULL if: | 46 // at the given slot. At() returns NULL if: |
39 // (1) the slot is out of range | 47 // (1) the slot is out of range |
40 // (2) no memory has been allocated at slot | 48 // (2) no memory has been allocated at slot |
41 T *At(int slot); | 49 T *At(int slot); |
42 | 50 |
43 private: | 51 private: |
44 std::vector<T*> slots_; | 52 std::vector<T*> slots_; |
45 std::vector<int> heap_; | 53 std::set<int> free_fds_; |
46 | 54 |
47 static bool comp(int i, int j) { return i > j; } | 55 static bool comp(int i, int j) { return i > j; } |
48 | 56 |
49 DISALLOW_COPY_AND_ASSIGN(SlotAllocator); | 57 DISALLOW_COPY_AND_ASSIGN(SlotAllocator); |
50 }; | 58 }; |
51 | 59 |
52 // template implementations | 60 // template implementations |
53 template <class T> | 61 template <class T> |
54 SlotAllocator<T>::~SlotAllocator() { | 62 SlotAllocator<T>::~SlotAllocator() { |
55 for (uint32_t i = 0; i < slots_.size(); ++i) { | 63 for (uint32_t i = 0; i < slots_.size(); ++i) { |
56 if (slots_[i]) { | 64 if (slots_[i]) { |
57 delete slots_[i]; | 65 delete slots_[i]; |
58 slots_[i] = NULL; | 66 slots_[i] = NULL; |
59 } | 67 } |
60 } | 68 } |
61 } | 69 } |
62 | 70 |
63 template <class T> | 71 template <class T> |
64 int SlotAllocator<T>::Alloc() { | 72 int SlotAllocator<T>::Alloc() { |
65 if (heap_.size() == 0) { | 73 if (free_fds_.size() == 0) { |
66 slots_.push_back(new T); | 74 slots_.push_back(new T); |
67 return slots_.size()-1; | 75 return slots_.size()-1; |
68 } | 76 } |
69 int index = heap_.front(); | 77 int index = *(free_fds_.begin()); |
70 std::pop_heap(heap_.begin(), heap_.end(), comp); | 78 free_fds_.erase(free_fds_.begin()); |
71 heap_.pop_back(); | |
72 slots_[index] = new T; | 79 slots_[index] = new T; |
73 return index; | 80 return index; |
74 } | 81 } |
75 | 82 |
76 template <class T> | 83 template <class T> |
| 84 int SlotAllocator<T>::AllocAt(int fd) { |
| 85 int prev_size = slots_.size(); |
| 86 if (slots_.size() < fd + 1) { |
| 87 slots_.resize(fd + 1); |
| 88 } else { |
| 89 if (free_fds_.find(fd) != free_fds_.end()) { |
| 90 slots_[fd] = new T; |
| 91 for (int i = prev_size; i < fd; ++i) free_fds_.insert(i); |
| 92 } else { |
| 93 return -1; |
| 94 } |
| 95 } |
| 96 return fd; |
| 97 } |
| 98 |
| 99 template <class T> |
77 void SlotAllocator<T>::Free(int slot) { | 100 void SlotAllocator<T>::Free(int slot) { |
78 if (slot < 0 || | 101 if (slot < 0 || |
79 static_cast<uint32_t>(slot) >= slots_.size() || | 102 static_cast<uint32_t>(slot) >= slots_.size() || |
80 !slots_[slot]) { | 103 !slots_[slot]) { |
81 return; | 104 return; |
82 } | 105 } |
83 delete slots_[slot]; | 106 delete slots_[slot]; |
84 slots_[slot] = NULL; | 107 slots_[slot] = NULL; |
85 heap_.push_back(slot); | 108 free_fds_.insert(slot); |
86 std::push_heap(heap_.begin(), heap_.end(), comp); | |
87 } | 109 } |
88 | 110 |
89 template <class T> | 111 template <class T> |
90 T *SlotAllocator<T>::At(int slot) { | 112 T *SlotAllocator<T>::At(int slot) { |
91 if (slot < 0 || static_cast<uint32_t>(slot) >= slots_.size()) { | 113 if (slot < 0 || static_cast<uint32_t>(slot) >= slots_.size()) { |
92 return NULL; | 114 return NULL; |
93 } | 115 } |
94 return slots_[slot]; | 116 return slots_[slot]; |
95 } | 117 } |
96 | 118 |
97 #endif // PACKAGES_LIBRARIES_NACL_MOUNTS_UTIL_SLOTALLOCATOR_H_ | 119 #endif // PACKAGES_LIBRARIES_NACL_MOUNTS_UTIL_SLOTALLOCATOR_H_ |
OLD | NEW |