Merge tag 'pull-loongarch-20241016' of https://gitlab.com/gaosong/qemu into staging
[qemu/armbru.git] / hw / hyperv / hv-balloon-page_range_tree.h
blob333772b86d2b92b7cb73a0eef7e9bf490d35632b
1 /*
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.
8 */
10 #ifndef HW_HYPERV_HV_BALLOON_PAGE_RANGE_TREE_H
11 #define HW_HYPERV_HV_BALLOON_PAGE_RANGE_TREE_H
14 /* PageRange */
15 typedef struct PageRange {
16 uint64_t start;
17 uint64_t count;
18 } 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;
30 } else {
31 out->count = 0;
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,
38 PageRange *out)
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;
46 } else {
47 out->count = 0;
51 static inline void page_range_intersect(const PageRange *range,
52 uint64_t start, uint64_t count,
53 PageRange *out)
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)
66 PageRange trange;
68 page_range_intersect(range, start, count, &trange);
69 return trange.count;
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);
91 /* PageRangeTree */
92 /* type safety */
93 typedef struct PageRangeTree {
94 GTree *t;
95 } PageRangeTree;
97 static inline bool page_range_tree_is_empty(PageRangeTree tree)
99 guint nnodes = g_tree_nnodes(tree.t);
101 return nnodes == 0;
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,
111 uint64_t maxcount);
113 void hvb_page_range_tree_insert(PageRangeTree tree,
114 uint64_t start, uint64_t count,
115 uint64_t *dupcount);
117 #endif