mirror of
https://github.com/nmap/nmap.git
synced 2026-02-03 12:06:35 +00:00
Manage expiration times via a heap queue.
This prevents nsock from iterating over the whole list of events at each runloop, thus improving performance. It made it necessary to have pointers from the msevents to the event lists they belong to. The patch therefore also changes gh_list from autonomous containers to embedded structures. Added unit tests accordingly and cosmetic changes to make things look more consistent.
This commit is contained in:
@@ -9,138 +9,167 @@
|
||||
#include <time.h>
|
||||
|
||||
|
||||
#define INT2PTR(i) ((void *)(intptr_t)(i))
|
||||
#define PTR2INT(p) ((intptr_t)(void *)(p))
|
||||
|
||||
#define LIST_COUNT 16
|
||||
#define ELT_COUNT 2000
|
||||
|
||||
|
||||
struct testlist {
|
||||
unsigned int val;
|
||||
gh_lnode_t lnode;
|
||||
};
|
||||
|
||||
static unsigned int nodeval(gh_lnode_t *lnode) {
|
||||
struct testlist *tl;
|
||||
|
||||
tl = container_of(lnode, struct testlist, lnode);
|
||||
return tl->val;
|
||||
}
|
||||
|
||||
static gh_lnode_t *mknode(unsigned int val) {
|
||||
struct testlist *tl;
|
||||
|
||||
tl = calloc(1, sizeof(struct testlist));
|
||||
tl->val = val;
|
||||
return &tl->lnode;
|
||||
}
|
||||
|
||||
static void delnode(gh_lnode_t *lnode) {
|
||||
if (lnode)
|
||||
free(container_of(lnode, struct testlist, lnode));
|
||||
}
|
||||
|
||||
static int ghlist_stress(void *tdata) {
|
||||
gh_list lists[LIST_COUNT];
|
||||
gh_list_elem *current, *next;
|
||||
gh_list_t lists[LIST_COUNT];
|
||||
gh_lnode_t *current, *next;
|
||||
int num = 0;
|
||||
int ret;
|
||||
int i;
|
||||
|
||||
for (i=0; i < LIST_COUNT; i++)
|
||||
for (i = 0; i < LIST_COUNT; i++)
|
||||
gh_list_init(&lists[i]);
|
||||
|
||||
for (num=25000; num < 50000; num++) {
|
||||
for (i=0; i < LIST_COUNT; i++) {
|
||||
gh_list_append(&lists[i], INT2PTR(num));
|
||||
for (num = ELT_COUNT/2; num < ELT_COUNT; num++) {
|
||||
for (i = 0; i < LIST_COUNT; i++) {
|
||||
gh_list_append(&lists[i], mknode(num));
|
||||
}
|
||||
}
|
||||
|
||||
for (num=24999; num >= 0; num--) {
|
||||
for (i=0; i < LIST_COUNT; i++) {
|
||||
gh_list_prepend(&lists[i], INT2PTR(num));
|
||||
for (num = (ELT_COUNT/2 - 1); num >= 0; num--) {
|
||||
for (i = 0; i < LIST_COUNT; i++) {
|
||||
gh_list_prepend(&lists[i], mknode(num));
|
||||
}
|
||||
}
|
||||
|
||||
for (num=0; num < 50000; num++) {
|
||||
for (i=0; i < LIST_COUNT; i++) {
|
||||
ret = PTR2INT(gh_list_pop(&lists[i]));
|
||||
for (num = 0; num < ELT_COUNT; num++) {
|
||||
for (i = 0; i < LIST_COUNT; i++) {
|
||||
current = gh_list_pop(&lists[i]);
|
||||
ret = nodeval(current);
|
||||
if (ret != num) {
|
||||
fprintf(stderr, "prepend_test: Bogus return value %d when expected %d\n",
|
||||
ret, num);
|
||||
return -EINVAL;
|
||||
}
|
||||
delnode(current);
|
||||
}
|
||||
}
|
||||
for (i=0; i < LIST_COUNT; i++) {
|
||||
ret = PTR2INT(gh_list_pop(&lists[i]));
|
||||
if (ret != 0) {
|
||||
for (i = 0; i < LIST_COUNT; i++) {
|
||||
current = gh_list_pop(&lists[i]);
|
||||
if (current) {
|
||||
fprintf(stderr, "Ret is bogus for list %d", i);
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
for (num=24999; num >= 0; num--) {
|
||||
for (i=0; i < LIST_COUNT; i++) {
|
||||
gh_list_prepend(&lists[i], INT2PTR(num));
|
||||
for (num = (ELT_COUNT/2 - 1); num >= 0; num--) {
|
||||
for (i = 0; i < LIST_COUNT; i++) {
|
||||
gh_list_prepend(&lists[i], mknode(num));
|
||||
}
|
||||
}
|
||||
|
||||
for (num=25000; num < 50000; num++) {
|
||||
for (i=0; i < LIST_COUNT; i++) {
|
||||
gh_list_append(&lists[i], INT2PTR(num));
|
||||
for (num = ELT_COUNT/2; num < ELT_COUNT; num++) {
|
||||
for (i = 0; i < LIST_COUNT; i++) {
|
||||
gh_list_append(&lists[i], mknode(num));
|
||||
}
|
||||
}
|
||||
|
||||
for (num=0; num < 50000; num++) {
|
||||
for (num = 0; num < ELT_COUNT; num++) {
|
||||
for (i=0; i < LIST_COUNT; i++) {
|
||||
ret = PTR2INT(gh_list_pop(&lists[i]));
|
||||
current = gh_list_pop(&lists[i]);
|
||||
ret = nodeval(current);
|
||||
if (ret != num) {
|
||||
fprintf(stderr, "prepend_test: Bogus return value %d when expected %d\n",
|
||||
ret, num);
|
||||
return -EINVAL;
|
||||
}
|
||||
delnode(current);
|
||||
}
|
||||
}
|
||||
|
||||
for (num=25000; num < 50000; num++) {
|
||||
for (i=0; i < LIST_COUNT; i++) {
|
||||
gh_list_append(&lists[i], INT2PTR(num));
|
||||
}
|
||||
for (num = ELT_COUNT/2; num < ELT_COUNT; num++) {
|
||||
for (i = 0; i < LIST_COUNT; i++)
|
||||
gh_list_append(&lists[i], mknode(num));
|
||||
}
|
||||
|
||||
for (num=24999; num >= 0; num--) {
|
||||
for (i=0; i < LIST_COUNT; i++) {
|
||||
gh_list_prepend(&lists[i], INT2PTR(num));
|
||||
}
|
||||
for (num = ELT_COUNT/2 - 1; num >= 0; num--) {
|
||||
for (i = 0; i < LIST_COUNT; i++)
|
||||
gh_list_prepend(&lists[i], mknode(num));
|
||||
}
|
||||
|
||||
for (num=0; num < 50000; num++) {
|
||||
for (i=0; i < LIST_COUNT; i++) {
|
||||
ret = PTR2INT(gh_list_pop(&lists[i]));
|
||||
for (num = 0; num < ELT_COUNT; num++) {
|
||||
for (i = 0; i < LIST_COUNT; i++) {
|
||||
current = gh_list_pop(&lists[i]);
|
||||
ret = nodeval(current);
|
||||
if (ret != num) {
|
||||
fprintf(stderr, "prepend_test: Bogus return value %d when expected %d\n",
|
||||
ret, num);
|
||||
return -EINVAL;
|
||||
}
|
||||
delnode(current);
|
||||
}
|
||||
}
|
||||
|
||||
for (num=24999; num >= 0; num--) {
|
||||
for (i=0; i < LIST_COUNT; i++) {
|
||||
gh_list_prepend(&lists[i], INT2PTR(num));
|
||||
}
|
||||
for (num = ELT_COUNT/2 - 1; num >= 0; num--) {
|
||||
for (i = 0; i < LIST_COUNT; i++)
|
||||
gh_list_prepend(&lists[i], mknode(num));
|
||||
}
|
||||
|
||||
for (num=25000; num < 50000; num++) {
|
||||
for (i=0; i < LIST_COUNT; i++) {
|
||||
gh_list_append(&lists[i], INT2PTR(num));
|
||||
}
|
||||
for (num = ELT_COUNT/2; num < ELT_COUNT; num++) {
|
||||
for (i=0; i < LIST_COUNT; i++)
|
||||
gh_list_append(&lists[i], mknode(num));
|
||||
}
|
||||
|
||||
for (i=0; i < LIST_COUNT; i++) {
|
||||
num=0;
|
||||
for (current = GH_LIST_FIRST_ELEM(&lists[i]); current;
|
||||
current = next) {
|
||||
for (i = 0; i < LIST_COUNT; i++) {
|
||||
num = 0;
|
||||
|
||||
for (current = gh_list_first_elem(&lists[i]); current; current = next) {
|
||||
int k;
|
||||
|
||||
next = GH_LIST_ELEM_NEXT(current);
|
||||
k = PTR2INT(GH_LIST_ELEM_DATA(current));
|
||||
next = gh_lnode_next(current);
|
||||
k = nodeval(current);
|
||||
if (k != num) {
|
||||
fprintf(stderr, "Got %d when I expected %d\n", k, num);
|
||||
return -EINVAL;
|
||||
}
|
||||
gh_list_remove_elem(&lists[i], current);
|
||||
gh_list_remove(&lists[i], current);
|
||||
delnode(current);
|
||||
num++;
|
||||
}
|
||||
if (num != 50000) {
|
||||
fprintf(stderr, "Number is %d, even though %d was expected", num, 50000);
|
||||
if (num != ELT_COUNT) {
|
||||
fprintf(stderr, "Number is %d, even though %d was expected", num, ELT_COUNT);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (GH_LIST_COUNT(&lists[i]) != 0) {
|
||||
if (gh_list_count(&lists[i]) != 0) {
|
||||
fprintf(stderr, "List should be empty, but instead it has %d members!\n",
|
||||
GH_LIST_COUNT(&lists[i]));
|
||||
gh_list_count(&lists[i]));
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
for (i=0; i < LIST_COUNT; i++) {
|
||||
for (i = 0; i < LIST_COUNT; i++) {
|
||||
while ((current = gh_list_pop(&lists[i])) != NULL)
|
||||
delnode(current);
|
||||
|
||||
gh_list_free(&lists[i]);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user