diff options
Diffstat (limited to 'innobase/sync/ts/tssync.c')
-rw-r--r-- | innobase/sync/ts/tssync.c | 1366 |
1 files changed, 1366 insertions, 0 deletions
diff --git a/innobase/sync/ts/tssync.c b/innobase/sync/ts/tssync.c new file mode 100644 index 00000000000..bf30a603284 --- /dev/null +++ b/innobase/sync/ts/tssync.c @@ -0,0 +1,1366 @@ +/************************************************************************ +The test module for the syncronization primitives + +(c) 1995 Innobase Oy + +Created 9/9/1995 Heikki Tuuri +*************************************************************************/ + + +#include "../sync0sync.h" +#include "../sync0rw.h" +#include "../sync0arr.h" +#include "../sync0ipm.h" +#include "ut0ut.h" +#include "mem0mem.h" +#include "os0sync.h" +#include "os0thread.h" +#include "os0sync.h" + +mutex_t mutex; +mutex_t mutex1; +mutex_t mutex2; +mutex_t mutex3; +mutex_t mutex4; + +ip_mutex_t ip_mutex; + +ip_mutex_t ip_mutex1; +ip_mutex_t ip_mutex2; +ip_mutex_t ip_mutex3; +ip_mutex_t ip_mutex4; + +ip_mutex_hdl_t* iph; + +ip_mutex_hdl_t* iph1; +ip_mutex_hdl_t* iph2; +ip_mutex_hdl_t* iph3; +ip_mutex_hdl_t* iph4; + + +rw_lock_t rw1; +rw_lock_t rw2; +rw_lock_t rw3; +rw_lock_t rw4; + +rw_lock_t rw9; +rw_lock_t rw10; +mutex_t mutex9; + +os_mutex_t osm; + +ulint last_thr; +ulint switch_count; +ulint glob_count; +ulint glob_inc; +ulint rc; + +bool qprint = FALSE; + +/******************************************************************** +Start function for thread 1 in test1. */ +ulint +thread1(void* arg) +/*==============*/ +{ + ulint i, j; + void* arg2; + + arg2 = arg; + + printf("Thread1 started!\n"); + + mutex_enter(&mutex); + + printf("Thread1 owns now the mutex!\n"); + + j = 0; + + for (i = 1; i < 1000000; i++) { + j += i; + } + + printf("Thread1 releases now the mutex!\n"); + + mutex_exit(&mutex); + + return(j); +} + +/******************************************************************** +Start function for thread 2 in test1. */ +ulint +thread2(void* arg) +/*==============*/ +{ + ulint i, j; + void* arg2; + + arg2 = arg; + + printf("Thread2 started!\n"); + + mutex_enter(&mutex); + + printf("Thread2 owns now the mutex!\n"); + + j = 0; + + for (i = 1; i < 1000000; i++) { + j += i; + } + + printf("Thread2 releases now the mutex!\n"); + + mutex_exit(&mutex); + + return(j); +} + +/******************************************************************** +Start function for the competing threads in test2. The function tests +the behavior lock-coupling through 4 mutexes. */ + +ulint +thread_n(volatile void* arg) +/*========================*/ +{ + ulint i, j, k, n; + + n = *((ulint*)arg); + + printf("Thread %ld started!\n", n); + + for (k = 0; k < 2000 * UNIV_DBC; k++) { + + mutex_enter(&mutex1); + + if (last_thr != n) { + switch_count++; + last_thr = n; + } + + j = 0; + + for (i = 1; i < 400; i++) { + j += i; + } + + mutex_enter(&mutex2); + + mutex_exit(&mutex1); + + for (i = 1; i < 400; i++) { + j += i; + } + mutex_enter(&mutex3); + + mutex_exit(&mutex2); + + for (i = 1; i < 400; i++) { + j += i; + } + mutex_enter(&mutex4); + + mutex_exit(&mutex3); + + for (i = 1; i < 400; i++) { + j += i; + } + + mutex_exit(&mutex4); + } + + printf("Thread %ld exits!\n", n); + + return(j); +} + +/******************************************************************** +Start function for mutex exclusion checking in test3. */ + +ulint +thread_x(void* arg) +/*===============*/ +{ + ulint k; + void* arg2; + + arg2 = arg; + + printf("Starting thread!\n"); + + for (k = 0; k < 200000 * UNIV_DBC; k++) { + + mutex_enter(&mutex); + + glob_count += glob_inc; + + mutex_exit(&mutex); + + } + + printf("Exiting thread!\n"); + + return(0); +} + + + +void +test1(void) +/*=======*/ +{ + os_thread_t thr1, thr2; + os_thread_id_t id1, id2; + ulint i, j; + ulint tm, oldtm; + ulint* lp; + + printf("-------------------------------------------\n"); + printf("SYNC-TEST 1. Test of mutexes.\n"); + + + printf("Main thread %ld starts!\n", + os_thread_get_curr_id()); + + osm = os_mutex_create(NULL); + + os_mutex_enter(osm); + os_mutex_exit(osm); + + os_mutex_free(osm); + + + mutex_create(&mutex); + + lp = &j; + + oldtm = ut_clock(); + + for (i = 0; i < 1000000; i++) { + id1 = os_thread_get_curr_id(); + } + + tm = ut_clock(); + printf("Wall clock time for %ld thread_get_id %ld milliseconds\n", + i, tm - oldtm); + + + oldtm = ut_clock(); + + for (i = 0; i < 100000 * UNIV_DBC; i++) { + + mutex_enter(&mutex); + mutex_exit(&mutex); + } + + tm = ut_clock(); + printf("Wall clock time for %ld mutex lock-unlock %ld milliseconds\n", + i, tm - oldtm); + + oldtm = ut_clock(); + + for (i = 0; i < 1000000; i++) { + + mutex_fence(); + } + + tm = ut_clock(); + printf("Wall clock time for %ld fences %ld milliseconds\n", + i, tm - oldtm); + + mutex_enter(&mutex); + + mutex_list_print_info(); + + ut_ad(1 == mutex_n_reserved()); + ut_ad(FALSE == sync_all_freed()); + + thr1 = os_thread_create(thread1, + NULL, + &id1); + + printf("Thread1 created, id %ld \n", id1); + + thr2 = os_thread_create(thread2, + NULL, + &id2); + + printf("Thread2 created, id %ld \n", id2); + + + j = 0; + + for (i = 1; i < 20000000; i++) { + j += i; + } + + sync_print(); + + sync_array_validate(sync_primary_wait_array); + + printf("Main thread releases now mutex!\n"); + + mutex_exit(&mutex); + + os_thread_wait(thr2); + + os_thread_wait(thr1); +} + +/****************************************************************** +Test function for possible convoy problem. */ + +void +test2(void) +/*=======*/ +{ + os_thread_t thr1, thr2, thr3, thr4, thr5; + os_thread_id_t id1, id2, id3, id4, id5; + ulint tm, oldtm; + ulint n1, n2, n3, n4, n5; + + printf("-------------------------------------------\n"); + printf("SYNC-TEST 2. Test of possible convoy problem.\n"); + + printf("System call count %lu\n", mutex_system_call_count); + + mutex_create(&mutex1); + mutex_create(&mutex2); + mutex_create(&mutex3); + mutex_create(&mutex4); + + switch_count = 0; + + oldtm = ut_clock(); + + n1 = 1; + + thr1 = os_thread_create(thread_n, + &n1, + &id1); + + os_thread_wait(thr1); + + + tm = ut_clock(); + printf("Wall clock time for single thread %ld milliseconds\n", + tm - oldtm); + printf("System call count %lu\n", mutex_system_call_count); + + switch_count = 0; + + oldtm = ut_clock(); + + n1 = 1; + thr1 = os_thread_create(thread_n, + &n1, + &id1); + n2 = 2; + thr2 = os_thread_create(thread_n, + &n2, + &id2); + n3 = 3; + thr3 = os_thread_create(thread_n, + &n3, + &id3); + n4 = 4; + thr4 = os_thread_create(thread_n, + &n4, + &id4); + n5 = 5; + thr5 = os_thread_create(thread_n, + &n5, + &id5); + + + os_thread_wait(thr1); + os_thread_wait(thr2); + os_thread_wait(thr3); + os_thread_wait(thr4); + os_thread_wait(thr5); + + + tm = ut_clock(); + printf("Wall clock time for 5 threads %ld milliseconds\n", + tm - oldtm); + printf("%ld thread switches occurred\n", switch_count); + + printf("If this is not 5 x single thread time, possibly convoy!\n"); + + printf("System call count %lu\n", mutex_system_call_count); +} + +/****************************************************************** +Test function for possible exclusion failure. */ + +void +test3(void) +/*=======*/ +{ + os_thread_t thr1, thr2; + os_thread_id_t id1, id2; + + printf("-------------------------------------------\n"); + printf("SYNC-TEST 3. Test of possible exclusion failure.\n"); + + glob_count = 0; + glob_inc = 1; + + thr1 = os_thread_create(thread_x, + NULL, + &id1); + thr2 = os_thread_create(thread_x, + NULL, + &id2); + + os_thread_wait(thr2); + os_thread_wait(thr1); + + ut_a(glob_count == 400000 * UNIV_DBC); +} + +/****************************************************************** +Test function for measuring the spin wait loop cycle time. */ + +void +test4(void) +/*=======*/ +{ +volatile ulint* ptr; + ulint i, tm, oldtm; + + printf("-------------------------------------------\n"); + printf("SYNC-TEST 4. Test of spin wait loop cycle time.\n"); + printf("Use this time to set the SYNC_SPIN_ROUNDS constant.\n"); + + + glob_inc = 1; + + ptr = &glob_inc; + + oldtm = ut_clock(); + + i = 0; + + while ((*ptr != 0) && (i < 10000000)) { + i++; + } + + tm = ut_clock(); + printf("Wall clock time for %ld cycles %ld milliseconds\n", + i, tm - oldtm); +} + +/******************************************************************** +Start function for s-lock thread in test5. */ +ulint +thread_srw(void* arg) +/*==============*/ +{ + ulint i, j; + void* arg2; + + arg2 = arg; + + printf("Thread_srw started!\n"); + + rw_lock_s_lock(&rw1); + + printf("Thread_srw has now s-lock!\n"); + + j = 0; + + for (i = 1; i < 1000000; i++) { + j += i; + } + + printf("Thread_srw releases now the s-lock!\n"); + + rw_lock_s_unlock(&rw1); + + return(j); +} + +/******************************************************************** +Start function for x-lock thread in test5. */ +ulint +thread_xrw(void* arg) +/*==============*/ +{ + ulint i, j; + void* arg2; + + arg2 = arg; + + printf("Thread_xrw started!\n"); + + rw_lock_x_lock(&rw1); + + printf("Thread_xrw has now x-lock!\n"); + + j = 0; + + for (i = 1; i < 1000000; i++) { + j += i; + } + + printf("Thread_xrw releases now the x-lock!\n"); + + rw_lock_x_unlock(&rw1); + + return(j); +} + + +void +test5(void) +/*=======*/ +{ + os_thread_t thr1, thr2; + os_thread_id_t id1, id2; + ulint i, j; + ulint tm, oldtm; + + printf("-------------------------------------------\n"); + printf("SYNC-TEST 5. Test of read-write locks.\n"); + + + printf("Main thread %ld starts!\n", + os_thread_get_curr_id()); + + + rw_lock_create(&rw1); + + oldtm = ut_clock(); + + + for (i = 0; i < 10000 * UNIV_DBC * UNIV_DBC; i++) { + + rw_lock_s_lock(&rw1); + + rw_lock_s_unlock(&rw1); + + } + + tm = ut_clock(); + printf("Wall clock time for %ld rw s-lock-unlock %ld milliseconds\n", + i, tm - oldtm); + + + oldtm = ut_clock(); + + + for (i = 0; i < 10000 * UNIV_DBC * UNIV_DBC; i++) { + + mutex_enter(&mutex); + rc++; + mutex_exit(&mutex); + + mutex_enter(&mutex); + rc--; + mutex_exit(&mutex); + } + + tm = ut_clock(); + printf("Wall clock time for %ld rw test %ld milliseconds\n", + i, tm - oldtm); + + + + oldtm = ut_clock(); + + for (i = 0; i < 10000 * UNIV_DBC * UNIV_DBC; i++) { + + rw_lock_x_lock(&rw1); + rw_lock_x_unlock(&rw1); + + } + + tm = ut_clock(); + printf("Wall clock time for %ld rw x-lock-unlock %ld milliseconds\n", + i, tm - oldtm); + + + /* Test recursive x-locking */ + for (i = 0; i < 10000; i++) { + rw_lock_x_lock(&rw1); + } + + for (i = 0; i < 10000; i++) { + + rw_lock_x_unlock(&rw1); + } + + /* Test recursive s-locking */ + for (i = 0; i < 10000; i++) { + + rw_lock_s_lock(&rw1); + } + + for (i = 0; i < 10000; i++) { + + rw_lock_s_unlock(&rw1); + } + + rw_lock_s_lock(&rw1); + + ut_ad(1 == rw_lock_n_locked()); + + mem_print_info(); + + rw_lock_list_print_info(); + + thr2 = os_thread_create(thread_xrw, + NULL, + &id2); + + printf("Thread_xrw created, id %ld \n", id2); + + + thr1 = os_thread_create(thread_srw, + NULL, + &id1); + + printf("Thread_srw created, id %ld \n", id1); + + j = 0; + + for (i = 1; i < 10000000; i++) { + j += i; + } + + rw_lock_list_print_info(); + + sync_array_validate(sync_primary_wait_array); + + printf("Main thread releases now rw-lock!\n"); + + rw_lock_s_unlock(&rw1); + + os_thread_wait(thr2); + + os_thread_wait(thr1); + + sync_array_print_info(sync_primary_wait_array); +} + +/******************************************************************** +Start function for the competing s-threads in test6. The function tests +the behavior lock-coupling through 4 rw-locks. */ + +ulint +thread_qs(volatile void* arg) +/*========================*/ +{ + ulint i, j, k, n; + + arg = arg; + + n = os_thread_get_curr_id(); + + printf("S-Thread %ld started, thread id %lu\n", n, + os_thread_get_curr_id()); + + for (k = 0; k < 1000 * UNIV_DBC; k++) { + + if (qprint) + printf("S-Thread %ld starts round %ld!\n", n, k); + + rw_lock_s_lock(&rw1); + + if (qprint) + printf("S-Thread %ld got lock 1 on round %ld!\n", n, k); + + + if (last_thr != n) { + switch_count++; + last_thr = n; + } + + j = 0; + + for (i = 1; i < 400; i++) { + j += i; + } + + rw_lock_s_lock(&rw2); + + if (qprint) + printf("S-Thread %ld got lock 2 on round %ld!\n", n, k); + + + rw_lock_s_unlock(&rw1); + + if (qprint) + printf("S-Thread %ld released lock 1 on round %ld!\n", n, k); + + + for (i = 1; i < 400; i++) { + j += i; + } + rw_lock_s_lock(&rw3); + + if (qprint) + printf("S-Thread %ld got lock 3 on round %ld!\n", n, k); + + + rw_lock_s_unlock(&rw2); + if (qprint) + printf("S-Thread %ld released lock 2 on round %ld!\n", n, k); + + + for (i = 1; i < 400; i++) { + j += i; + } + rw_lock_s_lock(&rw4); + + if (qprint) + printf("S-Thread %ld got lock 4 on round %ld!\n", n, k); + + + rw_lock_s_unlock(&rw3); + if (qprint) + printf("S-Thread %ld released lock 3 on round %ld!\n", n, k); + + + for (i = 1; i < 400; i++) { + j += i; + } + + rw_lock_s_unlock(&rw4); + if (qprint) + printf("S-Thread %ld released lock 4 on round %ld!\n", n, k); + + } + + printf("S-Thread %ld exits!\n", n); + + return(j); +} + +/******************************************************************** +Start function for the competing x-threads in test6. The function tests +the behavior lock-coupling through 4 rw-locks. */ + +ulint +thread_qx(volatile void* arg) +/*========================*/ +{ + ulint i, j, k, n; + + arg = arg; + + n = os_thread_get_curr_id(); + + printf("X-Thread %ld started, thread id %lu\n", n, + os_thread_get_curr_id()); + + for (k = 0; k < 1000 * UNIV_DBC; k++) { + + if (qprint) + printf("X-Thread %ld round %ld!\n", n, k); + + + rw_lock_x_lock(&rw1); + if (qprint) + printf("X-Thread %ld got lock 1 on round %ld!\n", n, k); + + + if (last_thr != n) { + switch_count++; + last_thr = n; + } + + j = 0; + + for (i = 1; i < 400; i++) { + j += i; + } + + rw_lock_x_lock(&rw2); + if (qprint) + printf("X-Thread %ld got lock 2 on round %ld!\n", n, k); + + + rw_lock_x_unlock(&rw1); + if (qprint) + printf("X-Thread %ld released lock 1 on round %ld!\n", n, k); + + + for (i = 1; i < 400; i++) { + j += i; + } + rw_lock_x_lock(&rw3); + if (qprint) + printf("X-Thread %ld got lock 3 on round %ld!\n", n, k); + + + rw_lock_x_unlock(&rw2); + if (qprint) + printf("X-Thread %ld released lock 2 on round %ld!\n", n, k); + + + for (i = 1; i < 400; i++) { + j += i; + } + rw_lock_x_lock(&rw4); + if (qprint) + printf("X-Thread %ld got lock 4 on round %ld!\n", n, k); + + rw_lock_x_unlock(&rw3); + if (qprint) + printf("X-Thread %ld released lock 3 on round %ld!\n", n, k); + + + for (i = 1; i < 400; i++) { + j += i; + } + + rw_lock_x_unlock(&rw4); + if (qprint) + printf("X-Thread %ld released lock 4 on round %ld!\n", n, k); + + } + + printf("X-Thread %ld exits!\n", n); + + return(j); +} + +/****************************************************************** +Test function for possible queuing problems with rw-locks. */ + +void +test6(void) +/*=======*/ +{ + os_thread_t thr1, thr2, thr3, thr4, thr5; + os_thread_id_t id1, id2, id3, id4, id5; + ulint tm, oldtm; + ulint n1, n2, n3, n4, n5; + + printf("-------------------------------------------\n"); + printf( + "SYNC-TEST 6. Test of possible queuing problems with rw-locks.\n"); +/* + sync_array_print_info(sync_primary_wait_array); +*/ + + rw_lock_create(&rw2); + rw_lock_create(&rw3); + rw_lock_create(&rw4); + + switch_count = 0; + + + oldtm = ut_clock(); + + n1 = 1; + + thr1 = os_thread_create(thread_qs, + &n1, + &id1); + + os_thread_wait(thr1); + + + tm = ut_clock(); + printf("Wall clock time for single s-lock thread %ld milliseconds\n", + tm - oldtm); + + oldtm = ut_clock(); + + n1 = 1; + + thr1 = os_thread_create(thread_qx, + &n1, + &id1); + + os_thread_wait(thr1); + + + tm = ut_clock(); + printf("Wall clock time for single x-lock thread %ld milliseconds\n", + tm - oldtm); + + switch_count = 0; + + oldtm = ut_clock(); + + + n1 = 1; + thr1 = os_thread_create(thread_qx, + &n1, + &id1); + + n2 = 2; + thr2 = os_thread_create(thread_qs, + &n2, + &id2); + + n3 = 3; + thr3 = os_thread_create(thread_qx, + &n3, + &id3); + + + n4 = 4; + thr4 = os_thread_create(thread_qs, + &n4, + &id4); + + n5 = 5; + thr5 = os_thread_create(thread_qx, + &n5, + &id5); + + os_thread_wait(thr1); + + os_thread_wait(thr2); + + os_thread_wait(thr3); + + os_thread_wait(thr4); + + os_thread_wait(thr5); + + + tm = ut_clock(); + printf("Wall clock time for 5 threads %ld milliseconds\n", + tm - oldtm); + printf("at least %ld thread switches occurred\n", switch_count); + + printf( + "If this is not 2 x s-thread + 3 x x-thread time, possibly convoy!\n"); + + rw_lock_list_print_info(); + + sync_array_print_info(sync_primary_wait_array); + +} + +/******************************************************************** +Start function for thread in test7. */ +ulint +ip_thread(void* arg) +/*================*/ +{ + ulint i, j; + void* arg2; + ulint ret; + ulint tm, oldtm; + + arg2 = arg; + + printf("Thread started!\n"); + + oldtm = ut_clock(); + + ret = ip_mutex_enter(iph, 100000); + +/* ut_a(ret == SYNC_TIME_EXCEEDED); +*/ + tm = ut_clock(); + + printf("Wall clock time for wait failure %ld ms\n", tm - oldtm); + + ret = ip_mutex_enter(iph, SYNC_INFINITE_TIME); + + ut_a(ret == 0); + + printf("Thread owns now the ip mutex!\n"); + + j = 0; + + for (i = 1; i < 1000000; i++) { + j += i; + } + + printf("Thread releases now the ip mutex!\n"); + + ip_mutex_exit(iph); + + return(j); +} + +/********************************************************************* +Test for interprocess mutex. */ +void +test7(void) +/*=======*/ +{ + os_thread_t thr1; + os_thread_id_t id1; + ulint i, j; + ulint tm, oldtm; + + printf("-------------------------------------------\n"); + printf("SYNC-TEST 7. Test of ip mutex.\n"); + + + printf("Main thread %ld starts!\n", + os_thread_get_curr_id()); + + ip_mutex_create(&ip_mutex, "IPMUTEX", &iph); + + oldtm = ut_clock(); + + for (i = 0; i < 100000 * UNIV_DBC; i++) { + + ip_mutex_enter(iph, SYNC_INFINITE_TIME); + ip_mutex_exit(iph); + } + + tm = ut_clock(); + printf("Wall clock time for %ld ip mutex lock-unlock %ld ms\n", + i, tm - oldtm); + + + ip_mutex_enter(iph, SYNC_INFINITE_TIME); + + thr1 = os_thread_create(ip_thread, + NULL, + &id1); + + printf("Thread created, id %ld \n", id1); + + + j = 0; + + for (i = 1; i < 100000000; i++) { + j += i; + } + + printf("Main thread releases now ip mutex!\n"); + + ip_mutex_exit(iph); + + os_thread_wait(thr1); + + ip_mutex_free(iph); +} + +/******************************************************************** +Start function for the competing threads in test8. The function tests +the behavior lock-coupling through 4 ip mutexes. */ + +ulint +thread_ipn(volatile void* arg) +/*========================*/ +{ + ulint i, j, k, n; + + n = *((ulint*)arg); + + printf("Thread %ld started!\n", n); + + for (k = 0; k < 2000 * UNIV_DBC; k++) { + + ip_mutex_enter(iph1, SYNC_INFINITE_TIME); + + if (last_thr != n) { + switch_count++; + last_thr = n; + } + + j = 0; + + for (i = 1; i < 400; i++) { + j += i; + } + + ip_mutex_enter(iph2, SYNC_INFINITE_TIME); + + ip_mutex_exit(iph1); + + for (i = 1; i < 400; i++) { + j += i; + } + ip_mutex_enter(iph3, SYNC_INFINITE_TIME); + + ip_mutex_exit(iph2); + + for (i = 1; i < 400; i++) { + j += i; + } + ip_mutex_enter(iph4, SYNC_INFINITE_TIME); + + ip_mutex_exit(iph3); + + for (i = 1; i < 400; i++) { + j += i; + } + + ip_mutex_exit(iph4); + } + + printf("Thread %ld exits!\n", n); + + return(j); +} + +/****************************************************************** +Test function for ip mutex. */ + +void +test8(void) +/*=======*/ +{ + os_thread_t thr1, thr2, thr3, thr4, thr5; + os_thread_id_t id1, id2, id3, id4, id5; + ulint tm, oldtm; + ulint n1, n2, n3, n4, n5; + + printf("-------------------------------------------\n"); + printf("SYNC-TEST 8. Test for ip mutex.\n"); + + + ip_mutex_create(&ip_mutex1, "jhfhk", &iph1); + ip_mutex_create(&ip_mutex2, "jggfg", &iph2); + ip_mutex_create(&ip_mutex3, "hfdx", &iph3); + ip_mutex_create(&ip_mutex4, "kjghg", &iph4); + + switch_count = 0; + + oldtm = ut_clock(); + + n1 = 1; + + thr1 = os_thread_create(thread_ipn, + &n1, + &id1); + + os_thread_wait(thr1); + + + tm = ut_clock(); + printf("Wall clock time for single thread %lu milliseconds\n", + tm - oldtm); + + switch_count = 0; + + oldtm = ut_clock(); + + n1 = 1; + thr1 = os_thread_create(thread_ipn, + &n1, + &id1); + n2 = 2; + thr2 = os_thread_create(thread_ipn, + &n2, + &id2); + n3 = 3; + thr3 = os_thread_create(thread_ipn, + &n3, + &id3); + n4 = 4; + thr4 = os_thread_create(thread_ipn, + &n4, + &id4); + n5 = 5; + thr5 = os_thread_create(thread_ipn, + &n5, + &id5); + + os_thread_wait(thr1); + os_thread_wait(thr2); + os_thread_wait(thr3); + os_thread_wait(thr4); + os_thread_wait(thr5); + + + tm = ut_clock(); + printf("Wall clock time for 5 threads %ld milliseconds\n", + tm - oldtm); + printf("%ld thread switches occurred\n", switch_count); + + printf("If this is not 5 x single thread time, possibly convoy!\n"); + + ip_mutex_free(iph1); + ip_mutex_free(iph2); + ip_mutex_free(iph3); + ip_mutex_free(iph4); +} + + +/******************************************************************** +Start function for s-lock thread in test9. */ +ulint +thread_srw9(void* arg) +/*==================*/ +{ + void* arg2; + + arg2 = arg; + + printf("Thread_srw9 started!\n"); + + rw_lock_x_lock(&rw10); + + printf("Thread_srw9 has now x-lock on rw10, wait for mutex!\n"); + + mutex_enter(&mutex9); + + return(0); +} + +/******************************************************************** +Start function for x-lock thread in test9. */ +ulint +thread_xrw9(void* arg) +/*==================*/ +{ + void* arg2; + + arg2 = arg; + + printf("Thread_xrw started!\n"); + + mutex_enter(&mutex9); + printf("Thread_xrw9 has now mutex9, wait for rw9!\n"); + + rw_lock_x_lock(&rw9); + + return(0); +} + +void +test9(void) +/*=======*/ +{ + os_thread_t thr1, thr2; + os_thread_id_t id1, id2; + + printf("-------------------------------------------\n"); + printf("SYNC-TEST 9. Test of deadlock detection.\n"); + + + printf("Main thread %ld starts!\n", + os_thread_get_curr_id()); + + rw_lock_create(&rw9); + rw_lock_create(&rw10); + mutex_create(&mutex9); + + rw_lock_s_lock(&rw9); + printf("Main thread has now s-lock on rw9\n"); + + thr2 = os_thread_create(thread_xrw9, + NULL, + &id2); + + printf("Thread_xrw9 created, id %ld \n", id2); + + os_thread_sleep(1000000); + + thr1 = os_thread_create(thread_srw9, + NULL, + &id1); + + printf("Thread_srw9 created, id %ld \n", id1); + + os_thread_sleep(1000000); + + sync_array_print_info(sync_primary_wait_array); + + printf("Now we should have a deadlock of 3 threads:\n"); + + rw_lock_s_lock(&rw10); +} + +void +test10(void) +/*=======*/ +{ + printf("-------------------------------------------\n"); + printf("SYNC-TEST 10. Test of deadlock detection on self-deadlock.\n"); + + + printf("Main thread %ld starts!\n", + os_thread_get_curr_id()); + + mutex_create(&mutex9); + + printf("Now we should have a deadlock of this thread on mutex:\n"); + + mutex_enter(&mutex9); + mutex_enter(&mutex9); +} + +void +test11(void) +/*=======*/ +{ + printf("-------------------------------------------\n"); + printf("SYNC-TEST 11. Test of deadlock detection on self-deadlock.\n"); + + + printf("Main thread %ld starts!\n", + os_thread_get_curr_id()); + + rw_lock_create(&rw9); + + printf("Now we should have a deadlock of this thread on X-lock:\n"); + + rw_lock_x_lock(&rw9); + rw_lock_s_lock_gen(&rw9, 567); +} + + +/************************************************************************ +Main test function. */ + +void +main(void) +/*======*/ +{ + ulint tm, oldtm; + + sync_init(); + mem_init(); + + oldtm = ut_clock(); + + test1(); + + test2(); + + test3(); + + test4(); + + test5(); + + test6(); + + test7(); + + test8(); + + /* This test SHOULD result in assert on deadlock! */ +/* test9();*/ + + /* This test SHOULD result in assert on deadlock! */ +/* test10();*/ + + /* This test SHOULD result in assert on deadlock! */ +/* test11();*/ + + ut_ad(0 == mutex_n_reserved()); + ut_ad(0 == rw_lock_n_locked()); + ut_ad(sync_all_freed()); + + + ut_ad(mem_all_freed()); + + sync_close(); + + tm = ut_clock(); + printf("Wall clock time for test %ld milliseconds\n", tm - oldtm); + printf("System call count %lu\n", mutex_system_call_count); + printf("TESTS COMPLETED SUCCESSFULLY!\n"); +} + + |