-
Notifications
You must be signed in to change notification settings - Fork 6.6k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
This CL introduce a simple scheduler for execute swap. (1) Must wait between two swaps. Use local storage to save the least swap time. (2) Check ARC running state regularly. The scheduler will be enabled in different parameters by finch. TEST=manually check will vmm-swap flag enabled Bug: b:265383671 Change-Id: I8c0e004cec150cc8bdada26d8fc0e2aaba522f1d Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4262294 Reviewed-by: Yuichiro Hanada <yhanada@chromium.org> Commit-Queue: Shengsong Tan <sstan@chromium.org> Cr-Commit-Position: refs/heads/main@{#1107315}
- Loading branch information
Shengsong Tan
authored and
Chromium LUCI CQ
committed
Feb 20, 2023
1 parent
b6aa987
commit 622c96c
Showing
6 changed files
with
204 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
// Copyright 2023 The Chromium Authors | ||
// Use of this source code is governed by a BSD-style license that can be | ||
// found in the LICENSE file. | ||
|
||
#include "chrome/browser/ash/arc/vmm/arc_vmm_swap_scheduler.h" | ||
|
||
#include "ash/components/arc/arc_prefs.h" | ||
#include "chrome/browser/ash/arc/vmm/arc_vmm_manager.h" | ||
#include "chrome/browser/browser_process.h" | ||
#include "chrome/browser/browser_process_platform_part.h" | ||
#include "components/prefs/pref_service.h" | ||
|
||
namespace arc { | ||
|
||
namespace { | ||
|
||
PrefService* local_state() { | ||
return g_browser_process->local_state(); | ||
} | ||
} // namespace | ||
|
||
ArcVmmSwapScheduler::ArcVmmSwapScheduler( | ||
base::TimeDelta minimum_swap_gap, | ||
base::TimeDelta checking_period, | ||
base::RepeatingCallback<bool()> swappable_checking_call, | ||
base::RepeatingCallback<void(bool)> swap_call) | ||
: minimum_swap_gap_(minimum_swap_gap), | ||
checking_period_(checking_period), | ||
swappable_checking_callback_(std::move(swappable_checking_call)), | ||
swap_callback_(std::move(swap_call)) {} | ||
|
||
ArcVmmSwapScheduler::~ArcVmmSwapScheduler() = default; | ||
|
||
void ArcVmmSwapScheduler::Start() { | ||
if (!timer_.IsRunning()) { | ||
timer_.Start(FROM_HERE, checking_period_, | ||
base::BindRepeating(&ArcVmmSwapScheduler::AttemptSwap, | ||
weak_ptr_factory_.GetWeakPtr())); | ||
} | ||
} | ||
|
||
void ArcVmmSwapScheduler::AttemptSwap() { | ||
const base::Time last_swap_out_time = | ||
local_state()->GetTime(prefs::kArcVmmSwapOutTime); | ||
|
||
if (!last_swap_out_time.is_null()) { | ||
auto past = base::Time::Now() - last_swap_out_time; | ||
if (past < minimum_swap_gap_) { | ||
return; | ||
} | ||
} | ||
|
||
if (!swappable_checking_callback_.is_null() && | ||
swappable_checking_callback_.Run()) { | ||
swap_callback_.Run(true); | ||
|
||
// TODO(sstan): Should be set by swap out notify. | ||
local_state()->SetTime(prefs::kArcVmmSwapOutTime, base::Time::Now()); | ||
} | ||
} | ||
|
||
} // namespace arc |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
// Copyright 2023 The Chromium Authors | ||
// Use of this source code is governed by a BSD-style license that can be | ||
// found in the LICENSE file. | ||
|
||
#ifndef CHROME_BROWSER_ASH_ARC_VMM_ARC_VMM_SWAP_SCHEDULER_H_ | ||
#define CHROME_BROWSER_ASH_ARC_VMM_ARC_VMM_SWAP_SCHEDULER_H_ | ||
|
||
#include "base/functional/callback.h" | ||
#include "base/timer/timer.h" | ||
|
||
namespace arc { | ||
|
||
// ArcVmmSwapScheduler periodically tries to swap out if it's suitable to enable | ||
// VMM swap for ARCVM. It won't request to swap out within the given interval | ||
// from the last swap out operation. | ||
class ArcVmmSwapScheduler { | ||
public: | ||
ArcVmmSwapScheduler(base::TimeDelta minimum_swap_gap, | ||
base::TimeDelta checking_period, | ||
base::RepeatingCallback<bool()> swappable_checking_call, | ||
base::RepeatingCallback<void(bool)> swap_call); | ||
ArcVmmSwapScheduler(const ArcVmmSwapScheduler&) = delete; | ||
ArcVmmSwapScheduler& operator=(const ArcVmmSwapScheduler&) = delete; | ||
~ArcVmmSwapScheduler(); | ||
|
||
void Start(); | ||
|
||
private: | ||
void AttemptSwap(); | ||
|
||
base::TimeDelta minimum_swap_gap_; | ||
base::TimeDelta checking_period_; | ||
|
||
base::RepeatingTimer timer_; | ||
|
||
// Callback returns true if the current ARCVM state is swappable. | ||
base::RepeatingCallback<bool()> swappable_checking_callback_; | ||
|
||
// Callback sends swap status to vmm manager. | ||
base::RepeatingCallback<void(bool)> swap_callback_; | ||
|
||
base::WeakPtrFactory<ArcVmmSwapScheduler> weak_ptr_factory_{this}; | ||
}; | ||
} // namespace arc | ||
#endif // CHROME_BROWSER_ASH_ARC_VMM_ARC_VMM_SWAP_SCHEDULER_H_ |
87 changes: 87 additions & 0 deletions
87
chrome/browser/ash/arc/vmm/arc_vmm_swap_scheduler_unittest.cc
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
// Copyright 2023 The Chromium Authors | ||
// Use of this source code is governed by a BSD-style license that can be | ||
// found in the LICENSE file. | ||
|
||
#include "chrome/browser/ash/arc/vmm/arc_vmm_swap_scheduler.h" | ||
|
||
#include "ash/components/arc/arc_prefs.h" | ||
#include "ash/components/arc/session/arc_service_manager.h" | ||
#include "base/test/bind.h" | ||
#include "chrome/browser/ash/arc/vmm/arc_vmm_manager.h" | ||
#include "chrome/test/base/scoped_testing_local_state.h" | ||
#include "chrome/test/base/testing_browser_process.h" | ||
#include "chrome/test/base/testing_profile.h" | ||
#include "chromeos/ash/components/dbus/concierge/fake_concierge_client.h" | ||
#include "content/public/test/browser_task_environment.h" | ||
#include "testing/gtest/include/gtest/gtest.h" | ||
|
||
namespace arc { | ||
|
||
namespace { | ||
constexpr auto kSwapGap = base::Minutes(60); | ||
constexpr auto kCheckingPreiod = base::Minutes(5); | ||
} // namespace | ||
|
||
class ArcVmmSwapSchedulerTest : public testing::Test { | ||
public: | ||
ArcVmmSwapSchedulerTest() : local_state_(TestingBrowserProcess::GetGlobal()) { | ||
ash::ConciergeClient::InitializeFake(); | ||
} | ||
|
||
ArcVmmSwapSchedulerTest(const ArcVmmSwapSchedulerTest&) = delete; | ||
ArcVmmSwapSchedulerTest& operator=(const ArcVmmSwapSchedulerTest&) = delete; | ||
|
||
~ArcVmmSwapSchedulerTest() override { ash::ConciergeClient::Shutdown(); } | ||
|
||
void InitScheduler(base::RepeatingCallback<bool()> swappable_checking_call, | ||
base::RepeatingCallback<void(bool)> swap_call) { | ||
scheduler_ = std::make_unique<ArcVmmSwapScheduler>( | ||
kSwapGap, kCheckingPreiod, swappable_checking_call, swap_call); | ||
} | ||
|
||
void SetSwapOutTime(base::Time time) { | ||
local_state_.Get()->SetTime(prefs::kArcVmmSwapOutTime, base::Time()); | ||
} | ||
|
||
base::test::TaskEnvironment* task_environment() { return &task_environment_; } | ||
|
||
ArcVmmSwapScheduler* scheduler() { return scheduler_.get(); } | ||
|
||
protected: | ||
content::BrowserTaskEnvironment task_environment_{ | ||
base::test::TaskEnvironment::TimeSource::MOCK_TIME}; | ||
|
||
private: | ||
std::unique_ptr<ArcVmmSwapScheduler> scheduler_; | ||
|
||
ScopedTestingLocalState local_state_; | ||
}; | ||
|
||
TEST_F(ArcVmmSwapSchedulerTest, FirstSwap) { | ||
// Pref value will be the base::Time() if it's empty. | ||
SetSwapOutTime(base::Time()); | ||
|
||
int checking_count = 0, swap_count = 0; | ||
InitScheduler(base::BindLambdaForTesting([&]() { | ||
checking_count++; | ||
return true; | ||
}), | ||
base::BindLambdaForTesting([&](bool enabled) { | ||
if (enabled) { | ||
swap_count++; | ||
} | ||
})); | ||
|
||
scheduler()->Start(); | ||
base::RunLoop().RunUntilIdle(); | ||
|
||
// Checking should wait for the first period. | ||
EXPECT_EQ(checking_count, 0); | ||
|
||
// Check and swapped. | ||
task_environment_.FastForwardBy(base::Minutes(20)); | ||
base::RunLoop().RunUntilIdle(); | ||
EXPECT_EQ(checking_count, 1); | ||
EXPECT_EQ(swap_count, 1); | ||
} | ||
} // namespace arc |