#include "myisam.h"#include <sys/types.h>Include dependency graph for mi_test3.c:

Go to the source code of this file.
Classes | |
| struct | record |
Defines | |
| #define | WEXITSTATUS(stat_val) ((unsigned)(stat_val) >> 8) |
| #define | WIFEXITED(stat_val) (((stat_val) & 255) == 0) |
| #define | rnd(X) (random() % X) |
| #define | rnd_init(X) srandom(X) |
Functions | |
| static void | get_options (int argc, char *argv[]) |
| void | start_test (int id) |
| int | test_read (MI_INFO *, int) |
| int | test_write (MI_INFO *, int, int) |
| int | test_update (MI_INFO *, int, int) |
| int | test_rrnd (MI_INFO *, int) |
| int | main (int argc, char **argv) |
| static void | get_options (int argc, char **argv) |
Variables | |
| const char * | filename = "test3" |
| uint | tests = 10 |
| uint | forks = 10 |
| uint | key_cacheing = 0 |
| uint | use_log = 0 |
| #define rnd | ( | X | ) | (random() % X) |
Definition at line 38 of file mi_test3.c.
Referenced by do_test(), main(), mem_field_init(), Dbtup::nr_delete(), page_cur_open_on_rnd_user_rec(), put_blob_in_record(), start_test(), test_read(), test_rrnd(), test_update(), and test_write().
| #define rnd_init | ( | X | ) | srandom(X) |
| #define WEXITSTATUS | ( | stat_val | ) | ((unsigned)(stat_val) >> 8) |
Definition at line 27 of file mi_test3.c.
| #define WIFEXITED | ( | stat_val | ) | (((stat_val) & 255) == 0) |
| static void get_options | ( | int | argc, | |
| char ** | argv | |||
| ) | [static] |
Definition at line 122 of file mi_test3.c.
References atoi(), DBUG_PUSH, exit, forks, key_cacheing, MACHINE_TYPE, pos(), progname, SYSTEM_TYPE, tests, and use_log.
00123 { 00124 char *pos,*progname; 00125 00126 progname= argv[0]; 00127 00128 while (--argc >0 && *(pos = *(++argv)) == '-' ) { 00129 switch(*++pos) { 00130 case 'l': 00131 use_log=1; 00132 break; 00133 case 'f': 00134 forks=atoi(++pos); 00135 break; 00136 case 't': 00137 tests=atoi(++pos); 00138 break; 00139 case 'K': /* Use key cacheing */ 00140 key_cacheing=1; 00141 break; 00142 case 'A': /* All flags */ 00143 use_log=key_cacheing=1; 00144 break; 00145 case '?': 00146 case 'I': 00147 case 'V': 00148 printf("%s Ver 1.0 for %s at %s\n",progname,SYSTEM_TYPE,MACHINE_TYPE); 00149 puts("By Monty, for your professional use\n"); 00150 puts("Test av locking with threads\n"); 00151 printf("Usage: %s [-?lKA] [-f#] [-t#]\n",progname); 00152 exit(0); 00153 case '#': 00154 DBUG_PUSH (++pos); 00155 break; 00156 default: 00157 printf("Illegal option: '%c'\n",*pos); 00158 break; 00159 } 00160 } 00161 return; 00162 }
Here is the call graph for this function:

| static void get_options | ( | int | argc, | |
| char * | argv[] | |||
| ) | [static] |
| int main | ( | int | argc, | |
| char ** | argv | |||
| ) |
Definition at line 58 of file mi_test3.c.
References bzero, exit, filename, forks, get_options(), HA_KEY_ALG_BTREE, HA_KEYTYPE_LONG_INT, HA_KEYTYPE_TEXT, HA_NOSAME, HA_PACK_KEY, HA_SPACE_PACK, keyinfo, keyseg, mi_create(), my_delete(), MY_INIT, MYF, recinfo, rnd, rnd_init, sleep, start_test(), status, and VOID.
00059 { 00060 int status,wait_ret; 00061 uint i=0; 00062 MI_KEYDEF keyinfo[10]; 00063 MI_COLUMNDEF recinfo[10]; 00064 HA_KEYSEG keyseg[10][2]; 00065 MY_INIT(argv[0]); 00066 get_options(argc,argv); 00067 00068 bzero((char*) keyinfo,sizeof(keyinfo)); 00069 bzero((char*) recinfo,sizeof(recinfo)); 00070 bzero((char*) keyseg,sizeof(keyseg)); 00071 keyinfo[0].seg= &keyseg[0][0]; 00072 keyinfo[0].seg[0].start=0; 00073 keyinfo[0].seg[0].length=8; 00074 keyinfo[0].seg[0].type=HA_KEYTYPE_TEXT; 00075 keyinfo[0].seg[0].flag=HA_SPACE_PACK; 00076 keyinfo[0].key_alg=HA_KEY_ALG_BTREE; 00077 keyinfo[0].keysegs=1; 00078 keyinfo[0].flag = (uint8) HA_PACK_KEY; 00079 keyinfo[0].block_length= 0; /* Default block length */ 00080 keyinfo[1].seg= &keyseg[1][0]; 00081 keyinfo[1].seg[0].start=8; 00082 keyinfo[1].seg[0].length=4; /* Long is always 4 in myisam */ 00083 keyinfo[1].seg[0].type=HA_KEYTYPE_LONG_INT; 00084 keyinfo[1].seg[0].flag=0; 00085 keyinfo[1].key_alg=HA_KEY_ALG_BTREE; 00086 keyinfo[1].keysegs=1; 00087 keyinfo[1].flag =HA_NOSAME; 00088 keyinfo[1].block_length= 0; /* Default block length */ 00089 00090 recinfo[0].type=0; 00091 recinfo[0].length=sizeof(record.id); 00092 recinfo[1].type=0; 00093 recinfo[1].length=sizeof(record.nr); 00094 recinfo[2].type=0; 00095 recinfo[2].length=sizeof(record.text); 00096 00097 puts("- Creating myisam-file"); 00098 my_delete(filename,MYF(0)); /* Remove old locks under gdb */ 00099 if (mi_create(filename,2,&keyinfo[0],2,&recinfo[0],0,(MI_UNIQUEDEF*) 0, 00100 (MI_CREATE_INFO*) 0,0)) 00101 exit(1); 00102 00103 rnd_init(0); 00104 printf("- Starting %d processes\n",forks); fflush(stdout); 00105 for (i=0 ; i < forks; i++) 00106 { 00107 if (!fork()) 00108 { 00109 start_test(i+1); 00110 sleep(1); 00111 return 0; 00112 } 00113 VOID(rnd(1)); 00114 } 00115 00116 for (i=0 ; i < forks ; i++) 00117 while ((wait_ret=wait(&status)) && wait_ret == -1); 00118 return 0; 00119 }
Here is the call graph for this function:

| void start_test | ( | int | id | ) |
Definition at line 165 of file mi_test3.c.
References st_mi_isaminfo::deleted, dflt_key_cache, error, exit, F_RDLCK, F_UNLCK, F_WRLCK, filename, HA_OPEN_WAIT_IF_LOCKED, HA_STATUS_VARIABLE, init_key_cache(), KEY_CACHE_BLOCK_SIZE, key_cacheing, lock, mi_close(), mi_lock_database(), mi_log(), mi_open(), mi_status(), my_errno, st_mi_isaminfo::records, rnd, test_read(), test_rrnd(), test_update(), test_write(), tests, and use_log.
Referenced by main().
00166 { 00167 uint i; 00168 int error,lock_type; 00169 MI_ISAMINFO isam_info; 00170 MI_INFO *file,*file1,*file2=0,*lock; 00171 00172 if (use_log) 00173 mi_log(1); 00174 if (!(file1=mi_open(filename,O_RDWR,HA_OPEN_WAIT_IF_LOCKED)) || 00175 !(file2=mi_open(filename,O_RDWR,HA_OPEN_WAIT_IF_LOCKED))) 00176 { 00177 fprintf(stderr,"Can't open isam-file: %s\n",filename); 00178 exit(1); 00179 } 00180 if (key_cacheing && rnd(2) == 0) 00181 init_key_cache(dflt_key_cache, KEY_CACHE_BLOCK_SIZE, 65536L, 0, 0); 00182 printf("Process %d, pid: %d\n",id,getpid()); fflush(stdout); 00183 00184 for (error=i=0 ; i < tests && !error; i++) 00185 { 00186 file= (rnd(2) == 1) ? file1 : file2; 00187 lock=0 ; lock_type=0; 00188 if (rnd(10) == 0) 00189 { 00190 if (mi_lock_database(lock=(rnd(2) ? file1 : file2), 00191 lock_type=(rnd(2) == 0 ? F_RDLCK : F_WRLCK))) 00192 { 00193 fprintf(stderr,"%2d: start: Can't lock table %d\n",id,my_errno); 00194 error=1; 00195 break; 00196 } 00197 } 00198 switch (rnd(4)) { 00199 case 0: error=test_read(file,id); break; 00200 case 1: error=test_rrnd(file,id); break; 00201 case 2: error=test_write(file,id,lock_type); break; 00202 case 3: error=test_update(file,id,lock_type); break; 00203 } 00204 if (lock) 00205 mi_lock_database(lock,F_UNLCK); 00206 } 00207 if (!error) 00208 { 00209 mi_status(file1,&isam_info,HA_STATUS_VARIABLE); 00210 printf("%2d: End of test. Records: %ld Deleted: %ld\n", 00211 id,(long) isam_info.records, (long) isam_info.deleted); 00212 fflush(stdout); 00213 } 00214 00215 mi_close(file1); 00216 mi_close(file2); 00217 if (use_log) 00218 mi_log(0); 00219 if (error) 00220 { 00221 printf("%2d: Aborted\n",id); fflush(stdout); 00222 exit(1); 00223 } 00224 }
Here is the call graph for this function:

Here is the caller graph for this function:

| int test_read | ( | MI_INFO * | file, | |
| int | id | |||
| ) |
Definition at line 227 of file mi_test3.c.
References F_RDLCK, find(), HA_ERR_END_OF_FILE, HA_ERR_KEY_NOT_FOUND, HA_READ_KEY_EXACT, lock, mi_lock_database(), mi_rkey(), mi_rnext(), mi_rprev(), my_errno, and rnd.
Referenced by start_test().
00228 { 00229 uint i,lock,found,next,prev; 00230 ulong find; 00231 00232 lock=0; 00233 if (rnd(2) == 0) 00234 { 00235 lock=1; 00236 if (mi_lock_database(file,F_RDLCK)) 00237 { 00238 fprintf(stderr,"%2d: Can't lock table %d\n",id,my_errno); 00239 return 1; 00240 } 00241 } 00242 00243 found=next=prev=0; 00244 for (i=0 ; i < 100 ; i++) 00245 { 00246 find=rnd(100000); 00247 if (!mi_rkey(file,record.id,1,(byte*) &find, 00248 sizeof(find),HA_READ_KEY_EXACT)) 00249 found++; 00250 else 00251 { 00252 if (my_errno != HA_ERR_KEY_NOT_FOUND) 00253 { 00254 fprintf(stderr,"%2d: Got error %d from read in read\n",id,my_errno); 00255 return 1; 00256 } 00257 else if (!mi_rnext(file,record.id,1)) 00258 next++; 00259 else 00260 { 00261 if (my_errno != HA_ERR_END_OF_FILE) 00262 { 00263 fprintf(stderr,"%2d: Got error %d from rnext in read\n",id,my_errno); 00264 return 1; 00265 } 00266 else if (!mi_rprev(file,record.id,1)) 00267 prev++; 00268 else 00269 { 00270 if (my_errno != HA_ERR_END_OF_FILE) 00271 { 00272 fprintf(stderr,"%2d: Got error %d from rnext in read\n", 00273 id,my_errno); 00274 return 1; 00275 } 00276 } 00277 } 00278 } 00279 } 00280 if (lock) 00281 { 00282 if (mi_lock_database(file,F_UNLCK)) 00283 { 00284 fprintf(stderr,"%2d: Can't unlock table\n",id); 00285 return 1; 00286 } 00287 } 00288 printf("%2d: read: found: %5d next: %5d prev: %5d\n", 00289 id,found,next,prev); 00290 fflush(stdout); 00291 return 0; 00292 }
Here is the call graph for this function:

Here is the caller graph for this function:

| int test_rrnd | ( | MI_INFO * | , | |
| int | ||||
| ) |
Definition at line 295 of file mi_test3.c.
References count, exit, F_RDLCK, F_UNLCK, HA_ERR_END_OF_FILE, HA_EXTRA_CACHE, HA_EXTRA_NO_CACHE, HA_OFFSET_ERROR, lock, mi_close(), mi_extra(), mi_lock_database(), mi_rrnd(), my_errno, and rnd.
Referenced by start_test().
00296 { 00297 uint count,lock; 00298 00299 lock=0; 00300 if (rnd(2) == 0) 00301 { 00302 lock=1; 00303 if (mi_lock_database(file,F_RDLCK)) 00304 { 00305 fprintf(stderr,"%2d: Can't lock table (%d)\n",id,my_errno); 00306 mi_close(file); 00307 return 1; 00308 } 00309 if (rnd(2) == 0) 00310 mi_extra(file,HA_EXTRA_CACHE,0); 00311 } 00312 00313 count=0; 00314 if (mi_rrnd(file,record.id,0L)) 00315 { 00316 if (my_errno == HA_ERR_END_OF_FILE) 00317 goto end; 00318 fprintf(stderr,"%2d: Can't read first record (%d)\n",id,my_errno); 00319 return 1; 00320 } 00321 for (count=1 ; !mi_rrnd(file,record.id,HA_OFFSET_ERROR) ;count++) ; 00322 if (my_errno != HA_ERR_END_OF_FILE) 00323 { 00324 fprintf(stderr,"%2d: Got error %d from rrnd\n",id,my_errno); 00325 return 1; 00326 } 00327 00328 end: 00329 if (lock) 00330 { 00331 mi_extra(file,HA_EXTRA_NO_CACHE,0); 00332 if (mi_lock_database(file,F_UNLCK)) 00333 { 00334 fprintf(stderr,"%2d: Can't unlock table\n",id); 00335 exit(0); 00336 } 00337 } 00338 printf("%2d: rrnd: %5d\n",id,count); fflush(stdout); 00339 return 0; 00340 }
Here is the call graph for this function:

Here is the caller graph for this function:

| int test_update | ( | MI_INFO * | file, | |
| int | id, | |||
| int | lock_type | |||
| ) |
Definition at line 400 of file mi_test3.c.
References bzero, F_RDLCK, F_UNLCK, F_WRLCK, find(), HA_ERR_END_OF_FILE, HA_ERR_FOUND_DUPP_KEY, HA_ERR_KEY_NOT_FOUND, HA_ERR_RECORD_CHANGED, HA_ERR_RECORD_DELETED, HA_READ_KEY_EXACT, int4store, lock, memcpy_fixed, mi_lock_database(), mi_rkey(), mi_rnext(), mi_rprev(), mi_update(), my_errno, rnd, strmov(), and update.
Referenced by start_test().
00401 { 00402 uint i,lock,found,next,prev,update; 00403 uint32 tmp; 00404 char find[4]; 00405 struct record new_record; 00406 00407 lock=0; 00408 if (rnd(2) == 0 || lock_type == F_RDLCK) 00409 { 00410 lock=1; 00411 if (mi_lock_database(file,F_WRLCK)) 00412 { 00413 if (lock_type == F_RDLCK && my_errno == EDEADLK) 00414 { 00415 printf("%2d: write: deadlock\n",id); fflush(stdout); 00416 return 0; 00417 } 00418 fprintf(stderr,"%2d: Can't lock table (%d)\n",id,my_errno); 00419 return 1; 00420 } 00421 } 00422 bzero((char*) &new_record,sizeof(new_record)); 00423 strmov(new_record.text,"Updated"); 00424 00425 found=next=prev=update=0; 00426 for (i=0 ; i < 100 ; i++) 00427 { 00428 tmp=rnd(100000); 00429 int4store(find,tmp); 00430 if (!mi_rkey(file,record.id,1,(byte*) find, 00431 sizeof(find),HA_READ_KEY_EXACT)) 00432 found++; 00433 else 00434 { 00435 if (my_errno != HA_ERR_KEY_NOT_FOUND) 00436 { 00437 fprintf(stderr,"%2d: Got error %d from read in update\n",id,my_errno); 00438 return 1; 00439 } 00440 else if (!mi_rnext(file,record.id,1)) 00441 next++; 00442 else 00443 { 00444 if (my_errno != HA_ERR_END_OF_FILE) 00445 { 00446 fprintf(stderr,"%2d: Got error %d from rnext in update\n", 00447 id,my_errno); 00448 return 1; 00449 } 00450 else if (!mi_rprev(file,record.id,1)) 00451 prev++; 00452 else 00453 { 00454 if (my_errno != HA_ERR_END_OF_FILE) 00455 { 00456 fprintf(stderr,"%2d: Got error %d from rnext in update\n", 00457 id,my_errno); 00458 return 1; 00459 } 00460 continue; 00461 } 00462 } 00463 } 00464 memcpy_fixed(new_record.id,record.id,sizeof(record.id)); 00465 tmp=rnd(20000)+40000; 00466 int4store(new_record.nr,tmp); 00467 if (!mi_update(file,record.id,new_record.id)) 00468 update++; 00469 else 00470 { 00471 if (my_errno != HA_ERR_RECORD_CHANGED && 00472 my_errno != HA_ERR_RECORD_DELETED && 00473 my_errno != HA_ERR_FOUND_DUPP_KEY) 00474 { 00475 fprintf(stderr,"%2d: Got error %d from update\n",id,my_errno); 00476 return 1; 00477 } 00478 } 00479 } 00480 if (lock) 00481 { 00482 if (mi_lock_database(file,F_UNLCK)) 00483 { 00484 fprintf(stderr,"Can't unlock table,id, error%d\n",my_errno); 00485 return 1; 00486 } 00487 } 00488 printf("%2d: update: %5d\n",id,update); fflush(stdout); 00489 return 0; 00490 }
Here is the call graph for this function:

Here is the caller graph for this function:

| int test_write | ( | MI_INFO * | file, | |
| int | id, | |||
| int | lock_type | |||
| ) |
Definition at line 343 of file mi_test3.c.
References count, errno, exit, F_RDLCK, F_UNLCK, F_WRLCK, HA_ERR_FOUND_DUPP_KEY, HA_EXTRA_NO_CACHE, HA_EXTRA_WRITE_CACHE, int4store, lock, mi_close(), mi_extra(), mi_lock_database(), mi_write(), my_errno, rnd, and strnmov().
Referenced by start_test().
00344 { 00345 uint i,tries,count,lock; 00346 00347 lock=0; 00348 if (rnd(2) == 0 || lock_type == F_RDLCK) 00349 { 00350 lock=1; 00351 if (mi_lock_database(file,F_WRLCK)) 00352 { 00353 if (lock_type == F_RDLCK && my_errno == EDEADLK) 00354 { 00355 printf("%2d: write: deadlock\n",id); fflush(stdout); 00356 return 0; 00357 } 00358 fprintf(stderr,"%2d: Can't lock table (%d)\n",id,my_errno); 00359 mi_close(file); 00360 return 1; 00361 } 00362 if (rnd(2) == 0) 00363 mi_extra(file,HA_EXTRA_WRITE_CACHE,0); 00364 } 00365 00366 sprintf(record.id,"%7d",getpid()); 00367 strnmov(record.text,"Testing...", sizeof(record.text)); 00368 00369 tries=(uint) rnd(100)+10; 00370 for (i=count=0 ; i < tries ; i++) 00371 { 00372 uint32 tmp=rnd(80000)+20000; 00373 int4store(record.nr,tmp); 00374 if (!mi_write(file,record.id)) 00375 count++; 00376 else 00377 { 00378 if (my_errno != HA_ERR_FOUND_DUPP_KEY) 00379 { 00380 fprintf(stderr,"%2d: Got error %d (errno %d) from write\n",id,my_errno, 00381 errno); 00382 return 1; 00383 } 00384 } 00385 } 00386 if (lock) 00387 { 00388 mi_extra(file,HA_EXTRA_NO_CACHE,0); 00389 if (mi_lock_database(file,F_UNLCK)) 00390 { 00391 fprintf(stderr,"%2d: Can't unlock table\n",id); 00392 exit(0); 00393 } 00394 } 00395 printf("%2d: write: %5d\n",id,count); fflush(stdout); 00396 return 0; 00397 }
Here is the call graph for this function:

Here is the caller graph for this function:

| const char* filename = "test3" |
Definition at line 43 of file mi_test3.c.
| uint key_cacheing = 0 |
Definition at line 44 of file mi_test3.c.
Definition at line 44 of file mi_test3.c.
Referenced by get_options(), main(), start_test(), test_arg(), test_pool(), and test_strarg().
Definition at line 44 of file mi_test3.c.
1.4.7

