From: Wouter Wijngaards Date: Thu, 22 Mar 2007 11:09:05 +0000 (+0000) Subject: AIX, and threaded hash table test. X-Git-Tag: release-0.2~40 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=d39976b2e1f7f43163e453eb598a6c722f57a3a8;p=thirdparty%2Funbound.git AIX, and threaded hash table test. git-svn-id: file:///svn/unbound/trunk@187 be551aaa-1e26-0410-a405-d3ace91eadb9 --- diff --git a/configure.ac b/configure.ac index df4bb6931..a85a15995 100644 --- a/configure.ac +++ b/configure.ac @@ -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 @@ -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, [ diff --git a/doc/Changelog b/doc/Changelog index 8a48129f3..d4a802b29 100644 --- a/doc/Changelog +++ b/doc/Changelog @@ -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. diff --git a/testcode/lock_verify.c b/testcode/lock_verify.c index 9f374f59d..53d6e780d 100644 --- a/testcode/lock_verify.c +++ b/testcode/lock_verify.c @@ -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); diff --git a/testcode/unitlruhash.c b/testcode/unitlruhash.c index 0548fc847..a6af77758 100644 --- a/testcode/unitlruhash.c +++ b/testcode/unitlruhash.c @@ -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