xref: /openbmc/qemu/util/range.c (revision fec0fc0a13ac7f1a1130433a6740cd850c3db34a)
1*fec0fc0aSEric Blake /*
2*fec0fc0aSEric Blake  * QEMU 64-bit address ranges
3*fec0fc0aSEric Blake  *
4*fec0fc0aSEric Blake  * Copyright (c) 2015-2016 Red Hat, Inc.
5*fec0fc0aSEric Blake  *
6*fec0fc0aSEric Blake  * This library is free software; you can redistribute it and/or
7*fec0fc0aSEric Blake  * modify it under the terms of the GNU General Public
8*fec0fc0aSEric Blake  * License as published by the Free Software Foundation; either
9*fec0fc0aSEric Blake  * version 2 of the License, or (at your option) any later version.
10*fec0fc0aSEric Blake  *
11*fec0fc0aSEric Blake  * This library is distributed in the hope that it will be useful,
12*fec0fc0aSEric Blake  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13*fec0fc0aSEric Blake  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14*fec0fc0aSEric Blake  * Lesser General Public License for more details.
15*fec0fc0aSEric Blake  *
16*fec0fc0aSEric Blake  * You should have received a copy of the GNU General Public
17*fec0fc0aSEric Blake  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
18*fec0fc0aSEric Blake  *
19*fec0fc0aSEric Blake  */
20*fec0fc0aSEric Blake 
21*fec0fc0aSEric Blake #include "qemu/osdep.h"
22*fec0fc0aSEric Blake #include "qemu/range.h"
23*fec0fc0aSEric Blake 
24*fec0fc0aSEric Blake /*
25*fec0fc0aSEric Blake  * Operations on 64 bit address ranges.
26*fec0fc0aSEric Blake  * Notes:
27*fec0fc0aSEric Blake  *   - ranges must not wrap around 0, but can include the last byte ~0x0LL.
28*fec0fc0aSEric Blake  *   - this can not represent a full 0 to ~0x0LL range.
29*fec0fc0aSEric Blake  */
30*fec0fc0aSEric Blake 
31*fec0fc0aSEric Blake /* 0,1 can merge with 1,2 but don't overlap */
32*fec0fc0aSEric Blake static bool ranges_can_merge(Range *range1, Range *range2)
33*fec0fc0aSEric Blake {
34*fec0fc0aSEric Blake     return !(range1->end < range2->begin || range2->end < range1->begin);
35*fec0fc0aSEric Blake }
36*fec0fc0aSEric Blake 
37*fec0fc0aSEric Blake static void range_merge(Range *range1, Range *range2)
38*fec0fc0aSEric Blake {
39*fec0fc0aSEric Blake     if (range1->end < range2->end) {
40*fec0fc0aSEric Blake         range1->end = range2->end;
41*fec0fc0aSEric Blake     }
42*fec0fc0aSEric Blake     if (range1->begin > range2->begin) {
43*fec0fc0aSEric Blake         range1->begin = range2->begin;
44*fec0fc0aSEric Blake     }
45*fec0fc0aSEric Blake }
46*fec0fc0aSEric Blake 
47*fec0fc0aSEric Blake GList *g_list_insert_sorted_merged(GList *list, gpointer data,
48*fec0fc0aSEric Blake                                    GCompareFunc func)
49*fec0fc0aSEric Blake {
50*fec0fc0aSEric Blake     GList *l, *next = NULL;
51*fec0fc0aSEric Blake     Range *r, *nextr;
52*fec0fc0aSEric Blake 
53*fec0fc0aSEric Blake     if (!list) {
54*fec0fc0aSEric Blake         list = g_list_insert_sorted(list, data, func);
55*fec0fc0aSEric Blake         return list;
56*fec0fc0aSEric Blake     }
57*fec0fc0aSEric Blake 
58*fec0fc0aSEric Blake     nextr = data;
59*fec0fc0aSEric Blake     l = list;
60*fec0fc0aSEric Blake     while (l && l != next && nextr) {
61*fec0fc0aSEric Blake         r = l->data;
62*fec0fc0aSEric Blake         if (ranges_can_merge(r, nextr)) {
63*fec0fc0aSEric Blake             range_merge(r, nextr);
64*fec0fc0aSEric Blake             l = g_list_remove_link(l, next);
65*fec0fc0aSEric Blake             next = g_list_next(l);
66*fec0fc0aSEric Blake             if (next) {
67*fec0fc0aSEric Blake                 nextr = next->data;
68*fec0fc0aSEric Blake             } else {
69*fec0fc0aSEric Blake                 nextr = NULL;
70*fec0fc0aSEric Blake             }
71*fec0fc0aSEric Blake         } else {
72*fec0fc0aSEric Blake             l = g_list_next(l);
73*fec0fc0aSEric Blake         }
74*fec0fc0aSEric Blake     }
75*fec0fc0aSEric Blake 
76*fec0fc0aSEric Blake     if (!l) {
77*fec0fc0aSEric Blake         list = g_list_insert_sorted(list, data, func);
78*fec0fc0aSEric Blake     }
79*fec0fc0aSEric Blake 
80*fec0fc0aSEric Blake     return list;
81*fec0fc0aSEric Blake }
82