Team Ai
Datasetpublic

codekingpro/portable-devtools

sourceHugging Faceupdated 5mo agoView on Hugging Face
1likes15kdownloads
memutils_memorychunk.h238 linesDownload Raw Back to utils
1/*-------------------------------------------------------------------------2 *3 * memutils_memorychunk.h4 *	  Here we define a struct named MemoryChunk which implementations of5 *	  MemoryContexts may use as a header for chunks of memory they allocate.6 *7 * MemoryChunk provides a lightweight header that a MemoryContext can use to8 * store a reference back to the block which the given chunk is allocated on9 * and also an additional 30-bits to store another value such as the size of10 * the allocated chunk.11 *12 * Although MemoryChunks are used by each of our MemoryContexts, future13 * implementations may choose to implement their own method for storing chunk14 * headers.  The only requirement is that the header ends with an 8-byte value15 * which the least significant 3-bits of are set to the MemoryContextMethodID16 * of the given context.17 *18 * By default, a MemoryChunk is 8 bytes in size, however, when19 * MEMORY_CONTEXT_CHECKING is defined the header becomes 16 bytes in size due20 * to the additional requested_size field.  The MemoryContext may use this21 * field for whatever they wish, but it is intended to be used for additional22 * checks which are only done in MEMORY_CONTEXT_CHECKING builds.23 *24 * The MemoryChunk contains a uint64 field named 'hdrmask'.  This field is25 * used to encode 4 separate pieces of information.  Starting with the least26 * significant bits of 'hdrmask', the bit space is reserved as follows:27 *28 * 1.	3-bits to indicate the MemoryContextMethodID as defined by29 *		MEMORY_CONTEXT_METHODID_MASK30 * 2.	1-bit to denote an "external" chunk (see below)31 * 3.	30-bits reserved for the MemoryContext to use for anything it32 *		requires.  Most MemoryContext likely want to store the size of the33 *		chunk here.34 * 4.	30-bits for the number of bytes that must be subtracted from the chunk35 *		to obtain the address of the block that the chunk is stored on.36 *37 * In some cases, for example when memory allocations become large, it's38 * possible fields 3 and 4 above are not large enough to store the values39 * required for the chunk.  In this case, the MemoryContext can choose to mark40 * the chunk as "external" by calling the MemoryChunkSetHdrMaskExternal()41 * function.  When this is done, fields 3 and 4 are unavailable for use by the42 * MemoryContext and it's up to the MemoryContext itself to devise its own43 * method for getting the reference to the block.44 *45 * Interface:46 *47 * MemoryChunkSetHdrMask:48 *		Used to set up a non-external MemoryChunk.49 *50 * MemoryChunkSetHdrMaskExternal:51 *		Used to set up an externally managed MemoryChunk.52 *53 * MemoryChunkIsExternal:54 *		Determine if the given MemoryChunk is externally managed, i.e.55 *		MemoryChunkSetHdrMaskExternal() was called on the chunk.56 *57 * MemoryChunkGetValue:58 *		For non-external chunks, return the stored 30-bit value as it was set59 *		in the call to MemoryChunkSetHdrMask().60 *61 * MemoryChunkGetBlock:62 *		For non-external chunks, return a pointer to the block as it was set63 *		in the call to MemoryChunkSetHdrMask().64 *65 * Also exports:66 *		MEMORYCHUNK_MAX_VALUE67 *		MEMORYCHUNK_MAX_BLOCKOFFSET68 *		PointerGetMemoryChunk69 *		MemoryChunkGetPointer70 *71 * Portions Copyright (c) 2022-2023, PostgreSQL Global Development Group72 * Portions Copyright (c) 1994, Regents of the University of California73 *74 * src/include/utils/memutils_memorychunk.h75 *76 *-------------------------------------------------------------------------77 */78 79#ifndef MEMUTILS_MEMORYCHUNK_H80#define MEMUTILS_MEMORYCHUNK_H81 82#include "utils/memutils_internal.h"83 84 /*85  * The maximum allowed value that MemoryContexts can store in the value86  * field.  Must be 1 less than a power of 2.87  */88#define MEMORYCHUNK_MAX_VALUE			UINT64CONST(0x3FFFFFFF)89 90/*91 * The maximum distance in bytes that a MemoryChunk can be offset from the92 * block that is storing the chunk.  Must be 1 less than a power of 2.93 */94#define MEMORYCHUNK_MAX_BLOCKOFFSET		UINT64CONST(0x3FFFFFFF)95 96/* define the least significant base-0 bit of each portion of the hdrmask */97#define MEMORYCHUNK_EXTERNAL_BASEBIT	MEMORY_CONTEXT_METHODID_BITS98#define MEMORYCHUNK_VALUE_BASEBIT		(MEMORYCHUNK_EXTERNAL_BASEBIT + 1)99#define MEMORYCHUNK_BLOCKOFFSET_BASEBIT	(MEMORYCHUNK_VALUE_BASEBIT + 30)100 101/*102 * A magic number for storing in the free bits of an external chunk.  This103 * must mask out the bits used for storing the MemoryContextMethodID and the104 * external bit.105 */106#define MEMORYCHUNK_MAGIC		(UINT64CONST(0xB1A8DB858EB6EFBA) >> \107								 MEMORYCHUNK_VALUE_BASEBIT << \108								 MEMORYCHUNK_VALUE_BASEBIT)109 110typedef struct MemoryChunk111{112#ifdef MEMORY_CONTEXT_CHECKING113	Size		requested_size;114#endif115 116	/* bitfield for storing details about the chunk */117	uint64		hdrmask;		/* must be last */118} MemoryChunk;119 120/* Get the MemoryChunk from the pointer */121#define PointerGetMemoryChunk(p) \122	((MemoryChunk *) ((char *) (p) - sizeof(MemoryChunk)))123/* Get the pointer from the MemoryChunk */124#define MemoryChunkGetPointer(c) \125	((void *) ((char *) (c) + sizeof(MemoryChunk)))126 127/* private macros for making the inline functions below more simple */128#define HdrMaskIsExternal(hdrmask) \129	((hdrmask) & (((uint64) 1) << MEMORYCHUNK_EXTERNAL_BASEBIT))130#define HdrMaskGetValue(hdrmask) \131	(((hdrmask) >> MEMORYCHUNK_VALUE_BASEBIT) & MEMORYCHUNK_MAX_VALUE)132 133/*134 * We should have used up all the bits here, so the compiler is likely to135 * optimize out the & MEMORYCHUNK_MAX_BLOCKOFFSET.136 */137#define HdrMaskBlockOffset(hdrmask) \138	(((hdrmask) >> MEMORYCHUNK_BLOCKOFFSET_BASEBIT) & MEMORYCHUNK_MAX_BLOCKOFFSET)139 140/* For external chunks only, check the magic number matches */141#define HdrMaskCheckMagic(hdrmask) \142	(MEMORYCHUNK_MAGIC == \143	 ((hdrmask) >> MEMORYCHUNK_VALUE_BASEBIT << MEMORYCHUNK_VALUE_BASEBIT))144/*145 * MemoryChunkSetHdrMask146 *		Store the given 'block', 'chunk_size' and 'methodid' in the given147 *		MemoryChunk.148 *149 * The number of bytes between 'block' and 'chunk' must be <=150 * MEMORYCHUNK_MAX_BLOCKOFFSET.151 * 'value' must be <= MEMORYCHUNK_MAX_VALUE.152 */153static inline void154MemoryChunkSetHdrMask(MemoryChunk *chunk, void *block,155					  Size value, MemoryContextMethodID methodid)156{157	Size		blockoffset = (char *) chunk - (char *) block;158 159	Assert((char *) chunk >= (char *) block);160	Assert(blockoffset <= MEMORYCHUNK_MAX_BLOCKOFFSET);161	Assert(value <= MEMORYCHUNK_MAX_VALUE);162	Assert((int) methodid <= MEMORY_CONTEXT_METHODID_MASK);163 164	chunk->hdrmask = (((uint64) blockoffset) << MEMORYCHUNK_BLOCKOFFSET_BASEBIT) |165		(((uint64) value) << MEMORYCHUNK_VALUE_BASEBIT) |166		methodid;167}168 169/*170 * MemoryChunkSetHdrMaskExternal171 *		Set 'chunk' as an externally managed chunk.  Here we only record the172 *		MemoryContextMethodID and set the external chunk bit.173 */174static inline void175MemoryChunkSetHdrMaskExternal(MemoryChunk *chunk,176							  MemoryContextMethodID methodid)177{178	Assert((int) methodid <= MEMORY_CONTEXT_METHODID_MASK);179 180	chunk->hdrmask = MEMORYCHUNK_MAGIC | (((uint64) 1) << MEMORYCHUNK_EXTERNAL_BASEBIT) |181		methodid;182}183 184/*185 * MemoryChunkIsExternal186 *		Return true if 'chunk' is marked as external.187 */188static inline bool189MemoryChunkIsExternal(MemoryChunk *chunk)190{191	/*192	 * External chunks should always store MEMORYCHUNK_MAGIC in the upper193	 * portion of the hdrmask, check that nothing has stomped on that.194	 */195	Assert(!HdrMaskIsExternal(chunk->hdrmask) ||196		   HdrMaskCheckMagic(chunk->hdrmask));197 198	return HdrMaskIsExternal(chunk->hdrmask);199}200 201/*202 * MemoryChunkGetValue203 *		For non-external chunks, returns the value field as it was set in204 *		MemoryChunkSetHdrMask.205 */206static inline Size207MemoryChunkGetValue(MemoryChunk *chunk)208{209	Assert(!HdrMaskIsExternal(chunk->hdrmask));210 211	return HdrMaskGetValue(chunk->hdrmask);212}213 214/*215 * MemoryChunkGetBlock216 *		For non-external chunks, returns the pointer to the block as was set217 *		in MemoryChunkSetHdrMask.218 */219static inline void *220MemoryChunkGetBlock(MemoryChunk *chunk)221{222	Assert(!HdrMaskIsExternal(chunk->hdrmask));223 224	return (void *) ((char *) chunk - HdrMaskBlockOffset(chunk->hdrmask));225}226 227/* cleanup all internal definitions */228#undef MEMORYCHUNK_EXTERNAL_BASEBIT229#undef MEMORYCHUNK_VALUE_BASEBIT230#undef MEMORYCHUNK_BLOCKOFFSET_BASEBIT231#undef MEMORYCHUNK_MAGIC232#undef HdrMaskIsExternal233#undef HdrMaskGetValue234#undef HdrMaskBlockOffset235#undef HdrMaskCheckMagic236 237#endif							/* MEMUTILS_MEMORYCHUNK_H */238 
codekingpro/portable-devtools · Team Ai