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

📄 mcxt.c

📁 PostgreSQL 8.1.4的源码 适用于Linux下的开源数据库系统
💻 C
📖 第 1 页 / 共 2 页
字号:
	(*context->methods->check) (context);	for (child = context->firstchild; child != NULL; child = child->nextchild)		MemoryContextCheck(child);}#endif/* * MemoryContextContains *		Detect whether an allocated chunk of memory belongs to a given *		context or not. * * Caution: this test is reliable as long as 'pointer' does point to * a chunk of memory allocated from *some* context.  If 'pointer' points * at memory obtained in some other way, there is a small chance of a * false-positive result, since the bits right before it might look like * a valid chunk header by chance. */boolMemoryContextContains(MemoryContext context, void *pointer){	StandardChunkHeader *header;	/*	 * Try to detect bogus pointers handed to us, poorly though we can.	 * Presumably, a pointer that isn't MAXALIGNED isn't pointing at an	 * allocated chunk.	 */	if (pointer == NULL || pointer != (void *) MAXALIGN(pointer))		return false;	/*	 * OK, it's probably safe to look at the chunk header.	 */	header = (StandardChunkHeader *)		((char *) pointer - STANDARDCHUNKHEADERSIZE);	/*	 * If the context link doesn't match then we certainly have a non-member	 * chunk.  Also check for a reasonable-looking size as extra guard against	 * being fooled by bogus pointers.	 */	if (header->context == context && AllocSizeIsValid(header->size))		return true;	return false;}/*-------------------- * MemoryContextCreate *		Context-type-independent part of context creation. * * This is only intended to be called by context-type-specific * context creation routines, not by the unwashed masses. * * The context creation procedure is a little bit tricky because * we want to be sure that we don't leave the context tree invalid * in case of failure (such as insufficient memory to allocate the * context node itself).  The procedure goes like this: *	1.	Context-type-specific routine first calls MemoryContextCreate(), *		passing the appropriate tag/size/methods values (the methods *		pointer will ordinarily point to statically allocated data). *		The parent and name parameters usually come from the caller. *	2.	MemoryContextCreate() attempts to allocate the context node, *		plus space for the name.  If this fails we can ereport() with no *		damage done. *	3.	We fill in all of the type-independent MemoryContext fields. *	4.	We call the type-specific init routine (using the methods pointer). *		The init routine is required to make the node minimally valid *		with zero chance of failure --- it can't allocate more memory, *		for example. *	5.	Now we have a minimally valid node that can behave correctly *		when told to reset or delete itself.  We link the node to its *		parent (if any), making the node part of the context tree. *	6.	We return to the context-type-specific routine, which finishes *		up type-specific initialization.  This routine can now do things *		that might fail (like allocate more memory), so long as it's *		sure the node is left in a state that delete will handle. * * This protocol doesn't prevent us from leaking memory if step 6 fails * during creation of a top-level context, since there's no parent link * in that case.  However, if you run out of memory while you're building * a top-level context, you might as well go home anyway... * * Normally, the context node and the name are allocated from * TopMemoryContext (NOT from the parent context, since the node must * survive resets of its parent context!).	However, this routine is itself * used to create TopMemoryContext!  If we see that TopMemoryContext is NULL, * we assume we are creating TopMemoryContext and use malloc() to allocate * the node. * * Note that the name field of a MemoryContext does not point to * separately-allocated storage, so it should not be freed at context * deletion. *-------------------- */MemoryContextMemoryContextCreate(NodeTag tag, Size size,					MemoryContextMethods *methods,					MemoryContext parent,					const char *name){	MemoryContext node;	Size		needed = size + strlen(name) + 1;	/* Get space for node and name */	if (TopMemoryContext != NULL)	{		/* Normal case: allocate the node in TopMemoryContext */		node = (MemoryContext) MemoryContextAlloc(TopMemoryContext,												  needed);	}	else	{		/* Special case for startup: use good ol' malloc */		node = (MemoryContext) malloc(needed);		Assert(node != NULL);	}	/* Initialize the node as best we can */	MemSet(node, 0, size);	node->type = tag;	node->methods = methods;	node->parent = NULL;		/* for the moment */	node->firstchild = NULL;	node->nextchild = NULL;	node->name = ((char *) node) + size;	strcpy(node->name, name);	/* Type-specific routine finishes any other essential initialization */	(*node->methods->init) (node);	/* OK to link node to parent (if any) */	if (parent)	{		node->parent = parent;		node->nextchild = parent->firstchild;		parent->firstchild = node;	}	/* Return to type-specific creation routine to finish up */	return node;}/* * MemoryContextAlloc *		Allocate space within the specified context. * * This could be turned into a macro, but we'd have to import * nodes/memnodes.h into postgres.h which seems a bad idea. */void *MemoryContextAlloc(MemoryContext context, Size size){	AssertArg(MemoryContextIsValid(context));	if (!AllocSizeIsValid(size))		elog(ERROR, "invalid memory alloc request size %lu",			 (unsigned long) size);	return (*context->methods->alloc) (context, size);}/* * MemoryContextAllocZero *		Like MemoryContextAlloc, but clears allocated memory * *	We could just call MemoryContextAlloc then clear the memory, but this *	is a very common combination, so we provide the combined operation. */void *MemoryContextAllocZero(MemoryContext context, Size size){	void	   *ret;	AssertArg(MemoryContextIsValid(context));	if (!AllocSizeIsValid(size))		elog(ERROR, "invalid memory alloc request size %lu",			 (unsigned long) size);	ret = (*context->methods->alloc) (context, size);	MemSetAligned(ret, 0, size);	return ret;}/* * MemoryContextAllocZeroAligned *		MemoryContextAllocZero where length is suitable for MemSetLoop * *	This might seem overly specialized, but it's not because newNode() *	is so often called with compile-time-constant sizes. */void *MemoryContextAllocZeroAligned(MemoryContext context, Size size){	void	   *ret;	AssertArg(MemoryContextIsValid(context));	if (!AllocSizeIsValid(size))		elog(ERROR, "invalid memory alloc request size %lu",			 (unsigned long) size);	ret = (*context->methods->alloc) (context, size);	MemSetLoop(ret, 0, size);	return ret;}/* * pfree *		Release an allocated chunk. */voidpfree(void *pointer){	StandardChunkHeader *header;	/*	 * Try to detect bogus pointers handed to us, poorly though we can.	 * Presumably, a pointer that isn't MAXALIGNED isn't pointing at an	 * allocated chunk.	 */	Assert(pointer != NULL);	Assert(pointer == (void *) MAXALIGN(pointer));	/*	 * OK, it's probably safe to look at the chunk header.	 */	header = (StandardChunkHeader *)		((char *) pointer - STANDARDCHUNKHEADERSIZE);	AssertArg(MemoryContextIsValid(header->context));	(*header->context->methods->free_p) (header->context, pointer);}/* * repalloc *		Adjust the size of a previously allocated chunk. */void *repalloc(void *pointer, Size size){	StandardChunkHeader *header;	/*	 * Try to detect bogus pointers handed to us, poorly though we can.	 * Presumably, a pointer that isn't MAXALIGNED isn't pointing at an	 * allocated chunk.	 */	Assert(pointer != NULL);	Assert(pointer == (void *) MAXALIGN(pointer));	/*	 * OK, it's probably safe to look at the chunk header.	 */	header = (StandardChunkHeader *)		((char *) pointer - STANDARDCHUNKHEADERSIZE);	AssertArg(MemoryContextIsValid(header->context));	if (!AllocSizeIsValid(size))		elog(ERROR, "invalid memory alloc request size %lu",			 (unsigned long) size);	return (*header->context->methods->realloc) (header->context,												 pointer, size);}/* * MemoryContextSwitchTo *		Returns the current context; installs the given context. * * This is inlined when using GCC. * * TODO: investigate supporting inlining for some non-GCC compilers. */#ifndef __GNUC__MemoryContextMemoryContextSwitchTo(MemoryContext context){	MemoryContext old;	AssertArg(MemoryContextIsValid(context));	old = CurrentMemoryContext;	CurrentMemoryContext = context;	return old;}#endif   /* ! __GNUC__ *//* * MemoryContextStrdup *		Like strdup(), but allocate from the specified context */char *MemoryContextStrdup(MemoryContext context, const char *string){	char	   *nstr;	Size		len = strlen(string) + 1;	nstr = (char *) MemoryContextAlloc(context, len);	memcpy(nstr, string, len);	return nstr;}#if defined(WIN32) || defined(__CYGWIN__)/* *	Memory support routines for libpgport on Win32 * *	Win32 can't load a library that DLLIMPORTs a variable *	if the link object files also DLLIMPORT the same variable. *	For this reason, libpgport can't reference CurrentMemoryContext *	in the palloc macro calls. * *	To fix this, we create several functions here that allow us to *	manage memory without doing the inline in libpgport. */void *pgport_palloc(Size sz){	return palloc(sz);}char *pgport_pstrdup(const char *str){	return pstrdup(str);}/* Doesn't reference a DLLIMPORT variable, but here for completeness. */voidpgport_pfree(void *pointer){	pfree(pointer);}#endif

⌨️ 快捷键说明

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