Serenity Operating System
1/*
2 * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
3 *
4 * SPDX-License-Identifier: BSD-2-Clause
5 */
6
7#pragma once
8
9#include <AK/Types.h>
10#include <Kernel/API/POSIX/sys/limits.h> // For PAGE_SIZE. Everyone needs PAGE_SIZE
11
12#define KMALLOC_SCRUB_BYTE 0xbb
13#define KFREE_SCRUB_BYTE 0xaa
14
15#define MAKE_ALIGNED_ALLOCATED(type, alignment) \
16public: \
17 [[nodiscard]] void* operator new(size_t) \
18 { \
19 void* ptr = kmalloc_aligned(sizeof(type), alignment); \
20 VERIFY(ptr); \
21 return ptr; \
22 } \
23 [[nodiscard]] void* operator new(size_t, std::nothrow_t const&) noexcept \
24 { \
25 return kmalloc_aligned(sizeof(type), alignment); \
26 } \
27 void operator delete(void* ptr) noexcept \
28 { \
29 kfree_sized(ptr, sizeof(type)); \
30 } \
31 \
32private:
33
34// The C++ standard specifies that the nothrow allocation tag should live in the std namespace.
35// Otherwise, `new (std::nothrow)` calls wouldn't get resolved.
36namespace std { // NOLINT(cert-dcl58-cpp) These declarations must be in ::std and we are not using <new>
37struct nothrow_t {
38 explicit nothrow_t() = default;
39};
40
41extern const nothrow_t nothrow;
42
43enum class align_val_t : size_t {};
44};
45
46void kmalloc_init();
47
48void kfree_sized(void*, size_t);
49
50struct kmalloc_stats {
51 size_t bytes_allocated;
52 size_t bytes_free;
53 size_t kmalloc_call_count;
54 size_t kfree_call_count;
55};
56void get_kmalloc_stats(kmalloc_stats&);
57
58extern bool g_dump_kmalloc_stacks;
59
60inline void* operator new(size_t, void* p) { return p; }
61inline void* operator new[](size_t, void* p) { return p; }
62
63[[nodiscard]] void* operator new(size_t size);
64[[nodiscard]] void* operator new(size_t size, std::nothrow_t const&) noexcept;
65[[nodiscard]] void* operator new(size_t size, std::align_val_t);
66[[nodiscard]] void* operator new(size_t size, std::align_val_t, std::nothrow_t const&) noexcept;
67
68void operator delete(void* ptr) noexcept DISALLOW("All deletes in the kernel should have a known size.");
69void operator delete(void* ptr, size_t) noexcept;
70void operator delete(void* ptr, std::align_val_t) noexcept DISALLOW("All deletes in the kernel should have a known size.");
71void operator delete(void* ptr, size_t, std::align_val_t) noexcept;
72
73[[nodiscard]] void* operator new[](size_t size);
74[[nodiscard]] void* operator new[](size_t size, std::nothrow_t const&) noexcept;
75
76void operator delete[](void* ptrs) noexcept DISALLOW("All deletes in the kernel should have a known size.");
77void operator delete[](void* ptr, size_t) noexcept;
78
79[[gnu::malloc, gnu::alloc_size(1)]] void* kmalloc(size_t);
80[[gnu::malloc, gnu::alloc_size(1, 2)]] void* kcalloc(size_t, size_t);
81
82[[gnu::malloc, gnu::alloc_size(1), gnu::alloc_align(2)]] void* kmalloc_aligned(size_t size, size_t alignment);
83
84size_t kmalloc_good_size(size_t);
85
86void kmalloc_enable_expand();