diff options
Diffstat (limited to 'innobase/os/ts/tsos.c')
-rw-r--r-- | innobase/os/ts/tsos.c | 793 |
1 files changed, 793 insertions, 0 deletions
diff --git a/innobase/os/ts/tsos.c b/innobase/os/ts/tsos.c new file mode 100644 index 00000000000..ecc10b86d2f --- /dev/null +++ b/innobase/os/ts/tsos.c @@ -0,0 +1,793 @@ +/************************************************************************ +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"); +} + |