mariadb/innobase/sync/ts/tssync.c
unknown 2662b59306 Added Innobase to source distribution
Docs/manual.texi:
  Added Innobase documentation
configure.in:
  Incremented version
include/my_base.h:
  Added option for Innobase
myisam/mi_check.c:
  cleanup
mysql-test/t/bdb.test:
  cleanup
mysql-test/t/innobase.test:
  Extended with new tests from bdb.test
mysql-test/t/merge.test:
  Added test of SHOW create
mysys/my_init.c:
  Fix for UNIXWARE 7
scripts/mysql_install_db.sh:
  Always write how to start mysqld
scripts/safe_mysqld.sh:
  Fixed type
sql/ha_innobase.cc:
  Update to new version
sql/ha_innobase.h:
  Update to new version
sql/handler.h:
  Added 'update_table_comment()' and 'append_create_info()'
sql/sql_delete.cc:
  Fixes for Innobase
sql/sql_select.cc:
  Fixes for Innobase
sql/sql_show.cc:
  Append create information (for MERGE tables)
sql/sql_update.cc:
  Fixes for Innobase
2001-02-17 14:19:19 +02:00

1366 lines
23 KiB
C

/************************************************************************
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");
}