2 * QEMU Hyper-V Dynamic Memory Protocol driver
4 * Copyright (C) 2020-2023 Oracle and/or its affiliates.
6 * This work is licensed under the terms of the GNU GPL, version 2 or later.
7 * See the COPYING file in the top-level directory.
10 #ifndef HW_HYPERV_HV_BALLOON_PAGE_RANGE_TREE_H
11 #define HW_HYPERV_HV_BALLOON_PAGE_RANGE_TREE_H
15 typedef struct PageRange
{
20 /* return just the part of range before (start) */
21 static inline void page_range_part_before(const PageRange
*range
,
22 uint64_t start
, PageRange
*out
)
24 uint64_t endr
= range
->start
+ range
->count
;
25 uint64_t end
= MIN(endr
, start
);
27 out
->start
= range
->start
;
28 if (end
> out
->start
) {
29 out
->count
= end
- out
->start
;
35 /* return just the part of range after (start, count) */
36 static inline void page_range_part_after(const PageRange
*range
,
37 uint64_t start
, uint64_t count
,
40 uint64_t end
= range
->start
+ range
->count
;
41 uint64_t ends
= start
+ count
;
43 out
->start
= MAX(range
->start
, ends
);
44 if (end
> out
->start
) {
45 out
->count
= end
- out
->start
;
51 static inline void page_range_intersect(const PageRange
*range
,
52 uint64_t start
, uint64_t count
,
55 uint64_t end1
= range
->start
+ range
->count
;
56 uint64_t end2
= start
+ count
;
57 uint64_t end
= MIN(end1
, end2
);
59 out
->start
= MAX(range
->start
, start
);
60 out
->count
= out
->start
< end
? end
- out
->start
: 0;
63 static inline uint64_t page_range_intersection_size(const PageRange
*range
,
64 uint64_t start
, uint64_t count
)
68 page_range_intersect(range
, start
, count
, &trange
);
72 static inline bool page_range_joinable_left(const PageRange
*range
,
73 uint64_t start
, uint64_t count
)
75 return start
+ count
== range
->start
;
78 static inline bool page_range_joinable_right(const PageRange
*range
,
79 uint64_t start
, uint64_t count
)
81 return range
->start
+ range
->count
== start
;
84 static inline bool page_range_joinable(const PageRange
*range
,
85 uint64_t start
, uint64_t count
)
87 return page_range_joinable_left(range
, start
, count
) ||
88 page_range_joinable_right(range
, start
, count
);
93 typedef struct PageRangeTree
{
97 static inline bool page_range_tree_is_empty(PageRangeTree tree
)
99 guint nnodes
= g_tree_nnodes(tree
.t
);
104 void hvb_page_range_tree_init(PageRangeTree
*tree
);
105 void hvb_page_range_tree_destroy(PageRangeTree
*tree
);
107 bool hvb_page_range_tree_intree_any(PageRangeTree tree
,
108 uint64_t start
, uint64_t count
);
110 bool hvb_page_range_tree_pop(PageRangeTree tree
, PageRange
*out
,
113 void hvb_page_range_tree_insert(PageRangeTree tree
,
114 uint64_t start
, uint64_t count
,