summaryrefslogtreecommitdiff
path: root/AK/NoAllocationGuard.h
blob: 544057809b1cce103b176a48a66976a2ccfdd204 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
/*
 * Copyright (c) 2022, kleines Filmröllchen <filmroellchen@serenityos.org>.
 *
 * SPDX-License-Identifier: BSD-2-Clause
 */

#pragma once

#include <AK/Forward.h>
#include <AK/Noncopyable.h>

#if defined(KERNEL)
#    include <Kernel/Arch/Processor.h>
#    include <Kernel/Heap/kmalloc.h>
#else
#    include <LibC/mallocdefs.h>
#endif

namespace AK {

class NoAllocationGuard {
    AK_MAKE_NONCOPYABLE(NoAllocationGuard);
    AK_MAKE_NONMOVABLE(NoAllocationGuard);

public:
    NoAllocationGuard()
        : m_allocation_enabled_previously(get_thread_allocation_state())
    {
        set_thread_allocation_state(false);
    }

    ~NoAllocationGuard()
    {
        set_thread_allocation_state(m_allocation_enabled_previously);
    }

private:
    static bool get_thread_allocation_state()
    {
#if defined(KERNEL)
        return Processor::current_thread()->get_allocation_enabled();
#elif defined(AK_OS_SERENITY)
        // This extern thread-local lives in our LibC, which doesn't exist on other systems.
        return s_allocation_enabled;
#else
        return true;
#endif
    }

    static void set_thread_allocation_state(bool value)
    {
#if defined(KERNEL)
        Processor::current_thread()->set_allocation_enabled(value);
#elif defined(AK_OS_SERENITY)
        s_allocation_enabled = value;
#else
        (void)value;
#endif
    }

    bool m_allocation_enabled_previously { true };
};

}

using AK::NoAllocationGuard;