mirror of
https://github.com/NLnetLabs/unbound.git
synced 2025-12-20 23:00:56 -05:00
AIX, and threaded hash table test.
git-svn-id: file:///svn/unbound/trunk@187 be551aaa-1e26-0410-a405-d3ace91eadb9
This commit is contained in:
parent
9f413c07e0
commit
d39976b2e1
5 changed files with 122 additions and 17 deletions
|
|
@ -90,7 +90,7 @@ CHECK_COMPILER_FLAG(O2, [CFLAGS="$CFLAGS -O2"])
|
|||
|
||||
AC_CHECK_HEADERS([getopt.h time.h],,, [AC_INCLUDES_DEFAULT])
|
||||
|
||||
CHECK_COMPILER_FLAG_NEEDED(-std=c99 -D__EXTENSIONS__ -D_BSD_SOURCE -D_POSIX_C_SOURCE=200112 -D_XOPEN_SOURCE=600,
|
||||
CHECK_COMPILER_FLAG_NEEDED(-std=c99 -D__EXTENSIONS__ -D_BSD_SOURCE -D_POSIX_C_SOURCE=200112 -D_XOPEN_SOURCE=600 -D_ALL_SOURCE,
|
||||
[
|
||||
#include "confdefs.h"
|
||||
#include <stdlib.h>
|
||||
|
|
@ -121,7 +121,7 @@ int test() {
|
|||
str = gai_strerror(0);
|
||||
return a;
|
||||
}
|
||||
], [CFLAGS="$CFLAGS -std=c99 -D__EXTENSIONS__ -D_BSD_SOURCE -D_POSIX_C_SOURCE=200112 -D_XOPEN_SOURCE=600"])
|
||||
], [CFLAGS="$CFLAGS -std=c99 -D__EXTENSIONS__ -D_BSD_SOURCE -D_POSIX_C_SOURCE=200112 -D_XOPEN_SOURCE=600 -D_ALL_SOURCE"])
|
||||
|
||||
CHECK_COMPILER_FLAG_NEEDED(-std=c99,
|
||||
[
|
||||
|
|
|
|||
|
|
@ -1,3 +1,10 @@
|
|||
22 March 2007: Wouter
|
||||
- AIX configure check.
|
||||
- lock-verify can handle references to locks that are created
|
||||
in files it has not yet read in.
|
||||
- threaded hash table test.
|
||||
- unit test runs lock-verify afterwards and checks result.
|
||||
|
||||
21 March 2007: Wouter
|
||||
- unit test of hash table, fixup locking problem in table_grow().
|
||||
- fixup accounting of sizes for removing items from hashtable.
|
||||
|
|
|
|||
|
|
@ -155,7 +155,7 @@ read_header(FILE* in)
|
|||
if( abs((int)(the_time - t)) > 3600)
|
||||
fatal_exit("input files from different times: %u %u",
|
||||
(unsigned)the_time, (unsigned)t);
|
||||
printf(" trace of thread %d\n", thrno);
|
||||
printf(" trace of thread %u:%d\n", (unsigned)p, thrno);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
|
@ -194,9 +194,34 @@ static void read_create(rbtree_t* all, FILE* in)
|
|||
fatal_exit("fread: %s", strerror(errno));
|
||||
o->smaller = rbtree_create(order_lock_cmp);
|
||||
o->node.key = &o->id;
|
||||
if(!rbtree_insert(all, &o->node)) {
|
||||
/* already inserted */
|
||||
struct order_lock* a = (struct order_lock*)rbtree_search(all,
|
||||
&o->id);
|
||||
log_assert(a);
|
||||
a->create_file = o->create_file;
|
||||
a->create_line = o->create_line;
|
||||
free(o->smaller);
|
||||
free(o);
|
||||
o = a;
|
||||
}
|
||||
if(verb) printf("read create %u %u %s %d\n",
|
||||
(unsigned)o->id.thr, (unsigned)o->id.instance,
|
||||
o->create_file, o->create_line);
|
||||
}
|
||||
|
||||
/** insert lock entry (empty) into list */
|
||||
static struct order_lock*
|
||||
insert_lock(rbtree_t* all, struct order_id* id)
|
||||
{
|
||||
struct order_lock* o = calloc(1, sizeof(struct order_lock));
|
||||
if(!o) fatal_exit("malloc failure");
|
||||
o->smaller = rbtree_create(order_lock_cmp);
|
||||
o->id = *id;
|
||||
o->node.key = &o->id;
|
||||
if(!rbtree_insert(all, &o->node))
|
||||
fatal_exit("lock created twice");
|
||||
if(verb) printf("read create %s %d\n", o->create_file, o->create_line);
|
||||
fatal_exit("insert fail should not happen");
|
||||
return o;
|
||||
}
|
||||
|
||||
/** read lock entry */
|
||||
|
|
@ -214,12 +239,16 @@ static void read_lock(rbtree_t* all, FILE* in, int val)
|
|||
!readup_str(&ref->file, in) ||
|
||||
fread(&ref->line, sizeof(int), 1, in) != 1)
|
||||
fatal_exit("fread: %s", strerror(errno));
|
||||
if(verb) printf("read lock %s %d\n", ref->file, ref->line);
|
||||
if(verb) printf("read lock %u %u %u %u %s %d\n",
|
||||
(unsigned)prev_id.thr, (unsigned)prev_id.instance,
|
||||
(unsigned)now_id.thr, (unsigned)now_id.instance,
|
||||
ref->file, ref->line);
|
||||
/* find the two locks involved */
|
||||
prev = (struct order_lock*)rbtree_search(all, &prev_id);
|
||||
now = (struct order_lock*)rbtree_search(all, &now_id);
|
||||
if(!prev || !now)
|
||||
fatal_exit("Could not find locks involved.");
|
||||
/* if not there - insert 'em */
|
||||
if(!prev) prev = insert_lock(all, &prev_id);
|
||||
if(!now) now = insert_lock(all, &now_id);
|
||||
ref->lock = prev;
|
||||
ref->node.key = &prev->id;
|
||||
if(!rbtree_insert(now->smaller, &ref->node)) {
|
||||
|
|
@ -326,6 +355,10 @@ static void check_order_lock(struct order_lock* lock)
|
|||
start.file = lock->create_file;
|
||||
start.line = lock->create_line;
|
||||
|
||||
if(!lock->create_file)
|
||||
log_err("lock %u %u does not have create info",
|
||||
(unsigned)lock->id.thr, (unsigned)lock->id.instance);
|
||||
|
||||
/* depth first search to find cycle with this lock at head */
|
||||
lock->dfs_next = NULL;
|
||||
search_cycle(&start, 0, &start);
|
||||
|
|
@ -343,7 +376,7 @@ static void check_order(rbtree_t* all_locks)
|
|||
i, (int)all_locks->count,
|
||||
lock->id.thr, lock->id.instance,
|
||||
lock->create_file, lock->create_line);
|
||||
else if (i % 100 == 0)
|
||||
else if (i % (all_locks->count/75) == 0)
|
||||
fprintf(stderr, ".");
|
||||
i++;
|
||||
check_order_lock(lock);
|
||||
|
|
|
|||
|
|
@ -324,30 +324,32 @@ check_table(struct lruhash* table)
|
|||
|
||||
/** test adding a random element (unlimited range) */
|
||||
static void
|
||||
testadd_unlim(struct lruhash* table, struct testdata* ref[])
|
||||
testadd_unlim(struct lruhash* table, struct testdata** ref)
|
||||
{
|
||||
int numtoadd = random() % (HASHTESTMAX * 10);
|
||||
struct testdata* data = newdata(numtoadd);
|
||||
struct testkey* key = newkey(numtoadd);
|
||||
key->entry.data = data;
|
||||
lruhash_insert(table, myhash(numtoadd), &key->entry, data);
|
||||
ref[numtoadd] = data;
|
||||
if(ref)
|
||||
ref[numtoadd] = data;
|
||||
}
|
||||
|
||||
/** test adding a random element (unlimited range) */
|
||||
static void
|
||||
testremove_unlim(struct lruhash* table, struct testdata* ref[])
|
||||
testremove_unlim(struct lruhash* table, struct testdata** ref)
|
||||
{
|
||||
int num = random() % (HASHTESTMAX*10);
|
||||
struct testkey* key = newkey(num);
|
||||
lruhash_remove(table, myhash(num), key);
|
||||
ref[num] = NULL;
|
||||
if(ref)
|
||||
ref[num] = NULL;
|
||||
delkey(key);
|
||||
}
|
||||
|
||||
/** test adding a random element (unlimited range) */
|
||||
static void
|
||||
testlookup_unlim(struct lruhash* table, struct testdata* ref[])
|
||||
testlookup_unlim(struct lruhash* table, struct testdata** ref)
|
||||
{
|
||||
int num = random() % (HASHTESTMAX*10);
|
||||
struct testkey* key = newkey(num);
|
||||
|
|
@ -357,9 +359,9 @@ testlookup_unlim(struct lruhash* table, struct testdata* ref[])
|
|||
unit_assert(en->key);
|
||||
unit_assert(en->data);
|
||||
}
|
||||
if(0) log_info("lookup unlim %d got %d, expect %d", num, en ?
|
||||
if(0 && ref) log_info("lookup unlim %d got %d, expect %d", num, en ?
|
||||
data->data :-1, ref[num] ? ref[num]->data : -1);
|
||||
if(data) {
|
||||
if(data && ref) {
|
||||
/* its okay for !data, it fell off the lru */
|
||||
unit_assert( data == ref[num] );
|
||||
}
|
||||
|
|
@ -422,6 +424,66 @@ test_long_table(struct lruhash* table)
|
|||
}
|
||||
}
|
||||
|
||||
/** structure to threaded test the lru hash table */
|
||||
struct test_thr {
|
||||
/** thread num, first entry. */
|
||||
int num;
|
||||
/** id */
|
||||
ub_thread_t id;
|
||||
/** hash table */
|
||||
struct lruhash* table;
|
||||
};
|
||||
|
||||
/** main routine for threaded hash table test */
|
||||
static void*
|
||||
test_thr_main(void* arg)
|
||||
{
|
||||
struct test_thr* t = (struct test_thr*)arg;
|
||||
int i;
|
||||
log_thread_set(&t->num);
|
||||
for(i=0; i<1000; i++) {
|
||||
switch(random() % 4) {
|
||||
case 0:
|
||||
case 3:
|
||||
testadd_unlim(t->table, NULL);
|
||||
break;
|
||||
case 1:
|
||||
testremove_unlim(t->table, NULL);
|
||||
break;
|
||||
case 2:
|
||||
testlookup_unlim(t->table, NULL);
|
||||
break;
|
||||
default:
|
||||
unit_assert(0);
|
||||
}
|
||||
if(0) lruhash_status(t->table, "hashtest", 1);
|
||||
if(i % 100 == 0) /* because of locking, not all the time */
|
||||
check_table(t->table);
|
||||
}
|
||||
check_table(t->table);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/** test hash table access by multiple threads. */
|
||||
static void
|
||||
test_threaded_table(struct lruhash* table)
|
||||
{
|
||||
int numth = 10;
|
||||
struct test_thr t[100];
|
||||
int i;
|
||||
|
||||
for(i=1; i<numth; i++) {
|
||||
t[i].num = i;
|
||||
t[i].table = table;
|
||||
ub_thread_create(&t[i].id, test_thr_main, &t[i]);
|
||||
}
|
||||
|
||||
for(i=1; i<numth; i++) {
|
||||
ub_thread_join(t[i].id);
|
||||
}
|
||||
if(0) lruhash_status(table, "hashtest", 1);
|
||||
}
|
||||
|
||||
void lruhash_test()
|
||||
{
|
||||
/* start very very small array, so it can do lots of table_grow() */
|
||||
|
|
@ -432,7 +494,10 @@ void lruhash_test()
|
|||
test_lru(table);
|
||||
test_short_table(table);
|
||||
test_long_table(table);
|
||||
/* hashtable tests go here */
|
||||
lruhash_delete(table);
|
||||
table = lruhash_create(2, 4096,
|
||||
test_sizefunc, test_compfunc, test_delkey, test_deldata, NULL);
|
||||
test_threaded_table(table);
|
||||
lruhash_delete(table);
|
||||
}
|
||||
|
||||
|
|
|
|||
BIN
testdata/02-unittest.tpkg
vendored
BIN
testdata/02-unittest.tpkg
vendored
Binary file not shown.
Loading…
Reference in a new issue