mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-11-21 23:20:20 +00:00
Documentation: Add Patterns.md
The purpose of this document is to track and describe the various patterns used through the SerenityOS code base.
This commit is contained in:
parent
3e45c3ed90
commit
293e7ccfc7
Notes:
sideshowbarker
2024-07-18 04:40:14 +09:00
Author: https://github.com/bgianfo Commit: https://github.com/SerenityOS/serenity/commit/293e7ccfc70 Pull-request: https://github.com/SerenityOS/serenity/pull/9834 Reviewed-by: https://github.com/AtkinsSJ Reviewed-by: https://github.com/alimpfard Reviewed-by: https://github.com/linusg
1 changed files with 82 additions and 0 deletions
82
Documentation/Patterns.md
Normal file
82
Documentation/Patterns.md
Normal file
|
@ -0,0 +1,82 @@
|
|||
# SerenityOS patterns
|
||||
|
||||
## Introduction
|
||||
|
||||
Over time numerous reoccurring patterns have emerged from or were adopted by
|
||||
the serenity code base. This document aims to track and describe them so they
|
||||
can be propagated further and keep the code base consistent.
|
||||
|
||||
## Intrusive Lists
|
||||
|
||||
[Intrusive lists](https://www.data-structures-in-practice.com/intrusive-linked-lists/) are common in the Kernel and in some specific cases
|
||||
are used in the SerenityOS userland. A data structure is said to be
|
||||
"intrusive" when each element holds the metadata that tracks the
|
||||
element's membership in the data structure. In the case of a list, this
|
||||
means that every element in an intrusive linked list has a node embedded
|
||||
inside of it. The main advantage of intrusive
|
||||
data structures is you don't need to worry about handling out of memory (OOM)
|
||||
on insertion into the data structure. This means error handling code is
|
||||
much simpler than say, using a `Vector` in environments that need to be durable
|
||||
to OOM.
|
||||
|
||||
The common pattern for declaring an intrusive list is to add the storage
|
||||
for the intrusive list node as a private member. A public type alias is
|
||||
then used to expose the list type to anyone who might need to create it.
|
||||
Here is an example from the `Region` class in the Kernel:
|
||||
|
||||
```cpp
|
||||
class Region final
|
||||
: public Weakable<Region> {
|
||||
|
||||
public:
|
||||
|
||||
... snip ...
|
||||
|
||||
private:
|
||||
bool m_syscall_region : 1 { false };
|
||||
|
||||
IntrusiveListNode<Region> m_memory_manager_list_node;
|
||||
IntrusiveListNode<Region> m_vmobject_list_node;
|
||||
|
||||
public:
|
||||
using ListInMemoryManager = IntrusiveList<Region, RawPtr<Region>, &Region::m_memory_manager_list_node>;
|
||||
using ListInVMObject = IntrusiveList<Region, RawPtr<Region>, &Region::m_vmobject_list_node>;
|
||||
};
|
||||
```
|
||||
|
||||
You can then use the list by referencing the public type alias like so:
|
||||
|
||||
```cpp
|
||||
class MemoryManager {
|
||||
|
||||
... snip ...
|
||||
|
||||
Region::ListInMemoryManager m_kernel_regions;
|
||||
Vector<UsedMemoryRange> m_used_memory_ranges;
|
||||
Vector<PhysicalMemoryRange> m_physical_memory_ranges;
|
||||
Vector<ContiguousReservedMemoryRange> m_reserved_memory_ranges;
|
||||
};
|
||||
```
|
||||
|
||||
## Static Assertions of the size of a type
|
||||
|
||||
It's a universal pattern to use `static_assert` to validate the size of a
|
||||
type matches the author's expectations. Unfortunately when these assertions
|
||||
fail they don't give you the values that actually caused the failure. This
|
||||
forces one to go investigate by printing out the size, or checking it in a
|
||||
debugger, etc.
|
||||
|
||||
For this reason `AK::AssertSize` was added. It exploits the fact that the
|
||||
compiler will emit template argument values for compiler errors to provide
|
||||
debugging information. Instead of getting no information you'll get the actual
|
||||
type sizes in your compiler error output.
|
||||
|
||||
Example Usage:
|
||||
|
||||
```cpp
|
||||
#include <AK/StdLibExtras.h>
|
||||
|
||||
struct Empty { };
|
||||
|
||||
static_assert(AssertSize<Empty, 1>());
|
||||
```
|
Loading…
Reference in a new issue