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

📄 mutex.c

📁 这是linux下运行的mysql软件包,可用于linux 下安装 php + mysql + apach 的网络配置
💻 C
字号:
/*- * See the file LICENSE for redistribution information. * * Copyright (c) 1999-2002 *	Sleepycat Software.  All rights reserved. */#include "db_config.h"#ifndef lintstatic const char revid[] = "$Id: mutex.c,v 11.37 2002/05/31 19:37:46 bostic Exp $";#endif /* not lint */#ifndef NO_SYSTEM_INCLUDES#include <sys/types.h>#include <string.h>#endif#include "db_int.h"#if	defined(MUTEX_NO_MALLOC_LOCKS) || defined(HAVE_MUTEX_SYSTEM_RESOURCES)#include "dbinc/db_shash.h"#include "dbinc/lock.h"#include "dbinc/log.h"#include "dbinc/mp.h"#include "dbinc/txn.h"#endifstatic int __db_mutex_alloc_int __P((DB_ENV *, REGINFO *, DB_MUTEX **));#ifdef	HAVE_MUTEX_SYSTEM_RESOURCESstatic REGMAINT * __db_mutex_maint __P((DB_ENV *, REGINFO *));#endif/* * __db_mutex_setup -- *	External interface to allocate, and/or initialize, record *	mutexes. * * PUBLIC: int __db_mutex_setup __P((DB_ENV *, REGINFO *, void *, u_int32_t)); */int__db_mutex_setup(dbenv, infop, ptr, flags)	DB_ENV *dbenv;	REGINFO *infop;	void *ptr;	u_int32_t flags;{	DB_MUTEX *mutex;	REGMAINT *maint;	u_int32_t iflags, offset;	int ret;	ret = 0;	/*	 * If they indicated the region is not locked, then lock it.	 * This is only needed when we have unusual mutex resources.	 * (I.e. MUTEX_NO_MALLOC_LOCKS or HAVE_MUTEX_SYSTEM_RESOURCES)	 */#if	defined(MUTEX_NO_MALLOC_LOCKS) || defined(HAVE_MUTEX_SYSTEM_RESOURCES)	if (!LF_ISSET(MUTEX_NO_RLOCK))		R_LOCK(dbenv, infop);#endif	/*	 * Allocate the mutex if they asked us to.	 */	mutex = NULL;	if (LF_ISSET(MUTEX_ALLOC)) {		if ((ret = __db_mutex_alloc_int(dbenv, infop, ptr)) != 0)			goto err;		mutex = *(DB_MUTEX **)ptr;	} else		mutex = (DB_MUTEX *)ptr;	/*	 * Set up to initialize the mutex.	 */	iflags = LF_ISSET(MUTEX_THREAD | MUTEX_SELF_BLOCK);	switch (infop->type) {	case REGION_TYPE_LOCK:		offset = P_TO_UINT32(mutex) + DB_FCNTL_OFF_LOCK;		break;	case REGION_TYPE_MPOOL:		offset = P_TO_UINT32(mutex) + DB_FCNTL_OFF_MPOOL;		break;	default:		offset = P_TO_UINT32(mutex) + DB_FCNTL_OFF_GEN;		break;	}	maint = NULL;#ifdef	HAVE_MUTEX_SYSTEM_RESOURCES	if (!LF_ISSET(MUTEX_NO_RECORD))		maint = (REGMAINT *)__db_mutex_maint(dbenv, infop);#endif	ret = __db_mutex_init(dbenv, mutex, offset, iflags, infop, maint);err:#if	defined(MUTEX_NO_MALLOC_LOCKS) || defined(HAVE_MUTEX_SYSTEM_RESOURCES)	if (!LF_ISSET(MUTEX_NO_RLOCK))		R_UNLOCK(dbenv, infop);#endif	/*	 * If we allocated the mutex but had an error on init'ing,	 * then we must free it before returning.	 * !!!	 * Free must be done after releasing region lock.	 */	if (ret != 0 && LF_ISSET(MUTEX_ALLOC) && mutex != NULL) {		__db_mutex_free(dbenv, infop, mutex);		*(DB_MUTEX **)ptr = NULL;	}	return (ret);}/* * __db_mutex_alloc_int -- *	Allocate and initialize a mutex. */static int__db_mutex_alloc_int(dbenv, infop, storep)	DB_ENV *dbenv;	REGINFO *infop;	DB_MUTEX **storep;{	int ret;	/*	 * If the architecture supports mutexes in heap memory, use heap memory.	 * If it doesn't, we have to allocate space in a region.  If allocation	 * in the region fails, fallback to allocating from the mpool region,	 * because it's big, it almost always exists and if it's entirely dirty,	 * we can free buffers until memory is available.	 */#if	defined(MUTEX_NO_MALLOC_LOCKS) || defined(HAVE_MUTEX_SYSTEM_RESOURCES)	ret = __db_shalloc(infop->addr, sizeof(DB_MUTEX), MUTEX_ALIGN, storep);	if (ret == ENOMEM && MPOOL_ON(dbenv)) {		DB_MPOOL *dbmp;		dbmp = dbenv->mp_handle;		if ((ret = __memp_alloc(dbmp,		    dbmp->reginfo, NULL, sizeof(DB_MUTEX), NULL, storep)) == 0)			(*storep)->flags = MUTEX_MPOOL;	} else		(*storep)->flags = 0;#else	COMPQUIET(dbenv, NULL);	COMPQUIET(infop, NULL);	ret = __os_calloc(dbenv, 1, sizeof(DB_MUTEX), storep);#endif	if (ret != 0)		__db_err(dbenv, "Unable to allocate memory for mutex");	return (ret);}/* * __db_mutex_free -- *	Free a mutex. * * PUBLIC: void __db_mutex_free __P((DB_ENV *, REGINFO *, DB_MUTEX *)); */void__db_mutex_free(dbenv, infop, mutexp)	DB_ENV *dbenv;	REGINFO *infop;	DB_MUTEX *mutexp;{#if	defined(MUTEX_NO_MALLOC_LOCKS) || defined(HAVE_MUTEX_SYSTEM_RESOURCES)	R_LOCK(dbenv, infop);#if	defined(HAVE_MUTEX_SYSTEM_RESOURCES)	if (F_ISSET(mutexp, MUTEX_INITED))		__db_shlocks_clear(mutexp, infop, NULL);#endif	if (F_ISSET(mutexp, MUTEX_MPOOL)) {		DB_MPOOL *dbmp;		dbmp = dbenv->mp_handle;		R_LOCK(dbenv, dbmp->reginfo);		__db_shalloc_free(dbmp->reginfo[0].addr, mutexp);		R_UNLOCK(dbenv, dbmp->reginfo);	} else		__db_shalloc_free(infop->addr, mutexp);	R_UNLOCK(dbenv, infop);#else	COMPQUIET(dbenv, NULL);	COMPQUIET(infop, NULL);	__os_free(dbenv, mutexp);#endif}#ifdef HAVE_MUTEX_SYSTEM_RESOURCES/* * __db_shreg_locks_record -- *	Record an entry in the shared locks area. *	Region lock must be held in caller. */static int__db_shreg_locks_record(dbenv, mutexp, infop, rp)	DB_ENV *dbenv;	DB_MUTEX *mutexp;	REGINFO *infop;	REGMAINT *rp;{	u_int i;	if (!F_ISSET(mutexp, MUTEX_INITED))		return (0);	DB_ASSERT(mutexp->reg_off == INVALID_ROFF);	rp->stat.st_records++;	i = (roff_t *)R_ADDR(infop, rp->regmutex_hint) - &rp->regmutexes[0];	if (rp->regmutexes[i] != INVALID_ROFF) {		/*		 * Our hint failed, search for an open slot.		 */		rp->stat.st_hint_miss++;		for (i = 0; i < rp->reglocks; i++)			if (rp->regmutexes[i] == INVALID_ROFF)				break;		if (i == rp->reglocks) {			rp->stat.st_max_locks++;			__db_err(dbenv,			    "Region mutexes: Exceeded maximum lock slots %lu",			    (u_long)rp->reglocks);			return (ENOMEM);		}	} else		rp->stat.st_hint_hit++;	/*	 * When we get here, i is an empty slot.  Record this	 * mutex, set hint to point to the next slot and we are done.	 */	rp->regmutexes[i] = R_OFFSET(infop, mutexp);	mutexp->reg_off = R_OFFSET(infop, &rp->regmutexes[i]);	rp->regmutex_hint = (i < rp->reglocks - 1) ?	    R_OFFSET(infop, &rp->regmutexes[i+1]) :	    R_OFFSET(infop, &rp->regmutexes[0]);	return (0);}/* * __db_shreg_locks_clear -- *	Erase an entry in the shared locks area. * * PUBLIC: void __db_shreg_locks_clear __P((DB_MUTEX *, REGINFO *, REGMAINT *)); */void__db_shreg_locks_clear(mutexp, infop, rp)	DB_MUTEX *mutexp;	REGINFO *infop;	REGMAINT *rp;{	/*	 * !!!	 * Assumes the caller's region lock is held.	 */	if (!F_ISSET(mutexp, MUTEX_INITED))		return;	/*	 * This function is generally only called on a forcible remove of an	 * environment.  We recorded our index in the mutex, find and clear it.	 */	DB_ASSERT(mutexp->reg_off != INVALID_ROFF);	DB_ASSERT(*(roff_t *)R_ADDR(infop, mutexp->reg_off) == \	    R_OFFSET(infop, mutexp));	*(roff_t *)R_ADDR(infop, mutexp->reg_off) = 0;	if (rp != NULL) {		rp->regmutex_hint = mutexp->reg_off;		rp->stat.st_clears++;	}	mutexp->reg_off = INVALID_ROFF;	__db_mutex_destroy(mutexp);}/* * __db_shreg_locks_destroy -- *	Destroy all mutexes in a region's range. * * PUBLIC: void __db_shreg_locks_destroy __P((REGINFO *, REGMAINT *)); */void__db_shreg_locks_destroy(infop, rp)	REGINFO *infop;	REGMAINT *rp;{	u_int32_t i;	/*	 * Go through the list of all mutexes and destroy them.	 */	for (i = 0; i < rp->reglocks; i++)		if (rp->regmutexes[i] != 0) {			rp->stat.st_destroys++;			__db_mutex_destroy((DB_MUTEX *)R_ADDR(infop,			    rp->regmutexes[i]));		}}/* * __db_shreg_mutex_init -- *	Initialize a shared memory mutex. * * PUBLIC: int __db_shreg_mutex_init __P((DB_ENV *, DB_MUTEX *, u_int32_t, * PUBLIC:    u_int32_t, REGINFO *, REGMAINT *)); */int__db_shreg_mutex_init(dbenv, mutexp, offset, flags, infop, rp)	DB_ENV *dbenv;	DB_MUTEX *mutexp;	u_int32_t offset;	u_int32_t flags;	REGINFO *infop;	REGMAINT *rp;{	int ret;	if ((ret = __db_mutex_init_int(dbenv, mutexp, offset, flags)) != 0)		return (ret);	/*	 * Some mutexes cannot be recorded, but we want one interface.	 * So, if we have no REGMAINT, then just return.	 */	if (rp == NULL)		return (ret);	/*	 * !!!	 * Since __db_mutex_init_int is a macro, we may not be	 * using the 'offset' as it is only used for one type	 * of mutex.  We COMPQUIET it here, after the call above.	 */	COMPQUIET(offset, 0);	ret = __db_shreg_locks_record(dbenv, mutexp, infop, rp);	/*	 * If we couldn't record it and we are returning an error,	 * we need to destroy the mutex we just created.	 */	if (ret)		__db_mutex_destroy(mutexp);	return (ret);}/* * __db_shreg_maintinit -- *	Initialize a region's maintenance information. * * PUBLIC: void __db_shreg_maintinit __P((REGINFO *, void *addr, size_t)); */void__db_shreg_maintinit(infop, addr, size)	REGINFO *infop;	void *addr;	size_t size;{	REGMAINT *rp;	u_int32_t i;	rp = (REGMAINT *)addr;	memset(addr, 0, sizeof(REGMAINT));	rp->reglocks = size / sizeof(roff_t);	rp->regmutex_hint = R_OFFSET(infop, &rp->regmutexes[0]);	for (i = 0; i < rp->reglocks; i++)		rp->regmutexes[i] = INVALID_ROFF;}static REGMAINT *__db_mutex_maint(dbenv, infop)	DB_ENV *dbenv;	REGINFO *infop;{	roff_t moff;	switch (infop->type) {	case REGION_TYPE_LOCK:		moff = ((DB_LOCKREGION *)R_ADDR(infop,		    infop->rp->primary))->maint_off;		break;	case REGION_TYPE_LOG:		moff = ((LOG *)R_ADDR(infop, infop->rp->primary))->maint_off;		break;	case REGION_TYPE_MPOOL:		moff = ((MPOOL *)R_ADDR(infop, infop->rp->primary))->maint_off;		break;	case REGION_TYPE_TXN:		moff = ((DB_TXNREGION *)R_ADDR(infop,		    infop->rp->primary))->maint_off;		break;	default:		__db_err(dbenv,	"Attempting to record mutex in a region not set up to do so");		return (NULL);	}	return ((REGMAINT *)R_ADDR(infop, moff));}#endif /* HAVE_MUTEX_SYSTEM_RESOURCES */

⌨️ 快捷键说明

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