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