⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tm.c

📁 这是linux下运行的mysql软件包,可用于linux 下安装 php + mysql + apach 的网络配置
💻 C
字号:
/* * Standalone mutex tester for Berkeley DB mutexes. */#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>#if defined(HAVE_MUTEX_PTHREADS) || defined(BUILD_PTHREADS_ANYWAY)#include <pthread.h>#endif#include "db_int.h"void  exec_proc();void  tm_file_init();void  map_file();void  run_proc();void *run_thread();void *run_thread_wake();void  tm_mutex_destroy();void  tm_mutex_init();void  tm_mutex_stats();void  unmap_file();#define	MUTEX_WAKEME	0x80			/* Wake-me flag. */DB_ENV	 dbenv;					/* Fake out DB. */size_t	 len;					/* Backing file size. */int	 align;					/* Mutex alignment in file. */int	 quit;					/* End-of-test flag. */char	*file = "mutex.file";			/* Backing file. */int	 maxlocks = 20;				/* -l: Backing locks. */int	 nlocks = 10000;			/* -n: Locks per processes. */int	 nprocs = 20;				/* -p: Processes. */int	 child;					/* -s: Slave. */int	 nthreads = 1;				/* -t: Threads. */int	 verbose;				/* -v: Verbosity. */intmain(argc, argv)	int argc;	char *argv[];{	extern int optind;	extern char *optarg;	pid_t pid;	int ch, eval, i, status;	char *tmpath;	tmpath = argv[0];	while ((ch = getopt(argc, argv, "l:n:p:st:v")) != EOF)		switch(ch) {		case 'l':			maxlocks = atoi(optarg);			break;		case 'n':			nlocks = atoi(optarg);			break;		case 'p':			nprocs = atoi(optarg);			break;		case 's':			child = 1;			break;		case 't':			nthreads = atoi(optarg);#if !defined(HAVE_MUTEX_PTHREADS) && !defined(BUILD_PTHREADS_ANYWAY)			if (nthreads != 1) {				(void)fprintf(stderr,	"tm: pthreads not available or not compiled for this platform.\n");				return (EXIT_FAILURE);			}#endif			break;		case 'v':			verbose = 1;			break;		case '?':		default:			(void)fprintf(stderr,    "usage: tm [-v] [-l maxlocks] [-n locks] [-p procs] [-t threads]\n");			return (EXIT_FAILURE);		}	argc -= optind;	argv += optind;	/*	 * The file layout:	 *	DB_MUTEX[1]		per-thread mutex array lock	 *	DB_MUTEX[nthreads]	per-thread mutex array	 *	DB_MUTEX[maxlocks]	per-lock mutex array	 *	u_long[maxlocks][2]	per-lock ID array	 */	align = ALIGN(sizeof(DB_MUTEX) * 2, MUTEX_ALIGN);	len =	    align * (1 + nthreads +  maxlocks) + sizeof(u_long) * maxlocks * 2;	printf(    "mutex alignment %d, structure alignment %d, backing file %lu bytes\n",	    MUTEX_ALIGN, align, (u_long)len);	if (child) {		run_proc();		return (EXIT_SUCCESS);	}	tm_file_init();	tm_mutex_init();	printf(	    "%d proc, %d threads/proc, %d lock requests from %d locks:\n",	    nprocs, nthreads, nlocks, maxlocks);	for (i = 0; i < nprocs; ++i)		switch (fork()) {		case -1:			perror("fork");			return (EXIT_FAILURE);		case 0:			exec_proc(tmpath);			break;		default:			break;		}	eval = EXIT_SUCCESS;	while ((pid = wait(&status)) != (pid_t)-1) {		fprintf(stderr,		    "%lu: exited %d\n", (u_long)pid, WEXITSTATUS(status));		if (WEXITSTATUS(status) != 0)			eval = EXIT_FAILURE;	}	tm_mutex_stats();	tm_mutex_destroy();	printf("tm: exit status: %s\n",	    eval == EXIT_SUCCESS ? "success" : "failed!");	return (eval);}voidexec_proc(tmpath)	char *tmpath;{	char *argv[10], **ap, b_l[10], b_n[10], b_t[10];	ap = &argv[0];	*ap++ = "tm";	sprintf(b_l, "-l%d", maxlocks);	*ap++ = b_l;	sprintf(b_n, "-n%d", nlocks);	*ap++ = b_n;	*ap++ = "-s";	sprintf(b_t, "-t%d", nthreads);	*ap++ = b_t;	if (verbose)		*ap++ = "-v";	*ap = NULL;	execvp(tmpath, argv);	fprintf(stderr, "%s: %s\n", tmpath, strerror(errno));	exit(EXIT_FAILURE);}voidrun_proc(){#if defined(HAVE_MUTEX_PTHREADS) || defined(BUILD_PTHREADS_ANYWAY)	pthread_t *kidsp, wakep;	int i, status;	void *retp;#endif	__os_sleep(&dbenv, 3, 0);		/* Let everyone catch up. */	srand((u_int)time(NULL) / getpid());	/* Initialize random numbers. */	if (nthreads == 1)			/* Simple case. */		exit((int)run_thread((void *)0));#if defined(HAVE_MUTEX_PTHREADS) || defined(BUILD_PTHREADS_ANYWAY)	/*	 * Spawn off threads.  We have nthreads all locking and going to	 * sleep, and one other thread cycling through and waking them up.	 */	if ((kidsp =	    (pthread_t *)calloc(sizeof(pthread_t), nthreads)) == NULL) {		fprintf(stderr, "tm: %s\n", strerror(errno));		exit(EXIT_FAILURE);	}	for (i = 0; i < nthreads; i++)		if ((errno = pthread_create(		    &kidsp[i], NULL, run_thread, (void *)i)) != 0) {			fprintf(stderr, "tm: failed spawning thread %d: %s\n",			    i, strerror(errno));			exit(EXIT_FAILURE);		}	if ((errno = pthread_create(	    &wakep, NULL, run_thread_wake, (void *)0)) != 0) {		fprintf(stderr, "tm: failed spawning wakeup thread: %s\n",		    strerror(errno));		exit(EXIT_FAILURE);	}	/* Wait for the threads to exit. */	status = 0;	for (i = 0; i < nthreads; i++) {		pthread_join(kidsp[i], &retp);		if (retp != NULL) {			fprintf(stderr,			    "tm: thread %d exited with error\n", i);			status = EXIT_FAILURE;		}	}	free(kidsp);	/* Signal wakeup thread to stop. */	quit = 1;	pthread_join(wakep, &retp);	if (retp != NULL) {		fprintf(stderr, "tm: wakeup thread exited with error\n");		status = EXIT_FAILURE;	}	exit(status);#endif}void *run_thread(arg)	void *arg;{	DB_MUTEX *gm_addr, *lm_addr, *tm_addr, *mp;	u_long gid1, gid2, *id_addr;	int fd, i, lock, id, nl, remap;	/* Set local and global per-thread ID. */	id = (int)arg;	gid1 = (u_long)getpid();#if defined(HAVE_MUTEX_PTHREADS) || defined(BUILD_PTHREADS_ANYWAY)	gid2 = (u_long)pthread_self();#else	gid2 = 0;#endif	printf("\tPID: %lu; TID: %lx; ID: %d\n", gid1, gid2, id);	nl = nlocks;	for (gm_addr = NULL, remap = 0;;) {		/* Map in the file as necessary. */		if (gm_addr == NULL) {			map_file(&gm_addr, &tm_addr, &lm_addr, &id_addr, &fd);			remap = (rand() % 100) + 35;		}		/* Select and acquire a data lock. */		lock = rand() % maxlocks;		mp = (DB_MUTEX *)((u_int8_t *)lm_addr + lock * align);		if (verbose)			printf("%lu/%lx: %03d\n", gid1, gid2, lock);		if (__db_mutex_lock(&dbenv, mp)) {			fprintf(stderr,			    "%lu/%lx: never got lock\n", gid1, gid2);			return ((void *)EXIT_FAILURE);		}		if (id_addr[lock * 2] != 0) {			fprintf(stderr,			    "RACE! (%lu/%lx granted lock %d held by %lu/%lx)\n",			    gid1, gid2,			    lock, id_addr[lock * 2], id_addr[lock * 2 + 1]);			return ((void *)EXIT_FAILURE);		}		id_addr[lock * 2] = gid1;		id_addr[lock * 2 + 1] = gid2;		/*		 * Pretend to do some work, periodically checking to see if		 * we still hold the mutex.		 */		for (i = 0; i < 3; ++i) {			__os_sleep(&dbenv, 0, rand() % 3);			if (id_addr[lock * 2] != gid1 ||			    id_addr[lock * 2 + 1] != gid2) {				fprintf(stderr,			    "RACE! (%lu/%lx stole lock %d from %lu/%lx)\n",				    id_addr[lock * 2],				    id_addr[lock * 2 + 1], lock, gid1, gid2);				return ((void *)EXIT_FAILURE);			}		}#if defined(HAVE_MUTEX_PTHREADS) || defined(BUILD_PTHREADS_ANYWAY)		/*		 * Test self-blocking and unlocking by other threads/processes:		 *		 *	acquire the global lock		 *	set our wakeup flag		 *	release the global lock		 *	acquire our per-thread lock		 *		 * The wakeup thread will wake us up.		 */		if (__db_mutex_lock(&dbenv, gm_addr)) {			fprintf(stderr, "%lu/%lx: global lock\n", gid1, gid2);			return ((void *)EXIT_FAILURE);		}		mp = (DB_MUTEX *)((u_int8_t *)tm_addr + id * align);		F_SET(mp, MUTEX_WAKEME);		if (__db_mutex_unlock(&dbenv, gm_addr)) {			fprintf(stderr,			    "%lu/%lx: per-thread wakeup failed\n", gid1, gid2);			return ((void *)EXIT_FAILURE);		}		if (__db_mutex_lock(&dbenv, mp)) {			fprintf(stderr,			    "%lu/%lx: per-thread lock\n", gid1, gid2);			return ((void *)EXIT_FAILURE);		}		/* Time passes... */		if (F_ISSET(mp, MUTEX_WAKEME)) {			fprintf(stderr, "%lu/%lx: %03d wakeup flag still set\n",			    gid1, gid2, id);			return ((void *)EXIT_FAILURE);		}#endif		/* Release the data lock. */		id_addr[lock * 2] = id_addr[lock * 2 + 1] = 0;		mp = (DB_MUTEX *)((u_int8_t *)lm_addr + lock * align);		if (__db_mutex_unlock(&dbenv, mp)) {			fprintf(stderr, "%lu/%lx: wakeup failed\n", gid1, gid2);			return ((void *)EXIT_FAILURE);		}		if (--nl % 100 == 0)			fprintf(stderr, "%lu/%lx: %d\n", gid1, gid2, nl);		if (nl == 0 || --remap == 0) {			unmap_file((void *)gm_addr, fd);			gm_addr = NULL;			if (nl == 0)				break;			__os_sleep(&dbenv, rand() % 3, 0);		}	}	return (NULL);}#if defined(HAVE_MUTEX_PTHREADS) || defined(BUILD_PTHREADS_ANYWAY)/* * run_thread_wake -- *	Thread to wake up other threads that are sleeping. */void *run_thread_wake(arg)	void *arg;{	DB_MUTEX *gm_addr, *tm_addr, *mp;	int fd, id;	arg = NULL;	map_file(&gm_addr, &tm_addr, NULL, NULL, &fd);	/* Loop, waking up sleepers and periodically sleeping ourselves. */	while (!quit) {		id = 0;		/* Acquire the global lock. */retry:		if (__db_mutex_lock(&dbenv, gm_addr)) {			fprintf(stderr, "wt: global lock failed\n");			return ((void *)EXIT_FAILURE);		}next:		mp = (DB_MUTEX *)((u_int8_t *)tm_addr + id * align);		if (F_ISSET(mp, MUTEX_WAKEME)) {			F_CLR(mp, MUTEX_WAKEME);			if (__db_mutex_unlock(&dbenv, mp)) {				fprintf(stderr, "wt: wakeup failed\n");				return ((void *)EXIT_FAILURE);			}		}		if (++id < nthreads && id % 3 != 0)			goto next;		if (__db_mutex_unlock(&dbenv, gm_addr)) {			fprintf(stderr, "wt: global unlock failed\n");			return ((void *)EXIT_FAILURE);		}		__os_sleep(&dbenv, 0, 500);		if (id < nthreads)			goto retry;	}	return (NULL);}#endif/* * tm_file_init -- *	Initialize the backing file. */voidtm_file_init(){	int fd;	/* Initialize the backing file. */	printf("Create the backing file...\n");#ifdef	HAVE_QNX	(void)shm_unlink(file);	if ((fd = shm_open(file, O_CREAT | O_RDWR | O_TRUNC,#else	(void)remove(file);	if ((fd = open(file, O_CREAT | O_RDWR | O_TRUNC,#endif	    S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH)) == -1) {		(void)fprintf(stderr, "%s: open: %s\n", file, strerror(errno));		exit(EXIT_FAILURE);	}	if (lseek(fd, (off_t)len, SEEK_SET) != len || write(fd, &fd, 1) != 1) {		(void)fprintf(stderr,		    "%s: seek/write: %s\n", file, strerror(errno));		exit(EXIT_FAILURE);	}	(void)close(fd);}/* * tm_mutex_init -- *	Initialize the mutexes. */voidtm_mutex_init(){	DB_MUTEX *gm_addr, *lm_addr, *mp, *tm_addr;	int fd, i;	map_file(&gm_addr, &tm_addr, &lm_addr, NULL, &fd);	printf("Initialize the global mutex...\n");	if (__db_mutex_init_int(&dbenv, gm_addr, 0, 0)) {		fprintf(stderr,		    "__db_mutex_init (global): %s\n", strerror(errno));		exit(EXIT_FAILURE);	}	printf("Initialize the per-thread mutexes...\n");	for (i = 1, mp = tm_addr;	    i <= nthreads; ++i, mp = (DB_MUTEX *)((u_int8_t *)mp + align)) {		if (__db_mutex_init_int(&dbenv, mp, 0, MUTEX_SELF_BLOCK)) {			fprintf(stderr, "__db_mutex_init (per-thread %d): %s\n",			    i, strerror(errno));			exit(EXIT_FAILURE);		}		if (__db_mutex_lock(&dbenv, mp)) {			fprintf(stderr,			    "__db_mutex_init (per-thread %d) lock: %s\n",			    i, strerror(errno));			exit(EXIT_FAILURE);		}	}	printf("Initialize the per-lock mutexes...\n");	for (i = 1, mp = lm_addr;	    i <= maxlocks; ++i, mp = (DB_MUTEX *)((u_int8_t *)mp + align))		if (__db_mutex_init_int(&dbenv, mp, 0, 0)) {			fprintf(stderr, "__db_mutex_init (per-lock: %d): %s\n",			    i, strerror(errno));			exit(EXIT_FAILURE);		}	unmap_file((void *)gm_addr, fd);}/* * tm_mutex_destroy -- *	Destroy the mutexes. */voidtm_mutex_destroy(){	DB_MUTEX *gm_addr, *lm_addr, *mp, *tm_addr;	int fd, i;	map_file(&gm_addr, &tm_addr, &lm_addr, NULL, &fd);	printf("Destroy the global mutex...\n");	if (__db_mutex_destroy(gm_addr)) {		fprintf(stderr,		    "__db_mutex_destroy (global): %s\n", strerror(errno));		exit(EXIT_FAILURE);	}	printf("Destroy the per-thread mutexes...\n");	for (i = 1, mp = tm_addr;	    i <= nthreads; ++i, mp = (DB_MUTEX *)((u_int8_t *)mp + align)) {		if (__db_mutex_destroy(mp)) {			fprintf(stderr,			    "__db_mutex_destroy (per-thread %d): %s\n",			    i, strerror(errno));			exit(EXIT_FAILURE);		}	}	printf("Destroy the per-lock mutexes...\n");	for (i = 1, mp = lm_addr;	    i <= maxlocks; ++i, mp = (DB_MUTEX *)((u_int8_t *)mp + align))		if (__db_mutex_destroy(mp)) {			fprintf(stderr,			    "__db_mutex_destroy (per-lock: %d): %s\n",			    i, strerror(errno));			exit(EXIT_FAILURE);		}	unmap_file((void *)gm_addr, fd);#ifdef HAVE_QNX	(void)shm_unlink(file);#endif}/* * tm_mutex_stats -- *	Display mutex statistics. */voidtm_mutex_stats(){	DB_MUTEX *gm_addr, *lm_addr, *mp;	int fd, i;	map_file(&gm_addr, NULL, &lm_addr, NULL, &fd);	printf("Per-lock mutex statistics...\n");	for (i = 1, mp = lm_addr;	    i <= maxlocks; ++i, mp = (DB_MUTEX *)((u_int8_t *)mp + align))		printf("mutex %2d: wait: %lu; no wait %lu\n", i,		    (u_long)mp->mutex_set_wait, (u_long)mp->mutex_set_nowait);	unmap_file((void *)gm_addr, fd);}/* * map_file -- *	Map in the backing file. */voidmap_file(gm_addrp, tm_addrp, lm_addrp, id_addrp, fdp)	DB_MUTEX **gm_addrp, **tm_addrp, **lm_addrp;	u_long **id_addrp;	int *fdp;{	void *maddr;	int fd;#ifndef MAP_FAILED#define	MAP_FAILED	(void *)-1#endif#ifndef MAP_FILE#define	MAP_FILE	0#endif#ifdef	HAVE_QNX	if ((fd = shm_open(file, O_RDWR, 0)) == -1) {#else	if ((fd = open(file, O_RDWR, 0)) == -1) {#endif		fprintf(stderr, "%s: open %s\n", file, strerror(errno));		exit(EXIT_FAILURE);	}	maddr = mmap(NULL, len,	    PROT_READ | PROT_WRITE, MAP_FILE | MAP_SHARED, fd, (off_t)0);	if (maddr == MAP_FAILED) {		fprintf(stderr, "%s: mmap: %s\n", file, strerror(errno));		exit(EXIT_FAILURE);	}	if (gm_addrp != NULL)		*gm_addrp = (DB_MUTEX *)maddr;	maddr = (u_int8_t *)maddr + align;	if (tm_addrp != NULL)		*tm_addrp = (DB_MUTEX *)maddr;	maddr = (u_int8_t *)maddr + align * nthreads;	if (lm_addrp != NULL)		*lm_addrp = (DB_MUTEX *)maddr;	maddr = (u_int8_t *)maddr + align * maxlocks;	if (id_addrp != NULL)		*id_addrp = (u_long *)maddr;	if (fdp != NULL)		*fdp = fd;}/* * unmap_file -- *	Discard backing file map. */voidunmap_file(maddr, fd)	void *maddr;	int fd;{	if (munmap(maddr, len) != 0) {		fprintf(stderr, "munmap: %s\n", strerror(errno));		exit(EXIT_FAILURE);	}	if (close(fd) != 0) {		fprintf(stderr, "close: %s\n", strerror(errno));		exit(EXIT_FAILURE);	}}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -