Use more C++17
[WebKit-https.git] / Source / bmalloc / bmalloc / Scavenger.h
1 /*
2  * Copyright (C) 2017-2018 Apple Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
24  */
25
26 #pragma once
27
28 #include "BPlatform.h"
29 #include "DeferredDecommit.h"
30 #include "Mutex.h"
31 #include "PerProcess.h"
32 #include "Vector.h"
33 #include <chrono>
34 #include <condition_variable>
35 #include <mutex>
36
37 #if BOS(DARWIN)
38 #include <dispatch/dispatch.h>
39 #endif
40
41 namespace bmalloc {
42
43 class Scavenger {
44 public:
45     BEXPORT Scavenger(std::lock_guard<Mutex>&);
46     
47     ~Scavenger() = delete;
48     
49     void scavenge();
50     
51 #if BOS(DARWIN)
52     void setScavengerThreadQOSClass(qos_class_t overrideClass) { m_requestedScavengerThreadQOSClass = overrideClass; }
53     qos_class_t requestedScavengerThreadQOSClass() const { return m_requestedScavengerThreadQOSClass; }
54 #endif
55     
56     bool willRun() { return m_state == State::Run; }
57     void run();
58     
59     bool willRunSoon() { return m_state > State::Sleep; }
60     void runSoon();
61     
62     BEXPORT void didStartGrowing();
63     BEXPORT void scheduleIfUnderMemoryPressure(size_t bytes);
64     BEXPORT void schedule(size_t bytes);
65
66     // This is only here for debugging purposes.
67     // FIXME: Make this fast so we can use it to help determine when to
68     // run the scavenger:
69     // https://bugs.webkit.org/show_bug.cgi?id=184176
70     size_t freeableMemory();
71     // This doesn't do any synchronization, so it might return a slightly out of date answer.
72     // It's unlikely, but possible.
73     size_t footprint();
74
75 private:
76     enum class State { Sleep, Run, RunSoon };
77     
78     void runHoldingLock();
79     void runSoonHoldingLock();
80
81     void scheduleIfUnderMemoryPressureHoldingLock(size_t bytes);
82
83     BNO_RETURN static void threadEntryPoint(Scavenger*);
84     BNO_RETURN void threadRunLoop();
85     
86     void setSelfQOSClass();
87     void setThreadName(const char*);
88
89     std::chrono::milliseconds timeSinceLastFullScavenge();
90     std::chrono::milliseconds timeSinceLastPartialScavenge();
91     void partialScavenge();
92
93     std::atomic<State> m_state { State::Sleep };
94     size_t m_scavengerBytes { 0 };
95     bool m_isProbablyGrowing { false };
96     
97     Mutex m_mutex;
98     Mutex m_scavengingMutex;
99     std::condition_variable_any m_condition;
100
101     std::thread m_thread;
102     std::chrono::steady_clock::time_point m_lastFullScavengeTime { std::chrono::steady_clock::now() };
103     std::chrono::steady_clock::time_point m_lastPartialScavengeTime { std::chrono::steady_clock::now() };
104     
105 #if BOS(DARWIN)
106     dispatch_source_t m_pressureHandlerDispatchSource;
107     qos_class_t m_requestedScavengerThreadQOSClass { QOS_CLASS_USER_INITIATED };
108 #endif
109     
110     Vector<DeferredDecommit> m_deferredDecommits;
111 };
112
113 } // namespace bmalloc
114
115