|
Packit |
c22fc9 |
/*
|
|
Packit |
c22fc9 |
* Soft: Keepalived is a failover program for the LVS project
|
|
Packit |
c22fc9 |
* <www.linuxvirtualserver.org>. It monitor & manipulate
|
|
Packit |
c22fc9 |
* a loadbalanced server pool using multi-layer checks.
|
|
Packit |
c22fc9 |
* In addition it provides a VRRPv2 & VRRPv3 stack.
|
|
Packit |
c22fc9 |
*
|
|
Packit |
c22fc9 |
* Author: Alexandre Cassen, <acassen@corp.free.fr>
|
|
Packit |
c22fc9 |
*
|
|
Packit |
c22fc9 |
* This program is distributed in the hope that it will be useful,
|
|
Packit |
c22fc9 |
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
Packit |
c22fc9 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
Packit |
c22fc9 |
* See the GNU General Public License for more details.
|
|
Packit |
c22fc9 |
*
|
|
Packit |
c22fc9 |
* This program is free software; you can redistribute it and/or
|
|
Packit |
c22fc9 |
* modify it under the terms of the GNU General Public License
|
|
Packit |
c22fc9 |
* as published by the Free Software Foundation; either version
|
|
Packit |
c22fc9 |
* 2 of the License, or (at your option) any later version.
|
|
Packit |
c22fc9 |
*
|
|
Packit |
c22fc9 |
* Copyright (C) 2018 Alexandre Cassen, <acassen@corp.free.fr>
|
|
Packit |
c22fc9 |
*/
|
|
Packit |
c22fc9 |
|
|
Packit |
c22fc9 |
#include "list_head.h"
|
|
Packit Service |
dfccb1 |
#include "warnings.h"
|
|
Packit Service |
dfccb1 |
|
|
Packit |
c22fc9 |
|
|
Packit |
c22fc9 |
void list_sort(struct list_head *head,
|
|
Packit |
c22fc9 |
int (*cmp)(struct list_head *a, struct list_head *b))
|
|
Packit |
c22fc9 |
{
|
|
Packit |
c22fc9 |
struct list_head *p, *q, *e, *list, *tail, *oldhead;
|
|
Packit Service |
dfccb1 |
unsigned insize, nmerges, psize, qsize, i;
|
|
Packit |
c22fc9 |
|
|
Packit |
c22fc9 |
list = head->next;
|
|
Packit |
c22fc9 |
list_head_del(head);
|
|
Packit |
c22fc9 |
insize = 1;
|
|
Packit |
c22fc9 |
|
|
Packit |
c22fc9 |
while (1) {
|
|
Packit |
c22fc9 |
p = oldhead = list;
|
|
Packit |
c22fc9 |
list = tail = NULL;
|
|
Packit |
c22fc9 |
nmerges = 0;
|
|
Packit |
c22fc9 |
|
|
Packit |
c22fc9 |
while (p) {
|
|
Packit |
c22fc9 |
nmerges++;
|
|
Packit |
c22fc9 |
q = p;
|
|
Packit |
c22fc9 |
psize = 0;
|
|
Packit |
c22fc9 |
for (i = 0; i < insize; i++) {
|
|
Packit |
c22fc9 |
psize++;
|
|
Packit |
c22fc9 |
q = q->next == oldhead ? NULL : q->next;
|
|
Packit |
c22fc9 |
if (!q)
|
|
Packit |
c22fc9 |
break;
|
|
Packit |
c22fc9 |
}
|
|
Packit |
c22fc9 |
|
|
Packit |
c22fc9 |
qsize = insize;
|
|
Packit |
c22fc9 |
while (psize > 0 || (qsize > 0 && q)) {
|
|
Packit |
c22fc9 |
if (!psize) {
|
|
Packit |
c22fc9 |
e = q;
|
|
Packit |
c22fc9 |
q = q->next;
|
|
Packit |
c22fc9 |
qsize--;
|
|
Packit |
c22fc9 |
if (q == oldhead)
|
|
Packit |
c22fc9 |
q = NULL;
|
|
Packit |
c22fc9 |
} else if (!qsize || !q) {
|
|
Packit |
c22fc9 |
e = p;
|
|
Packit |
c22fc9 |
p = p->next;
|
|
Packit |
c22fc9 |
psize--;
|
|
Packit |
c22fc9 |
} else if (cmp(p, q) <= 0) {
|
|
Packit |
c22fc9 |
e = p;
|
|
Packit |
c22fc9 |
p = p->next;
|
|
Packit |
c22fc9 |
psize--;
|
|
Packit |
c22fc9 |
} else {
|
|
Packit |
c22fc9 |
e = q;
|
|
Packit |
c22fc9 |
q = q->next;
|
|
Packit |
c22fc9 |
qsize--;
|
|
Packit |
c22fc9 |
if (q == oldhead)
|
|
Packit |
c22fc9 |
q = NULL;
|
|
Packit |
c22fc9 |
}
|
|
Packit |
c22fc9 |
if (tail)
|
|
Packit |
c22fc9 |
tail->next = e;
|
|
Packit |
c22fc9 |
else
|
|
Packit |
c22fc9 |
list = e;
|
|
Packit |
c22fc9 |
e->prev = tail;
|
|
Packit |
c22fc9 |
tail = e;
|
|
Packit |
c22fc9 |
}
|
|
Packit |
c22fc9 |
p = q;
|
|
Packit |
c22fc9 |
}
|
|
Packit |
c22fc9 |
|
|
Packit |
c22fc9 |
tail->next = list;
|
|
Packit |
c22fc9 |
list->prev = tail;
|
|
Packit |
c22fc9 |
|
|
Packit |
c22fc9 |
if (nmerges <= 1)
|
|
Packit |
c22fc9 |
break;
|
|
Packit |
c22fc9 |
|
|
Packit |
c22fc9 |
insize *= 2;
|
|
Packit |
c22fc9 |
}
|
|
Packit |
c22fc9 |
|
|
Packit |
c22fc9 |
head->next = list;
|
|
Packit |
c22fc9 |
head->prev = list->prev;
|
|
Packit |
c22fc9 |
list->prev->next = head;
|
|
Packit |
c22fc9 |
list->prev = head;
|
|
Packit |
c22fc9 |
}
|