File: region.cc

package info (click to toggle)
chromium 138.0.7204.183-1
  • links: PTS, VCS
  • area: main
  • in suites: trixie
  • size: 6,071,908 kB
  • sloc: cpp: 34,937,088; ansic: 7,176,967; javascript: 4,110,704; python: 1,419,953; asm: 946,768; xml: 739,971; pascal: 187,324; sh: 89,623; perl: 88,663; objc: 79,944; sql: 50,304; cs: 41,786; fortran: 24,137; makefile: 21,806; php: 13,980; tcl: 13,166; yacc: 8,925; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (95 lines) | stat: -rw-r--r-- 3,208 bytes parent folder | download | duplicates (3)
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
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
// Copyright 2020 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chromeos/ash/components/memory/userspace_swap/region.h"

#include <sys/uio.h>

#include <cstdint>
#include <ostream>
#include <string_view>
#include <vector>

#include "base/containers/span.h"

namespace ash {
namespace memory {
namespace userspace_swap {

// AsIovec will return the iovec representation of this Region.
struct iovec COMPONENT_EXPORT(USERSPACE_SWAP) Region::AsIovec() const {
  return {.iov_base = reinterpret_cast<void*>(address), .iov_len = length};
}

std::string_view COMPONENT_EXPORT(
    USERSPACE_SWAP) Region::AsStringPiece() const {
  return std::string_view(reinterpret_cast<char*>(address), length);
}

RegionOverlap COMPONENT_EXPORT(USERSPACE_SWAP) Region::CalculateRegionOverlap(
    const Region& range) const {
  RegionOverlap overlap;

  // We have four possible situations here related to how a region actually fits
  // within a range, as only a portion of a region we manage may have been
  // removed or unmapped. When situations such as 2, 3, and 4 happen we need to
  // deal with them and we will do that by restoring the remaining portion of
  // the region.
  //
  //          [ region_start           region_end ]
  //   1.     [ range_start             range_end ]
  //   2.     [range_start   range_end]
  //   3.                 [range_start   range_end]
  //   4.           [range_start   range_end]
  //
  //   Given these scenarios RemainingRegions will populate |before|
  //   and |after| if there are portions which were unaffected by an
  //   operation. This allows the Removed/Unmapped callbacks to determine how to
  //   restore any memory that was not removed or unmapped.
  uintptr_t region_start = address;
  uintptr_t region_end = address + length;
  uintptr_t range_start = range.address;
  uintptr_t range_end = range.address + range.length;

  CHECK_LE(range_start, range_end);
  CHECK_LE(region_start, region_end);

  if (range_end < region_start || range_start > region_end) {
    return overlap;  // There is no overlap
  }

  // Since we only care about the pieces that related to this region we will
  // clamp range_start and range_end.
  range_start = std::max(range_start, region_start);
  range_end = std::min(range_end, region_end);

  if (range_start > region_start) {
    overlap.before = Region(region_start, range_start - region_start);
  }

  overlap.intersection = Region(range_start, range_end - range_start);

  if (range_end < region_end) {
    overlap.after = Region(range_end, region_end - range_end);
  }

  return overlap;
}

// Easily print a region to a stream, useful for debugging.
std::ostream& COMPONENT_EXPORT(USERSPACE_SWAP) operator<<(
    std::ostream& os,
    const Region& region) {
  os << "[" << reinterpret_cast<void*>(region.address) << "-"
     << reinterpret_cast<void*>(region.address + region.length) << "]";
  return os;
}

RegionOverlap::RegionOverlap() = default;
RegionOverlap::~RegionOverlap() = default;
RegionOverlap::RegionOverlap(const RegionOverlap&) = default;

}  // namespace userspace_swap
}  // namespace memory
}  // namespace ash