#include "db_config.h"
#include <sys/types.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "db_int.h"
Go to the source code of this file.
Defines | |
| #define | MAP_FAILED (void *)-1 |
| #define | MAP_FILE 0 |
| #define | MUTEX_WAKEME 0x80 |
Functions | |
| void | exec_proc () |
| int | main (int argc, argv) |
| void | run_proc () |
| void * | run_thread () |
| void * | run_thread_wake () |
| void | tm_file_init () |
| void | tm_mutex_destroy () |
| void | tm_mutex_init () |
| void | tm_mutex_stats () |
| void | unmap_file () |
Variables | |
| int | align |
| int | child |
| DB_ENV | dbenv |
| char * | file = "mutex.file" |
| size_t | len |
| int | maxlocks = 20 |
| int | nlocks = 10000 |
| int | nprocs = 20 |
| int | nthreads = 1 |
| int | quit |
| int | verbose |
|
|
Referenced by _mi_memmap_file(), history_do_write(), and read_history_range(). |
|
|
|
|
|
Definition at line 35 of file tm.c. Referenced by run_thread(). |
|
|
Referenced by main(). |
|
||||||||||||
|
Definition at line 51 of file tm.c. References ALIGN, align, atoi(), child, exec_proc(), getopt(), len, maxlocks, MUTEX_ALIGN, nlocks, nprocs, nthreads, optarg, optind, perror(), run_proc(), status, tm_file_init(), tm_mutex_destroy(), tm_mutex_init(), tm_mutex_stats(), verbose, and WEXITSTATUS. 00054 { 00055 extern int optind; 00056 extern char *optarg; 00057 pid_t pid; 00058 int ch, eval, i, status; 00059 char *tmpath; 00060 00061 tmpath = argv[0]; 00062 while ((ch = getopt(argc, argv, "l:n:p:st:v")) != EOF) 00063 switch(ch) { 00064 case 'l': 00065 maxlocks = atoi(optarg); 00066 break; 00067 case 'n': 00068 nlocks = atoi(optarg); 00069 break; 00070 case 'p': 00071 nprocs = atoi(optarg); 00072 break; 00073 case 's': 00074 child = 1; 00075 break; 00076 case 't': 00077 nthreads = atoi(optarg); 00078 #if !defined(HAVE_MUTEX_PTHREADS) && !defined(BUILD_PTHREADS_ANYWAY) 00079 if (nthreads != 1) { 00080 (void)fprintf(stderr, 00081 "tm: pthreads not available or not compiled for this platform.\n"); 00082 return (EXIT_FAILURE); 00083 } 00084 #endif 00085 break; 00086 case 'v': 00087 verbose = 1; 00088 break; 00089 case '?': 00090 default: 00091 (void)fprintf(stderr, 00092 "usage: tm [-v] [-l maxlocks] [-n locks] [-p procs] [-t threads]\n"); 00093 return (EXIT_FAILURE); 00094 } 00095 argc -= optind; 00096 argv += optind; 00097 00098 /* 00099 * The file layout: 00100 * DB_MUTEX[1] per-thread mutex array lock 00101 * DB_MUTEX[nthreads] per-thread mutex array 00102 * DB_MUTEX[maxlocks] per-lock mutex array 00103 * u_long[maxlocks][2] per-lock ID array 00104 */ 00105 align = ALIGN(sizeof(DB_MUTEX) * 2, MUTEX_ALIGN); 00106 len = 00107 align * (1 + nthreads + maxlocks) + sizeof(u_long) * maxlocks * 2; 00108 printf( 00109 "mutex alignment %d, structure alignment %d, backing file %lu bytes\n", 00110 MUTEX_ALIGN, align, (u_long)len); 00111 00112 if (child) { 00113 run_proc(); 00114 return (EXIT_SUCCESS); 00115 } 00116 00117 tm_file_init(); 00118 tm_mutex_init(); 00119 00120 printf( 00121 "%d proc, %d threads/proc, %d lock requests from %d locks:\n", 00122 nprocs, nthreads, nlocks, maxlocks); 00123 for (i = 0; i < nprocs; ++i) 00124 switch (fork()) { 00125 case -1: 00126 perror("fork"); 00127 return (EXIT_FAILURE); 00128 case 0: 00129 exec_proc(tmpath); 00130 break; 00131 default: 00132 break; 00133 } 00134 00135 eval = EXIT_SUCCESS; 00136 while ((pid = wait(&status)) != (pid_t)-1) { 00137 fprintf(stderr, 00138 "%lu: exited %d\n", (u_long)pid, WEXITSTATUS(status)); 00139 if (WEXITSTATUS(status) != 0) 00140 eval = EXIT_FAILURE; 00141 } 00142 00143 tm_mutex_stats(); 00144 tm_mutex_destroy(); 00145 00146 printf("tm: exit status: %s\n", 00147 eval == EXIT_SUCCESS ? "success" : "failed!"); 00148 return (eval); 00149 }
|
|
|
Definition at line 177 of file tm.c. References __os_sleep(), errno, exit, free, nthreads, NULL, quit, run_thread(), run_thread_wake(), status, and strerror(). Referenced by main(). 00178 { 00179 #if defined(HAVE_MUTEX_PTHREADS) || defined(BUILD_PTHREADS_ANYWAY) 00180 pthread_t *kidsp, wakep; 00181 int i, status; 00182 void *retp; 00183 #endif 00184 __os_sleep(&dbenv, 3, 0); /* Let everyone catch up. */ 00185 00186 srand((u_int)time(NULL) / getpid()); /* Initialize random numbers. */ 00187 00188 if (nthreads == 1) /* Simple case. */ 00189 exit((int)run_thread((void *)0)); 00190 00191 #if defined(HAVE_MUTEX_PTHREADS) || defined(BUILD_PTHREADS_ANYWAY) 00192 /* 00193 * Spawn off threads. We have nthreads all locking and going to 00194 * sleep, and one other thread cycling through and waking them up. 00195 */ 00196 if ((kidsp = 00197 (pthread_t *)calloc(sizeof(pthread_t), nthreads)) == NULL) { 00198 fprintf(stderr, "tm: %s\n", strerror(errno)); 00199 exit(EXIT_FAILURE); 00200 } 00201 for (i = 0; i < nthreads; i++) 00202 if ((errno = pthread_create( 00203 &kidsp[i], NULL, run_thread, (void *)i)) != 0) { 00204 fprintf(stderr, "tm: failed spawning thread %d: %s\n", 00205 i, strerror(errno)); 00206 exit(EXIT_FAILURE); 00207 } 00208 00209 if ((errno = pthread_create( 00210 &wakep, NULL, run_thread_wake, (void *)0)) != 0) { 00211 fprintf(stderr, "tm: failed spawning wakeup thread: %s\n", 00212 strerror(errno)); 00213 exit(EXIT_FAILURE); 00214 } 00215 00216 /* Wait for the threads to exit. */ 00217 status = 0; 00218 for (i = 0; i < nthreads; i++) { 00219 pthread_join(kidsp[i], &retp); 00220 if (retp != NULL) { 00221 fprintf(stderr, 00222 "tm: thread %d exited with error\n", i); 00223 status = EXIT_FAILURE; 00224 } 00225 } 00226 free(kidsp); 00227 00228 /* Signal wakeup thread to stop. */ 00229 quit = 1; 00230 pthread_join(wakep, &retp); 00231 if (retp != NULL) { 00232 fprintf(stderr, "tm: wakeup thread exited with error\n"); 00233 status = EXIT_FAILURE; 00234 } 00235 00236 exit(status); 00237 #endif 00238 }
|
|
|
Referenced by run_proc(). |
|
|
Referenced by run_proc(). |
|
|
Definition at line 419 of file tm.c. References close(), errno, exit, file, len, lseek, off_t, open(), S_IRGRP, S_IROTH, S_IRUSR, S_IWGRP, S_IWOTH, S_IWUSR, SEEK_SET, strerror(), and write(). Referenced by main(). 00420 { 00421 int fd; 00422 00423 00424 /* Initialize the backing file. */ 00425 printf("Create the backing file...\n"); 00426 #ifdef HAVE_QNX 00427 (void)shm_unlink(file); 00428 if ((fd = shm_open(file, O_CREAT | O_RDWR | O_TRUNC, 00429 #else 00430 (void)remove(file); 00431 if ((fd = open(file, O_CREAT | O_RDWR | O_TRUNC, 00432 #endif 00433 00434 S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH)) == -1) { 00435 (void)fprintf(stderr, "%s: open: %s\n", file, strerror(errno)); 00436 exit(EXIT_FAILURE); 00437 } 00438 if (lseek(fd, (off_t)len, SEEK_SET) != len || write(fd, &fd, 1) != 1) { 00439 (void)fprintf(stderr, 00440 "%s: seek/write: %s\n", file, strerror(errno)); 00441 exit(EXIT_FAILURE); 00442 } 00443 (void)close(fd); 00444 }
|
|
|
Definition at line 498 of file tm.c. Referenced by main(). 00499 { 00500 DB_MUTEX *gm_addr, *lm_addr, *mp, *tm_addr; 00501 int fd, i; 00502 00503 map_file(&gm_addr, &tm_addr, &lm_addr, NULL, &fd); 00504 00505 printf("Destroy the global mutex...\n"); 00506 if (__db_mutex_destroy(gm_addr)) { 00507 fprintf(stderr, 00508 "__db_mutex_destroy (global): %s\n", strerror(errno)); 00509 exit(EXIT_FAILURE); 00510 } 00511 00512 printf("Destroy the per-thread mutexes...\n"); 00513 for (i = 1, mp = tm_addr; 00514 i <= nthreads; ++i, mp = (DB_MUTEX *)((u_int8_t *)mp + align)) { 00515 if (__db_mutex_destroy(mp)) { 00516 fprintf(stderr, 00517 "__db_mutex_destroy (per-thread %d): %s\n", 00518 i, strerror(errno)); 00519 exit(EXIT_FAILURE); 00520 } 00521 } 00522 00523 printf("Destroy the per-lock mutexes...\n"); 00524 for (i = 1, mp = lm_addr; 00525 i <= maxlocks; ++i, mp = (DB_MUTEX *)((u_int8_t *)mp + align)) 00526 if (__db_mutex_destroy(mp)) { 00527 fprintf(stderr, 00528 "__db_mutex_destroy (per-lock: %d): %s\n", 00529 i, strerror(errno)); 00530 exit(EXIT_FAILURE); 00531 } 00532 00533 unmap_file((void *)gm_addr, fd); 00534 #ifdef HAVE_QNX 00535 (void)shm_unlink(file); 00536 #endif 00537 }
|
|
|
Definition at line 451 of file tm.c. Referenced by main(). 00452 { 00453 DB_MUTEX *gm_addr, *lm_addr, *mp, *tm_addr; 00454 int fd, i; 00455 00456 map_file(&gm_addr, &tm_addr, &lm_addr, NULL, &fd); 00457 00458 printf("Initialize the global mutex...\n"); 00459 if (__db_mutex_init_int(&dbenv, gm_addr, 0, 0)) { 00460 fprintf(stderr, 00461 "__db_mutex_init (global): %s\n", strerror(errno)); 00462 exit(EXIT_FAILURE); 00463 } 00464 00465 printf("Initialize the per-thread mutexes...\n"); 00466 for (i = 1, mp = tm_addr; 00467 i <= nthreads; ++i, mp = (DB_MUTEX *)((u_int8_t *)mp + align)) { 00468 if (__db_mutex_init_int(&dbenv, mp, 0, MUTEX_SELF_BLOCK)) { 00469 fprintf(stderr, "__db_mutex_init (per-thread %d): %s\n", 00470 i, strerror(errno)); 00471 exit(EXIT_FAILURE); 00472 } 00473 if (__db_mutex_lock(&dbenv, mp)) { 00474 fprintf(stderr, 00475 "__db_mutex_init (per-thread %d) lock: %s\n", 00476 i, strerror(errno)); 00477 exit(EXIT_FAILURE); 00478 } 00479 } 00480 00481 printf("Initialize the per-lock mutexes...\n"); 00482 for (i = 1, mp = lm_addr; 00483 i <= maxlocks; ++i, mp = (DB_MUTEX *)((u_int8_t *)mp + align)) 00484 if (__db_mutex_init_int(&dbenv, mp, 0, 0)) { 00485 fprintf(stderr, "__db_mutex_init (per-lock: %d): %s\n", 00486 i, strerror(errno)); 00487 exit(EXIT_FAILURE); 00488 } 00489 00490 unmap_file((void *)gm_addr, fd); 00491 }
|
|
|
Definition at line 544 of file tm.c. Referenced by main(). 00545 { 00546 DB_MUTEX *gm_addr, *lm_addr, *mp; 00547 int fd, i; 00548 00549 map_file(&gm_addr, NULL, &lm_addr, NULL, &fd); 00550 00551 printf("Per-lock mutex statistics...\n"); 00552 for (i = 1, mp = lm_addr; 00553 i <= maxlocks; ++i, mp = (DB_MUTEX *)((u_int8_t *)mp + align)) 00554 printf("mutex %2d: wait: %lu; no wait %lu\n", i, 00555 (u_long)mp->mutex_set_wait, (u_long)mp->mutex_set_nowait); 00556 00557 unmap_file((void *)gm_addr, fd); 00558 }
|
|
|
Referenced by run_thread(), and mapped_file::~mapped_file(). |
|
|
Definition at line 39 of file tm.c. Referenced by NdbOperation::equal_impl(), Dbdih::execDIADDTABREQ(), main(), run_thread(), NdbIndexScanOperation::setBound(), and FsBuffer::setup(). |
|
|
Definition at line 46 of file tm.c. Referenced by __bam_dpages(), __bam_vrfy_inp(), __bam_vrfy_subtree(), __dd_build(), __ham_vrfy_bucket(), __ham_vrfy_item(), __ram_vrfy_inp(), sp_pcontext::destroy(), handle_child(), main(), sp_pcontext::push_context(), spawn_init(), and uses_only_table_name_fields(). |
|
|
|
|
|
|
|
|
|
|
|
Definition at line 43 of file tm.c. Referenced by exec_proc(), main(), and run_thread(). |
|
|
Definition at line 44 of file tm.c. Referenced by exec_proc(), main(), and run_thread(). |
|
|
Definition at line 45 of file tm.c. Referenced by main(). |
|
|
Definition at line 47 of file tm.c. Referenced by exec_proc(), main(), and run_proc(). |
|
|
Definition at line 40 of file tm.c. Referenced by run_proc(). |
|
1.4.3