tm.c File Reference

#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


Define Documentation

#define MAP_FAILED   (void *)-1
 

Referenced by _mi_memmap_file(), history_do_write(), and read_history_range().

#define MAP_FILE   0
 

#define MUTEX_WAKEME   0x80
 

Definition at line 35 of file tm.c.

Referenced by run_thread().


Function Documentation

void exec_proc  ) 
 

Referenced by main().

int main int  argc,
argv 
 

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 }

void run_proc  ) 
 

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 }

void* run_thread  ) 
 

Referenced by run_proc().

void* run_thread_wake  ) 
 

Referenced by run_proc().

void tm_file_init  ) 
 

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 }

void tm_mutex_destroy  ) 
 

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 }

void tm_mutex_init  ) 
 

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 }

void tm_mutex_stats  ) 
 

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 }

void unmap_file  ) 
 

Referenced by run_thread(), and mapped_file::~mapped_file().


Variable Documentation

int align
 

Definition at line 39 of file tm.c.

Referenced by NdbOperation::equal_impl(), Dbdih::execDIADDTABREQ(), main(), run_thread(), NdbIndexScanOperation::setBound(), and FsBuffer::setup().

int child
 

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().

DB_ENV dbenv
 

Definition at line 37 of file tm.c.

char* file = "mutex.file"
 

Definition at line 41 of file tm.c.

size_t len
 

Definition at line 38 of file tm.c.

int maxlocks = 20
 

Definition at line 43 of file tm.c.

Referenced by exec_proc(), main(), and run_thread().

int nlocks = 10000
 

Definition at line 44 of file tm.c.

Referenced by exec_proc(), main(), and run_thread().

int nprocs = 20
 

Definition at line 45 of file tm.c.

Referenced by main().

int nthreads = 1
 

Definition at line 47 of file tm.c.

Referenced by exec_proc(), main(), and run_proc().

int quit
 

Definition at line 40 of file tm.c.

Referenced by run_proc().

int verbose
 

Definition at line 48 of file tm.c.

Referenced by check_counts(), check_if_ignore_table(), com_go(), compress(), compress_isam_file(), convert_file(), db_connect(), db_disconnect(), dbConnect(), dbDisconnect(), dump_table(), examine_log(), exec_proc(), get_one_option(), get_options(), get_statistic(), get_table_structure(), get_view_structure(), join_same_trees(), lock_table(), main(), mysql_end(), open_isam_file(), out_header(), out_item(), out_trailer(), printf_log(), put_info(), run_test(), run_thread(), static_get_options(), term_echotc(), testMicros(), write_field_info(), write_huff_tree(), and write_to_table().


Generated on Wed Jul 20 21:07:03 2005 for MySQL 5.0.9 Beta by  doxygen 1.4.3