Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cascaded allocator #2113

Open
wants to merge 50 commits into
base: master
Choose a base branch
from
Open

Conversation

smithAchang
Copy link

@smithAchang smithAchang commented Sep 4, 2023

ACE has fixed-size ACE*_Cached_Allocator, but in some case the total n_chunks can't be determined easyly :(

If the ACE framework has the ability to malloc fixed-size chunks 'infinitely' just like ACE_Malloc< ACE_MEM_POOL_1, ACE_LOCK > for mallocing various-size chunks, that will be very useful!

design

  • choose ACE_Dynamic_Cached_Allocator not ACE_Cached_Allocator

ACE_Cached_Allocator provides poor enhancement for the API

  • combinate ACE_Vector<T> to enable the flexibility of allocator hierarchy
  • all allocators forms a hierarchy with the allocator in lower level has 2 * n_chunks(upper level) capacity

Summary by CodeRabbit

  • New Features

    • Introduced an enhanced dynamic memory management system with a hierarchical caching approach to improve performance and reliability.
  • Tests

    • Added a comprehensive test suite to validate the new memory allocation capabilities, ensuring robust error handling and proper resource management.
    • Updated test configurations to integrate these new checks into the regular build process.
    • Included a new test case specifically for the cascaded allocator functionality.

@jwillemsen jwillemsen added the needs review Needs to be reviewed label Sep 4, 2023
@jwillemsen
Copy link
Member

Only read your description, please use std::vector, ACE_Vector is old and we don't want to use that anymore

@jwillemsen jwillemsen removed their request for review September 6, 2023 05:53
@smithAchang
Copy link
Author

I have fixed these questions,

Have I lefted any unfinished review issues ?

Copy link
Author

@smithAchang smithAchang left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok

@jwillemsen jwillemsen removed their request for review September 6, 2023 11:30
@jwillemsen
Copy link
Member

I have fixed these questions,

Have I lefted any unfinished review issues ?

I am busy with other things, review time on github is very limited, you will have to wait until me or someone else has time to do another review, I only did a high level review

@smithAchang
Copy link
Author

ok, thx :)


private:
// Useful STL-style traits.
using comb_alloc_type = ACE_Dynamic_Cached_Allocator<ACE_Null_Mutex>;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't this be ACE_LOCK?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

there is no need because the nested allocator will be protected by container class api

2、make simple for statement at one line
3、add the pool_sum API for component transparency
4、move pool_depth API from INL file to source file for its complexity
2、modify the test case to use lock strategy, that will more likely find some compiling error than free lock
2、fix test function name
this->hierarchy_.push_back(tmp);
if (0 == this->hierarchy_.size())
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

empty?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

when push_back fails it will throw, maybe use std::unique_ptr?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These APIs have strong exception safety guarantee, so there is no need to use std::unique_ptr.

Is it true ?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

By the way, I can see the result of these calls to judge whether potential exceptions have occurred

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See https://en.cppreference.com/w/cpp/language/exceptions, push_back can throw, when it does the state of the std::vector is guaranteed at that moment, but it will not just return. The exception should go back to the caller to my idea, your allocator should not leak when push_back (or any operation it uses) throws

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

when using unique_ptr the check after the push_back seems invalid

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have used std::unique_ptr for idiom in new commit

But for a vector of pointer, I think sdt::vector can keep strong exception guarantee.

If an exception is thrown (which can be due to Allocator::allocate() or element copy/move constructor/assignment), this > function has no effect ([strong exception guarantee]> (https://en.cppreference.com/w/cpp/language/exceptions#Exception_safety)).


Strong exception guarantee — If the function throws an exception, the state of the program is rolled back to the state > just before the function call (for example, [std::vector::push_back]>(https://en.cppreference.com/w/cpp/container/vector/push_back)).

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, Your idea is right!

The APIs provide strong exception guarantee, but not Nothrow

I will delete the defence codes

Copy link
Contributor

coderabbitai bot commented Feb 4, 2025

Walkthrough

This pull request introduces a new subproject commit along with a new cascaded dynamic cached allocator. The changes add a templated allocator class with methods for memory allocation (malloc, calloc, free) and pool management (dump, pool_depth, pool_sum, mutex) across new source, header, and inline files. Additionally, test files and configuration entries have been added to verify the allocator’s functionality within the project.

Changes

File(s) Change Summary
ACE/MPC Added new subproject commit (307f1fc30267dde08c28d5665716530ce7ff0abd) representing a specific snapshot of the project.
ACE/ace/Malloc_T.cpp, ACE/ace/Malloc_T.h, ACE/ace/Malloc_T.inl Introduced the ACE_Cascaded_Dynamic_Cached_Allocator class template with memory management methods (malloc, calloc, free, remove, bind, trybind, find, unbind, sync, protect, dump, pool_depth, pool_sum, mutex) and added new include directives (<memory>, <vector>, ace/Null_Mutex.h).
ACE/tests/Allocator_Cascaded_Test.cpp, ACE/tests/run_test.lst, ACE/tests/tests.mpc Added a new test file and updated test configurations to include the Allocator Cascaded Test, ensuring comprehensive validation of the new allocator’s functionality.

Sequence Diagram(s)

sequenceDiagram
    participant U as User/Application
    participant A as Cascaded Allocator
    participant CA as Child Allocator
    U->>A: Request allocation (malloc/calloc)
    alt Allocation fits in first child allocator
       A->>CA: Allocate memory
    else Fallback path
       A->>CA: Attempt allocation from last child or create new child
    end
    CA-->>A: Return allocated pointer
    A-->>U: Return memory pointer
Loading

Poem

I'm a coding bunny, hopping with delight,
In cascaded memory fields, everything's just right.
I nibble on commits like crunchy carrot snacks,
With smart pointers and tests lining up in stacks.
Through every allocation and free, I joyfully stray,
Celebrating fresh code on this bright new day!

✨ Finishing Touches
  • 📝 Generate Docstrings (Beta)

🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR. (Beta)
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (3)
ACE/ace/Malloc_T.cpp (1)

181-311: Validate expanded allocator logic and concurrency approach.

  1. The constructor defers allocation failures by reconstructing the hierarchy later if needed; verify whether this lazy handling of ACE_NEW failures is acceptable.
  2. The malloc method tries the “first” and “last” allocators, then expands. This is efficient under normal usage, but consider exposing a configuration to limit the maximum number of cascaded allocators to avoid runaway expansions.
  3. Concurrency:
    • Properly guarded by ACE_GUARD, ensuring safe multi-thread usage.
    • The free method routes all freed chunks to the first allocator, which is a valid design but could cause fragmentation in heavily threaded scenarios.
      Overall, design is logically consistent with the PR objectives.
ACE/tests/Allocator_Cascaded_Test.cpp (2)

110-111: Fix misleading comment.

The comment suggests "three" chunks but the actual count is the sum of initial and cascaded chunks.

-                             "  cascaded pool depth must be three after having freed all malloc ptrs\n");
+                             "  cascaded pool depth must equal total chunks (initial + cascaded) after freeing all malloc ptrs\n");

125-126: Enhance error message clarity.

The error message could be more descriptive about the expected memory content.

-                               "  calloc call must set the memory content as expected\n");
+                               "  calloc must initialize memory with the specified initial value\n");
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 13acc82 and 58da8c3.

📒 Files selected for processing (7)
  • ACE/MPC (1 hunks)
  • ACE/ace/Malloc_T.cpp (2 hunks)
  • ACE/ace/Malloc_T.h (4 hunks)
  • ACE/ace/Malloc_T.inl (1 hunks)
  • ACE/tests/Allocator_Cascaded_Test.cpp (1 hunks)
  • ACE/tests/run_test.lst (1 hunks)
  • ACE/tests/tests.mpc (1 hunks)
✅ Files skipped from review due to trivial changes (1)
  • ACE/MPC
⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: Codacy Static Code Analysis
🔇 Additional comments (11)
ACE/ace/Malloc_T.h (4)

8-9: No issues noted with updated authors.


19-19: Confirm concurrency handling with Null_Mutex.
Using Null_Mutex means there is effectively no locking in this allocator. Ensure higher-level synchronization (if required) is guaranteed by the container class or the calling code to prevent race conditions when multiple threads access this allocator hierarchy.


29-29: Usage of std::vector is aligned with modern C++ best practices.


210-311: Consider overflow checks and test coverage for expanding hierarchy.

  1. The cascade logic creates new allocators with size initial_n_chunks_ * (1 << hierarchy_.size()). In extreme cases, this could overflow or lead to memory exhaustion. Consider adding upper-bound checks to protect against unexpectedly large expansions.
  2. Ensure thorough tests covering multi-level expansions and associated memory usage.
  3. The rest of the design, including internal locking and usage of modern containers, looks good.
ACE/ace/Malloc_T.cpp (1)

17-17: Including <memory> for smart pointers is a good improvement.

ACE/ace/Malloc_T.inl (1)

41-53: Potential overflow in pool_sum() and external lock usage.

  1. pool_sum() returns the cumulative chunk count but does not guard against potential overflow if the hierarchy grows very large. Consider adding an upper bound or a warning.
  2. Exposing mutex() allows external lock manipulation, which can be flexible but might lead to unpredictable locking orders when used incorrectly. Validate or document expectations for external code.

Do you want a follow-up patch to add overflow checks or to document safe usage patterns for this lock accessor?

ACE/tests/Allocator_Cascaded_Test.cpp (3)

1-2: Remove duplicate empty lines.


20-28: LGTM!

The error handling macro is well-structured and correctly uses ACE's logging facilities.


157-170: LGTM!

The main function correctly follows ACE's test framework conventions.

ACE/tests/run_test.lst (1)

19-19: LGTM!

The test entry is correctly added to the test list.

ACE/tests/tests.mpc (1)

148-154: LGTM!

The project definition is well-structured and follows the file's conventions.

Comment on lines 72 to 73
ACE_TEST_EXCEPTION_RETURN (ptr == nullptr,
" pool must return valid ptr for calloc call with normal nbytes\n");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Fix incorrect error message.

The error message mentions "calloc" but the test is for "malloc".

-                             "  pool must return valid ptr for calloc call with normal nbytes\n");
+                             "  pool must return valid ptr for malloc call with normal nbytes\n");
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
ACE_TEST_EXCEPTION_RETURN (ptr == nullptr,
" pool must return valid ptr for calloc call with normal nbytes\n");
ACE_TEST_EXCEPTION_RETURN (ptr == nullptr,
" pool must return valid ptr for malloc call with normal nbytes\n");

Comment on lines 1 to 15
// ============================================================================
// ============================================================================
//
// = LIBRARY
// tests
//
// = DESCRIPTION
// This program tests the basic APIs supported in
// <ACE_Cascaded_Dynamic_Cached_Allocator>, and demonstrates how to use it.
//
// = AUTHOR
// Smith Achang <[email protected]>
//
// ============================================================================

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Add copyright notice.

The file is missing the standard ACE copyright notice.

Add the following copyright notice at the beginning of the file:

+// -*- C++ -*-
+
+// ============================================================================
+//
+// = LIBRARY
+//    tests
+//
+// = FILENAME
+//    Allocator_Cascaded_Test.cpp
+//
+// = DESCRIPTION
+//    This program tests the basic APIs supported in
+//    <ACE_Cascaded_Dynamic_Cached_Allocator>, and demonstrates how to use it.
+//
+// = AUTHOR
+//    Smith Achang <[email protected]>
+//
+// Copyright (c) 2025 CodeRabbit Inc.
+// All rights reserved.
+//
+// ============================================================================
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
// ============================================================================
// ============================================================================
//
// = LIBRARY
// tests
//
// = DESCRIPTION
// This program tests the basic APIs supported in
// <ACE_Cascaded_Dynamic_Cached_Allocator>, and demonstrates how to use it.
//
// = AUTHOR
// Smith Achang <[email protected]>
//
// ============================================================================
// -*- C++ -*-
// ============================================================================
//
// = LIBRARY
// tests
//
// = FILENAME
// Allocator_Cascaded_Test.cpp
//
// = DESCRIPTION
// This program tests the basic APIs supported in
// <ACE_Cascaded_Dynamic_Cached_Allocator>, and demonstrates how to use it.
//
// = AUTHOR
// Smith Achang <[email protected]>
//
// Copyright (c) 2025 CodeRabbit Inc.
// All rights reserved.
//
// ============================================================================
// ============================================================================
// ============================================================================
//
// = LIBRARY
// tests
//
// = DESCRIPTION
// This program tests the basic APIs supported in
// <ACE_Cascaded_Dynamic_Cached_Allocator>, and demonstrates how to use it.
//
// = AUTHOR
// Smith Achang <[email protected]>
//
// ============================================================================

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

♻️ Duplicate comments (2)
ACE/tests/Allocator_Cascaded_Test.cpp (2)

1-16: ⚠️ Potential issue

Add standard ACE copyright notice and fix header style.

The file header needs to follow ACE's standard format and include the copyright notice.

Add the copyright notice and fix the header style:

-
-//============================================================================
-/**
- *  @file    Allocator_Cascaded_Test.cpp
- *
- *  This program tests the basic APIs supported in <ACE_Cascaded_Dynamic_Cached_Allocator> and demonstrates how to use it.
- *
- *  @author Smith Achang <[email protected]>
- */
-//============================================================================
+// -*- C++ -*-
+
+// ============================================================================
+//
+// = LIBRARY
+//    tests
+//
+// = FILENAME
+//    Allocator_Cascaded_Test.cpp
+//
+// = DESCRIPTION
+//    This program tests the basic APIs supported in
+//    <ACE_Cascaded_Dynamic_Cached_Allocator>, and demonstrates how to use it.
+//
+// = AUTHOR
+//    Smith Achang <[email protected]>
+//
+// Copyright (c) 2025 CodeRabbit Inc.
+// All rights reserved.
+//
+// ============================================================================

69-70: ⚠️ Potential issue

Fix incorrect error message.

The error message mentions "malloc" but the test is for "calloc".

-                             "  pool must return valid ptr for malloc call with normal nbytes\n");
+                             "  pool must return valid ptr for calloc call with normal nbytes\n");
🧹 Nitpick comments (2)
ACE/tests/Allocator_Cascaded_Test.cpp (2)

112-112: Define magic numbers as named constants.

The magic number 8 * 1024 should be defined as a named constant for better maintainability.

+  static const size_t TOTAL_ALLOC_COUNT = 8 * 1024;
-  size_t const totalAllocSum = 8 * 1024;

27-152: Add test cases for flexible chunk handling.

Given that the PR's objective is to handle fixed-size chunks more flexibly, consider adding test cases that verify:

  1. Dynamic growth behavior when n_chunks is not predetermined
  2. Memory fragmentation scenarios
  3. Performance comparison with ACE_Cached_Allocator

Would you like me to generate additional test cases to cover these scenarios?

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 58da8c3 and 76ceba9.

📒 Files selected for processing (1)
  • ACE/tests/Allocator_Cascaded_Test.cpp (1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: Codacy Static Code Analysis
🔇 Additional comments (2)
ACE/tests/Allocator_Cascaded_Test.cpp (2)

17-25: LGTM! Well-structured error handling macro.

The macro follows good practices with proper do-while(0) pattern and consistent error handling style.


154-167: LGTM! Main function follows ACE test framework conventions.

The implementation correctly uses ACE's test framework macros and handles the return value properly.

size_t pool_sum, old_pool_sum, pool_depth, old_pool_depth;
char initial_value = '\0';

ACE_Cascaded_Dynamic_Cached_Allocator<ACE_SYNCH_MUTEX> alloc (initial_n_chunks, chunk_size);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Add thread safety tests.

The allocator uses ACE_SYNCH_MUTEX but there are no tests verifying thread safety. Consider adding concurrent allocation tests.

Would you like me to generate a concurrent test implementation to verify thread safety?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement needs review Needs to be reviewed
Development

Successfully merging this pull request may close these issues.

2 participants