mirror of
https://github.com/intel/llvm.git
synced 2026-01-28 10:38:23 +08:00
[libc] Gracefully handle allocation failures around BlockStore.
Reviewed By: lntue Differential Revision: https://reviews.llvm.org/D140459
This commit is contained in:
@@ -4,6 +4,8 @@ add_header_library(
|
||||
blockstore
|
||||
HDRS
|
||||
blockstore.h
|
||||
DEPENDS
|
||||
libc.src.__support.CPP.new
|
||||
)
|
||||
|
||||
add_header_library(
|
||||
|
||||
@@ -9,9 +9,10 @@
|
||||
#ifndef LLVM_LIBC_SUPPORT_BLOCKSTORE_H
|
||||
#define LLVM_LIBC_SUPPORT_BLOCKSTORE_H
|
||||
|
||||
#include <src/__support/CPP/new.h>
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
// TODO: fix our assert.h to make it useable
|
||||
#define assert(x) \
|
||||
@@ -114,7 +115,10 @@ public:
|
||||
|
||||
T *new_obj() {
|
||||
if (fill_count == BLOCK_SIZE) {
|
||||
auto new_block = reinterpret_cast<Block *>(::malloc(sizeof(Block)));
|
||||
AllocChecker ac;
|
||||
auto new_block = new (ac) Block();
|
||||
if (!ac)
|
||||
return nullptr;
|
||||
if (REVERSE_ORDER) {
|
||||
new_block->next = current;
|
||||
} else {
|
||||
@@ -129,9 +133,12 @@ public:
|
||||
return obj;
|
||||
}
|
||||
|
||||
void push_back(const T &value) {
|
||||
[[nodiscard]] bool push_back(const T &value) {
|
||||
T *ptr = new_obj();
|
||||
if (ptr == nullptr)
|
||||
return false;
|
||||
*ptr = value;
|
||||
return true;
|
||||
}
|
||||
|
||||
T &back() {
|
||||
@@ -153,7 +160,7 @@ public:
|
||||
current->next = nullptr;
|
||||
}
|
||||
if (last != &first)
|
||||
::free(last);
|
||||
delete last;
|
||||
fill_count = BLOCK_SIZE;
|
||||
}
|
||||
|
||||
@@ -182,14 +189,14 @@ void BlockStore<T, BLOCK_SIZE, REVERSE_ORDER>::destroy(
|
||||
while (current->next != nullptr) {
|
||||
auto temp = current;
|
||||
current = current->next;
|
||||
free(temp);
|
||||
delete temp;
|
||||
}
|
||||
} else {
|
||||
auto current = block_store->first.next;
|
||||
while (current != nullptr) {
|
||||
auto temp = current;
|
||||
current = current->next;
|
||||
free(temp);
|
||||
delete temp;
|
||||
}
|
||||
}
|
||||
block_store->current = nullptr;
|
||||
|
||||
@@ -67,13 +67,9 @@ void call_exit_callbacks() {
|
||||
} // namespace internal
|
||||
|
||||
static int add_atexit_unit(const AtExitUnit &unit) {
|
||||
// TODO: Use the return value of push_back and bubble it to the public
|
||||
// function as error return value. Note that a BlockStore push_back can
|
||||
// fail because of allocation failure. Likewise, a FixedVector push_back
|
||||
// can fail when it is full.
|
||||
handler_list_mtx.lock();
|
||||
exit_callbacks.push_back(unit);
|
||||
handler_list_mtx.unlock();
|
||||
MutexLock lock(&handler_list_mtx);
|
||||
if (!exit_callbacks.push_back(unit))
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@ public:
|
||||
void populate_and_iterate() {
|
||||
__llvm_libc::cpp::BlockStore<Element, BLOCK_SIZE, REVERSE> block_store;
|
||||
for (int i = 0; i < int(ELEMENT_COUNT); ++i)
|
||||
block_store.push_back({i, 2 * i, 3 * unsigned(i)});
|
||||
ASSERT_TRUE(block_store.push_back({i, 2 * i, 3 * unsigned(i)}));
|
||||
auto end = block_store.end();
|
||||
int i = 0;
|
||||
for (auto iter = block_store.begin(); iter != end; ++iter, ++i) {
|
||||
@@ -46,7 +46,7 @@ public:
|
||||
using __llvm_libc::cpp::BlockStore;
|
||||
BlockStore<int, 4, REVERSE> block_store;
|
||||
for (int i = 0; i < 20; i++)
|
||||
block_store.push_back(i);
|
||||
ASSERT_TRUE(block_store.push_back(i));
|
||||
for (int i = 19; i >= 0; i--, block_store.pop_back())
|
||||
ASSERT_EQ(block_store.back(), i);
|
||||
block_store.destroy(&block_store);
|
||||
@@ -57,9 +57,11 @@ public:
|
||||
BlockStore<int, 2, REVERSE> block_store;
|
||||
|
||||
ASSERT_TRUE(block_store.empty());
|
||||
block_store.push_back(1);
|
||||
for (int i = 0; i < 10; i++, block_store.push_back(1))
|
||||
ASSERT_TRUE(block_store.push_back(1));
|
||||
for (int i = 0; i < 10; i++) {
|
||||
ASSERT_FALSE(block_store.empty());
|
||||
ASSERT_TRUE(block_store.push_back(1));
|
||||
}
|
||||
block_store.destroy(&block_store);
|
||||
}
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user