[libc-commits] [libc] eb9cc25 - [libc] Gracefully handle allocation failures around BlockStore.
Siva Chandra Reddy via libc-commits
libc-commits at lists.llvm.org
Wed Dec 21 13:05:18 PST 2022
Author: Siva Chandra Reddy
Date: 2022-12-21T21:05:09Z
New Revision: eb9cc253cb048b6dbf2fcd73ac55b5eda0184ed3
URL: https://github.com/llvm/llvm-project/commit/eb9cc253cb048b6dbf2fcd73ac55b5eda0184ed3
DIFF: https://github.com/llvm/llvm-project/commit/eb9cc253cb048b6dbf2fcd73ac55b5eda0184ed3.diff
LOG: [libc] Gracefully handle allocation failures around BlockStore.
Reviewed By: lntue
Differential Revision: https://reviews.llvm.org/D140459
Added:
Modified:
libc/src/__support/CMakeLists.txt
libc/src/__support/blockstore.h
libc/src/stdlib/atexit.cpp
libc/test/src/__support/blockstore_test.cpp
Removed:
################################################################################
diff --git a/libc/src/__support/CMakeLists.txt b/libc/src/__support/CMakeLists.txt
index 3ca589b71781e..fc80c5389ddfc 100644
--- a/libc/src/__support/CMakeLists.txt
+++ b/libc/src/__support/CMakeLists.txt
@@ -4,6 +4,8 @@ add_header_library(
blockstore
HDRS
blockstore.h
+ DEPENDS
+ libc.src.__support.CPP.new
)
add_header_library(
diff --git a/libc/src/__support/blockstore.h b/libc/src/__support/blockstore.h
index 44c8b98551d93..43b6483846665 100644
--- a/libc/src/__support/blockstore.h
+++ b/libc/src/__support/blockstore.h
@@ -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 @@ class BlockStore {
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 @@ class BlockStore {
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 @@ class BlockStore {
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;
diff --git a/libc/src/stdlib/atexit.cpp b/libc/src/stdlib/atexit.cpp
index 7725463b8eb74..88a7d1a579a0d 100644
--- a/libc/src/stdlib/atexit.cpp
+++ b/libc/src/stdlib/atexit.cpp
@@ -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;
}
diff --git a/libc/test/src/__support/blockstore_test.cpp b/libc/test/src/__support/blockstore_test.cpp
index 3edbb920144bd..f844999b06e99 100644
--- a/libc/test/src/__support/blockstore_test.cpp
+++ b/libc/test/src/__support/blockstore_test.cpp
@@ -21,7 +21,7 @@ class LlvmLibcBlockStoreTest : public __llvm_libc::testing::Test {
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 @@ class LlvmLibcBlockStoreTest : public __llvm_libc::testing::Test {
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 @@ class LlvmLibcBlockStoreTest : public __llvm_libc::testing::Test {
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);
}
};
More information about the libc-commits
mailing list