mariadb/innobase/os/ts/tsos.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

793 lines
14 KiB
C

/************************************************************************
The test module for the operating system interface
(c) 1995 Innobase Oy
Created 9/27/1995 Heikki Tuuri
*************************************************************************/
#include "../os0thread.h"
#include "../os0shm.h"
#include "../os0proc.h"
#include "../os0sync.h"
#include "../os0file.h"
#include "ut0ut.h"
#include "ut0mem.h"
#include "sync0sync.h"
#include "mem0mem.h"
#define _WIN32_WINNT 0x0400
#include "n:\program files\devstudio\vc\include\windows.h"
#include "n:\program files\devstudio\vc\include\winbase.h"
ulint last_thr = 1;
byte global_buf[4000000];
ulint* cache_buf;
os_file_t file;
os_file_t file2;
os_event_t gl_ready;
mutex_t ios_mutex;
ulint ios;
ulint rnd = 9837497;
/********************************************************************
Start function for threads in test1. */
ulint
thread(void* arg)
/*==============*/
{
ulint i;
void* arg2;
ulint count = 0;
ulint n;
ulint rnd_loc;
byte local_buf[2000];
arg2 = arg;
n = *((ulint*)arg);
/* printf("Thread %lu started!\n", n); */
for (i = 0; i < 8000; i++) {
rnd_loc = rnd;
rnd += 763482469;
ut_memcpy(global_buf + (rnd_loc % 1500000) + 8200, local_buf,
2000);
if (last_thr != n) {
count++;
last_thr = n;
}
if (i % 32 == 0) {
os_thread_yield();
}
}
printf("Thread %lu exits: %lu thread switches noticed\n", n, count);
return(0);
}
/*********************************************************************
Test of the speed of wait for multiple events. */
void
testa1(void)
/*========*/
{
ulint i;
os_event_t arr[64];
ulint tm, oldtm;
printf("-------------------------------------------------\n");
printf("TEST A1. Speed of waits\n");
for (i = 0; i < 64; i++) {
arr[i] = os_event_create(NULL);
ut_a(arr[i]);
}
os_event_set(arr[1]);
oldtm = ut_clock();
for (i = 0; i < 10000; i++) {
os_event_wait_multiple(4, arr);
}
tm = ut_clock();
printf("Wall clock time for %lu multiple waits %lu millisecs\n",
i, tm - oldtm);
oldtm = ut_clock();
for (i = 0; i < 10000; i++) {
os_event_wait(arr[1]);
}
tm = ut_clock();
printf("Wall clock time for %lu single waits %lu millisecs\n",
i, tm - oldtm);
for (i = 0; i < 64; i++) {
os_event_free(arr[i]);
}
}
/*********************************************************************
Test for threads. */
void
test1(void)
/*=======*/
{
os_thread_t thr[64];
os_thread_id_t id[64];
ulint n[64];
ulint tm, oldtm;
ulint i, j;
printf("-------------------------------------------\n");
printf("OS-TEST 1. Test of thread switching through yield\n");
printf("Main thread %lu starts!\n", os_thread_get_curr_id());
for (j = 0; j < 2; j++) {
oldtm = ut_clock();
for (i = 0; i < 64; i++) {
n[i] = i;
thr[i] = os_thread_create(thread, n + i, id + i);
/* printf("Thread %lu created, id %lu \n", i, id[i]); */
}
for (i = 0; i < 64; i++) {
os_thread_wait(thr[i]);
}
tm = ut_clock();
printf("Wall clock time for test %lu milliseconds\n", tm - oldtm);
oldtm = ut_clock();
for (i = 0; i < 64; i++) {
thr[5] = os_thread_create(thread, n + 5, id + 5);
/* printf("Thread created, id %lu \n", id[5]); */
os_thread_wait(thr[5]);
}
tm = ut_clock();
printf("Wall clock time for single thread test %lu milliseconds\n",
tm - oldtm);
}
}
/*********************************************************************
Test for shared memory and process switching through yield. */
void
test2(void)
/*=======*/
{
os_shm_t shm;
ulint tm, oldtm;
ulint* pr_no;
ulint count;
ulint i;
bool ret;
os_process_t proc;
os_process_id_t proc_id;
printf("-------------------------------------------\n");
printf("OS-TEST 2. Test of process switching through yield\n");
shm = os_shm_create(1000, "TSOS_SHM");
pr_no = os_shm_map(shm);
*pr_no = 1;
count = 0;
ret = os_process_create("tsosaux.exe", NULL, &proc, &proc_id);
printf("Last error: %lu\n", os_thread_get_last_error());
ut_a(ret);
printf("Process 1 starts test!\n");
oldtm = ut_clock();
for (i = 0; i < 500000; i++) {
if (*pr_no != 1) {
count++;
*pr_no = 1;
}
os_thread_yield();
}
tm = ut_clock();
printf("Process 1 finishes test: %lu process switches noticed\n",
count);
printf("Wall clock time for test %lu milliseconds\n", tm - oldtm);
os_shm_unmap(shm);
os_shm_free(shm);
}
#ifdef notdefined
/*********************************************************************
Test for asynchronous file io. */
void
test3(void)
/*=======*/
{
ulint i;
ulint j;
void* mess;
bool ret;
void* buf;
ulint rnd;
ulint addr[64];
ulint serv[64];
ulint tm, oldtm;
printf("-------------------------------------------\n");
printf("OS-TEST 3. Test of asynchronous file io\n");
/* Align the buffer for file io */
buf = (void*)(((ulint)global_buf + 6300) & (~0xFFF));
rnd = ut_time();
rnd = rnd * 3416133;
printf("rnd seed %lu\n", rnd % 4900);
oldtm = ut_clock();
for (i = 0; i < 32; i++) {
ret = os_aio_read(file, buf, 8192 * (rnd % 4900), 0,
8192, (void*)i);
ut_a(ret);
rnd += 1;
ret = os_aio_wait(0, &mess);
ut_a(ret);
}
tm = ut_clock();
printf("Wall clock time for synchr. io %lu milliseconds\n",
tm - oldtm);
rnd = rnd * 3416133;
printf("rnd seed %lu\n", rnd % 5000);
oldtm = ut_clock();
for (j = 0; j < 5; j++) {
rnd = rnd + 3416133;
for (i = 0; i < 16; i++) {
ret = os_aio_read(file, buf, 8192 * (rnd % 5000), 0, 8192,
(void*)i);
addr[i] = rnd % 5000;
ut_a(ret);
rnd += 1;
}
for (i = 0; i < 16; i++) {
ret = os_aio_read(file, buf, 8192 * (rnd % 5000), 0, 8192,
(void*)i);
addr[i] = rnd % 5000;
ut_a(ret);
rnd += 1;
}
rnd = rnd + 3416133;
for (i = 0; i < 32; i++) {
ret = os_aio_wait(0, &mess);
ut_a(ret);
ut_a((ulint)mess < 64);
serv[(ulint)mess] = i;
}
}
tm = ut_clock();
printf("Wall clock time for aio %lu milliseconds\n", tm - oldtm);
rnd = rnd * 3416133;
printf("rnd seed %lu\n", rnd % 4900);
oldtm = ut_clock();
for (j = 0; j < 5; j++) {
rnd = rnd + 3416133;
for (i = 0; i < 1; i++) {
ret = os_aio_read(file, buf, 8192 * (rnd % 4900), 0,
64 * 8192, (void*)i);
ut_a(ret);
rnd += 4;
ret = os_aio_wait(0, &mess);
ut_a(ret);
ut_a((ulint)mess < 64);
}
}
tm = ut_clock();
printf("Wall clock time for synchr. io %lu milliseconds\n",
tm - oldtm);
/*
for (i = 0; i < 63; i++) {
printf("read %lu addr %lu served as %lu\n",
i, addr[i], serv[i]);
}
*/
ut_a(ret);
}
/************************************************************************
Io-handler thread function. */
ulint
handler_thread(
/*===========*/
void* arg)
{
ulint segment;
void* mess;
ulint i;
bool ret;
segment = *((ulint*)arg);
printf("Thread %lu starts\n", segment);
for (i = 0;; i++) {
ret = os_aio_wait(segment, &mess);
mutex_enter(&ios_mutex);
ios++;
mutex_exit(&ios_mutex);
ut_a(ret);
/* printf("Message for thread %lu %lu\n", segment,
(ulint)mess); */
if ((ulint)mess == 3333) {
os_event_set(gl_ready);
}
}
return(0);
}
/************************************************************************
Test of io-handler threads */
void
test4(void)
/*=======*/
{
ulint i;
ulint j;
bool ret;
void* buf;
ulint rnd;
ulint tm, oldtm;
os_thread_t thr[5];
os_thread_id_t id[5];
ulint n[5];
printf("-------------------------------------------\n");
printf("OS-TEST 4. Test of asynchronous file io\n");
/* Align the buffer for file io */
buf = (void*)(((ulint)global_buf + 6300) & (~0xFFF));
gl_ready = os_event_create(NULL);
ios = 0;
sync_init();
mem_init();
mutex_create(&ios_mutex);
for (i = 0; i < 5; i++) {
n[i] = i;
thr[i] = os_thread_create(handler_thread, n + i, id + i);
}
rnd = 0;
oldtm = ut_clock();
for (j = 0; j < 128; j++) {
for (i = 0; i < 32; i++) {
ret = os_aio_read(file, (byte*)buf + 8192 * (rnd % 100),
8192 * (rnd % 4096), 0,
8192, (void*)i);
ut_a(ret);
rnd += 1;
}
/*
rnd += 67475941;
for (i = 0; i < 1; i++) {
ret = os_aio_read(file2, buf, 8192 * (rnd % 5000), 0,
8192, (void*)i);
ut_a(ret);
rnd += 1;
}
*/
}
ret = os_aio_read(file, buf, 8192 * (rnd % 4096), 0, 8192,
(void*)3333);
ut_a(ret);
ut_a(!os_aio_all_slots_free());
/*
printf("Starting flush!\n");
ret = os_file_flush(file);
ut_a(ret);
printf("Ending flush!\n");
*/
tm = ut_clock();
printf("All ios queued! N ios: %lu\n", ios);
printf("Wall clock time for test %lu milliseconds\n", tm - oldtm);
os_event_wait(gl_ready);
tm = ut_clock();
printf("N ios: %lu\n", ios);
printf("Wall clock time for test %lu milliseconds\n", tm - oldtm);
os_thread_sleep(2000000);
printf("N ios: %lu\n", ios);
ut_a(os_aio_all_slots_free());
}
/*************************************************************************
Initializes the asyncronous io system for tests. */
void
init_aio(void)
/*==========*/
{
bool ret;
ulint i;
void* buf;
void* mess;
buf = (void*)(((ulint)global_buf + 6300) & (~0xFFF));
os_aio_init(160, 5);
file = os_file_create("j:\\tsfile2", OS_FILE_CREATE, OS_FILE_TABLESPACE,
&ret);
if (ret == FALSE) {
ut_a(os_file_get_last_error() == OS_FILE_ALREADY_EXISTS);
file = os_file_create("j:\\tsfile2", OS_FILE_OPEN,
OS_FILE_TABLESPACE, &ret);
ut_a(ret);
} else {
for (i = 0; i < 4100; i++) {
ret = os_aio_write(file, buf, 8192 * i, 0, 8192, NULL);
ut_a(ret);
ret = os_aio_wait(0, &mess);
ut_a(ret);
ut_a(mess == NULL);
}
}
file2 = os_file_create("F:\\tmp\\tsfile", OS_FILE_CREATE,
OS_FILE_TABLESPACE,
&ret);
if (ret == FALSE) {
ut_a(os_file_get_last_error() == OS_FILE_ALREADY_EXISTS);
file2 = os_file_create("F:\\tmp\\tsfile", OS_FILE_OPEN,
OS_FILE_TABLESPACE, &ret);
ut_a(ret);
} else {
for (i = 0; i < 5000; i++) {
ret = os_aio_write(file2, buf, 8192 * i, 0, 8192, NULL);
ut_a(ret);
ret = os_aio_wait(0, &mess);
ut_a(ret);
ut_a(mess == NULL);
}
}
}
/************************************************************************
Test of synchronous io */
void
test5(void)
/*=======*/
{
ulint i, j, k;
bool ret;
void* buf;
ulint rnd = 0;
ulint tm = 0;
ulint oldtm = 0;
os_file_t files[1000];
char name[5];
ulint err;
printf("-------------------------------------------\n");
printf("OS-TEST 5. Test of creating and opening of many files\n");
/* Align the buffer for file io */
buf = (void*)(((ulint)global_buf + 6300) & (~0xFFF));
name[2] = '.';
name[3] = 'd';
name[4] = '\0';
oldtm = ut_clock();
for (j = 0; j < 20; j++) {
for (i = 0; i < 20; i++) {
name[0] = (char)(i + (ulint)'A');
name[1] = (char)(j + (ulint)'A');
files[j * 20 + i] = os_file_create(name, OS_FILE_CREATE,
OS_FILE_NORMAL, &ret);
if (!ret) {
err = os_file_get_last_error();
}
ut_a(ret);
}
}
for (k = 0; k < i * j; k++) {
ret = os_file_close(files[k]);
ut_a(ret);
}
for (j = 0; j < 20; j++) {
for (i = 0; i < 20; i++) {
name[0] = (char)(i + (ulint)'A');
name[1] = (char)(j + (ulint)'A');
ret = os_file_delete(name);
ut_a(ret);
}
}
tm = ut_clock();
printf("Wall clock time for test %lu milliseconds\n", tm - oldtm);
}
/************************************************************************
Test of synchronous io */
void
test6(void)
/*=======*/
{
ulint i, j;
bool ret;
void* buf;
ulint rnd = 0;
ulint tm = 0;
ulint oldtm = 0;
os_file_t s_file;
printf("-------------------------------------------\n");
printf("OS-TEST 6. Test of synchronous io\n");
buf = (void*)(((ulint)global_buf + 6300) & (~0xFFF));
ret = os_file_close(file);
ut_a(ret);
ret = os_file_close(file2);
ut_a(ret);
s_file = os_file_create("tsfile", OS_FILE_OPEN,
OS_FILE_NORMAL, &ret);
if (!ret) {
printf("Error no %lu\n", os_file_get_last_error());
}
ut_a(ret);
rnd = ut_time() * 6346353;
oldtm = ut_clock();
for (j = 0; j < 100; j++) {
rnd += 8072791;
for (i = 0; i < 32; i++) {
ret = os_file_read(s_file, buf, 8192 * (rnd % 5000), 0,
8192);
ut_a(ret);
rnd += 1;
}
}
tm = ut_clock();
printf("Wall clock time for test %lu milliseconds\n", tm - oldtm);
}
/************************************************************************
Test of file size operations. */
void
test7(void)
/*=======*/
{
bool ret;
os_file_t f;
ulint len;
ulint high;
printf("-------------------------------------------\n");
printf("OS-TEST 7. Test of setting and getting file size\n");
f = os_file_create("sizefile", OS_FILE_CREATE, OS_FILE_TABLESPACE,
&ret);
ut_a(ret);
ret = os_file_get_size(f, &len, &high);
ut_a(ret);
ut_a(len == 0);
ut_a(high == 0);
ret = os_file_set_size(f, 5000000, 0);
ut_a(ret);
ret = os_file_get_size(f, &len, &high);
ut_a(ret);
ut_a(len == 5000000);
ut_a(high == 0);
ret = os_file_set_size(f, 4000000, 0);
ut_a(ret);
ret = os_file_get_size(f, &len, &high);
ut_a(ret);
ut_a(len == 4000000);
ut_a(high == 0);
ret = os_file_close(f);
ut_a(ret);
ret = os_file_delete("sizefile");
ut_a(ret);
}
#endif
/************************************************************************
Main test function. */
void
main(void)
/*======*/
{
ulint tm, oldtm;
ulint i;
CRITICAL_SECTION cs;
ulint sum;
ulint rnd;
cache_buf = VirtualAlloc(NULL, 4 * 1024, MEM_COMMIT,
PAGE_READWRITE /* | PAGE_NOCACHE */);
oldtm = ut_clock();
sum = 0;
rnd = 0;
for (i = 0; i < 1000000; i++) {
sum += cache_buf[rnd * (16)];
rnd += 1;
if (rnd > 7) {
rnd = 0;
}
}
tm = ut_clock();
printf("Wall clock time for cache test %lu milliseconds\n", tm - oldtm);
InterlockedExchange(&i, 5);
InitializeCriticalSection(&cs);
oldtm = ut_clock();
for (i = 0; i < 10000000; i++) {
TryEnterCriticalSection(&cs);
LeaveCriticalSection(&cs);
}
tm = ut_clock();
printf("Wall clock time for test %lu milliseconds\n", tm - oldtm);
testa1();
test1();
/* test2(); */
/* init_aio(); */
/*
test3();
*/
/* test4();
test5();
test6();
test7(); */
printf("TESTS COMPLETED SUCCESSFULLY!\n");
}