]> git.ipfire.org Git - thirdparty/unbound.git/commitdiff
AIX, and threaded hash table test.
authorWouter Wijngaards <wouter@nlnetlabs.nl>
Thu, 22 Mar 2007 11:09:05 +0000 (11:09 +0000)
committerWouter Wijngaards <wouter@nlnetlabs.nl>
Thu, 22 Mar 2007 11:09:05 +0000 (11:09 +0000)
git-svn-id: file:///svn/unbound/trunk@187 be551aaa-1e26-0410-a405-d3ace91eadb9

configure.ac
doc/Changelog
testcode/lock_verify.c
testcode/unitlruhash.c
testdata/02-unittest.tpkg

index df4bb6931bb09b4d3c5c149a0b31042d3b4660ca..a85a159951957226d6908d2f1c68e7a2874e5a3b 100644 (file)
@@ -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,
 [
index 8a48129f3f3efc0a09dfe22fb8d6969222eecf73..d4a802b29d4753f0be25921e94326e671ba65d45 100644 (file)
@@ -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.
index 9f374f59d60e78ac9d497c77f03cefc0dd4b398f..53d6e780de9d5c11c091e6dd8d37a2f1268e805d 100644 (file)
@@ -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);
index 0548fc847bed3ae88eb77ecfedc9b2badfe8784f..a6af777586cf52c7d1046ce433c405add809c041 100644 (file)
@@ -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);
 }
 
index b0bd7904e2dcf274e19332e8fdaf124a6a763948..a0c0c816e7bc3941647f2af61c15f9bcceb16d88 100644 (file)
Binary files a/testdata/02-unittest.tpkg and b/testdata/02-unittest.tpkg differ