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

[core/mem]: Document, refactor, reformat! #4209

Merged
merged 35 commits into from
Sep 16, 2024

Conversation

flysand7
Copy link
Contributor

@flysand7 flysand7 commented Sep 6, 2024

This PR makes a few small changes to the core:mem package. The changes are not supposed to alter the way existing code works, but if I find some bugs in the process I'll fix them in this PR too.

The changes include the following:

1. Formatting

Empty line gaps between procedures have been made consistent across all procedures. For now it is one empty line between two adjacent procedures, in the future I may add a two empty lines between procedures relating to different allocators.

Calls and declarations of procedures with parameters on multiple lines have been properly formatted at +1 indent from the start of the declaration/call, rather than aligned to the first parameter. There were also indentation issues relating to previous aligned that have been fixed due to this (alignment spaces started from the start of the line, instead of the first tab).

Lines over 120 characters in length that involve function calls have been wrapped.

2. API for using allocators directly

To make the behavior consistent, all allocators have their own API. This simplifies the internal code that calls itself a little bit, because now we have concrete functions to call, instead of calling allocator proc directly, and it makes things a little bit less crowded in the allocator procedures.

I chose to expose those functions not only because Odin prefers to expose things even if they are "internal", but also because these functions can get you going with using an allocator quicker if you aren't hooking into context/allocator system and just want a thing to quickly create and use. For example you can create a stack allocator for a few loops and then dispose of it quickly, without having to convert it into an allocator, reassigning it to context and any of that stuff. I see some potential of it being used for making the code a little bit more explicit in times of need.

All allocators will be provided with the following functions:

  • *_alloc, *_alloc_bytes, *_alloc_non_zeroed, *_alloc_bytes_non_zeroed
  • (if supported) *_free
  • (if supported) *_free_all
  • (if supported) *_resize, *_resize_bytes, *_resize_non_zeroed, *_resize_bytes_non_zeroed

The resize procedures are only exposed if non-default implementation is used in the allocator.

The word allocator has been omitted in all of these procedures, except for buddy_allocator_* procedures, which I don't want to alter too much. So, for example in case of stack allocator, the allocation function would be called stack_alloc.

The the types of parameters will be according to conventions from alloc.odin, i.e. *bytes* in the name specifies the usage of slice types, otherwise pointer types. The parameters to each of these procedures would be the minimum necessary amount needed for the procedure to work. The old_size in resize functions will not be a parameter, if allocator stores that information in the header.

3. Bugs and issue fixes.

  • Scratch allocator's alloc_non_zeroed mode would zero-out memory for all allocations when it uses the backing allocator, even if non-zeroed mode is used.
  • Dynamic pool's alloc_non_zeroed mode would zero-out memory for all allocations, even if non-zeroed mode is used.
  • Some of the allocator procedures that call panic, assert, a backing allocator, and some calls to default_resize_bytes_align, would not correctly pass the location of the user's code that called those allocator procedures, that would theorhetically result in the error being printed for a wrong line of code. Panics and asserts related to user's errors are now all called with a passing of the loc parameter.
  • align_forward and align_backward families of functions have been rewritten using branchless code. The missing assertion (alignment must be a power of 2) in align_backward_uintptr was added.
  • Added resize_non_zeroed and resize_bytes_non_zeroed procedures as these weren't exposed via mem package.
  • Made arena and small stack panic upon allocations where the backing buffer wasn't properly initialized.
  • Default memory resize procedure was not properly relocating the allocation if the old memory pointer wasn't aligned to the specified alignment.
  • Enforced checks on parameter values in the runtime memory procedures, i.e. when alignment wasn't a power of two, because otherwise the location wouldn't be passed properly.
  • Rollback stack allocator's alloc and resize procedures were renamed to alloc_non_zeroed and resize_non_zeroed to highlight their zeroing behaviour.

4. Changes to Dynamic Pool (Dynamic Arena)

Dynamic pool allocator was a misnomer. It is in fact not a pool, but renaming it outright could cause a lot of code to break. In this PR the dynamic pool was renamed into dynamic arena and the old declarations were preserved via aliases.

Dynamic pool has also obtained two function variants that have been missing, alloc_non_zeroed and resize_non_zeroed. Previously this allocator was always zeroing-out memory, even on non-zero requests

As described in the above section, the source code location was more properly handled in the functions relating to the dynamic arena. The backing allocator functions pass the source code location into all functions of the underlying allocations.

5. Package documentation

The mem package has been given a proper documentation, for now containing a basic overview of addresses and abstractions over them (pointers, multipointers, slices), as well as some basic concepts like alignment and allocators.

All functions have been documented, according to the style I described in one of my previous PR's.

The allocator interface has been documented more thoroughly. The motivations and the main ideas were described in discussion #4216.


I'll add more stuff to the list as I work through the package

@flysand7 flysand7 changed the title [coire/mem]: Document, refactor, reformat! [core/mem]: Document, refactor, reformat! Sep 7, 2024
core/mem/mem.odin Outdated Show resolved Hide resolved
@flysand7 flysand7 marked this pull request as ready for review September 13, 2024 23:48
@flysand7
Copy link
Contributor Author

Ready for review and merging.

Comment on lines +1516 to +1527
/* Preserved for compatibility */
Dynamic_Pool :: Dynamic_Arena
DYNAMIC_POOL_BLOCK_SIZE_DEFAULT :: DYNAMIC_ARENA_BLOCK_SIZE_DEFAULT
DYNAMIC_POOL_OUT_OF_BAND_SIZE_DEFAULT :: DYNAMIC_ARENA_OUT_OF_BAND_SIZE_DEFAULT
dynamic_pool_allocator_proc :: dynamic_arena_allocator_proc
dynamic_pool_free_all :: dynamic_arena_free_all
dynamic_pool_reset :: dynamic_arena_reset
dynamic_pool_alloc_bytes :: dynamic_arena_alloc_bytes
dynamic_pool_alloc :: dynamic_arena_alloc
dynamic_pool_init :: dynamic_arena_init
dynamic_pool_allocator :: dynamic_arena_allocator
dynamic_pool_destroy :: dynamic_arena_destroy
Copy link
Member

Choose a reason for hiding this comment

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

Perfect!

@gingerBill gingerBill merged commit 68619f2 into odin-lang:master Sep 16, 2024
7 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants