📄 mempartlib.c
字号:
/* memPartLib.c - core memory partition manager *//* Copyright 1984-2002 Wind River Systems, Inc. */#include "copyright_wrs.h"/*modification history--------------------02c,22may02,zl use the ALIGNED() macro for alignment test (SPR#74247).02b,23apr02,gls added check for overflow in memPartAlignedAlloc (SPR #27741)02a,04oct01,tam fixed doc. of arch alignment01z,03mar00,zl merged SH support into T201y,15mar99,c_c Doc: Fixed alignment for MIPS (SPR #8883).01x,21feb99,jdi doc: listed errnos.01w,17feb98,dvs added instrumentation points (pr)01v,17dec97,yp corrected documentation for memPartIsValid (SPR #8537)01u,07oct96,dgp doc: change description of memPartXxx() (no partition deletion available)01t,19mar95,dvs removed tron references.01s,19sep94,rhp added stdlib.h to INCLUDE FILES list in doc (SPR#2285)01r,13sep93,jmm fixed memPartAddToPool to check correct sizes of memory01q,24jun93,jmm fixed memPartAddToPool to reject pool sizes that are too small01p,24jun93,jmm fixed memPartAddToPool to round poolSize down to alignment boundry (spr 2185)01o,10feb93,jdi deleted mention of "error" handling in doc for free(); fixed spelling of stdlib.h.01n,05feb93,jdi tweaked wording for 01m.01m,05feb93,smb corrected return documentation for free and malloc01l,23jan93,jdi documentation cleanup for 5.1.01k,13nov92,dnw added include of smObjLib.h01j,20oct92,pme added reference to shared memory manager documentation.01i,02oct92,jdi documentation cleanup.01h,08sep92,jmm changed memPartFree() to mark coalesced blocks as not free01g,23aug92,jcf changed bzero to bfill. removed taskOptionsGet.01f,29jul92,pme added NULL function pointer check for smObj routines.01e,28jul92,jcf changed default memory partition options. moved MEM_BLOCK_ERROR_SUSPEND_FLAG handling here.01d,19jul92,pme added shared memory partition support.01c,19jul92,smb added some ANSI documentation.01b,18jul92,smb Changed errno.h to errnoLib.h.01a,01jul92,jcf extracted from v4n memLib.c*//*DESCRIPTIONThis library provides core facilities for managing the allocation ofblocks of memory from ranges of memory called memory partitions. Thelibrary was designed to provide a compact implementation; full-featuredfunctionality is available with memLib, which provides enhanced memorymanagement features built as an extension of memPartLib. (For moreinformation about enhanced memory partition management options, see themanual entry for memLib.) This library consists of two sets of routines.The first set, memPart...(), comprises a general facility for the creationand management of memory partitions, and for the allocation and deallocationof blocks from those partitions. The second set provides a traditionalANSI-compatible malloc()/free() interface to the system memory partition.The system memory partition is created when the kernel is initialized bykernelInit(), which is called by the root task, usrRoot(), inusrConfig.c. The ID of the system memory partition is stored in theglobal variable `memSysPartId'; its declaration is included in memLib.h.The allocation of memory, using malloc() in the typical case andmemPartAlloc() for a specific memory partition, is done with a first-fitalgorithm. Adjacent blocks of memory are coalesced when they are freedwith memPartFree() and free(). There is also a routine provided for allocatingmemory aligned to a specified boundary from a specific memory partition,memPartAlignedAlloc().CAVEATSArchitectures have various alignment constraints. To provide optimalperformance, malloc() returns a pointer to a buffer having the appropriatealignment for the architecture in use. The portion of the allocatedbuffer reserved for system bookkeeping, known as the overhead, may varydepending on the architecture..ne 12.TScenter,tab(|);lf3 cf3 cf3a n n .Architecture | Boundary | Overhead_ ARM | 4 | 8 COLDFIRE | 4 | 8 I86 | 4 | 8 M68K | 4 | 8 MCORE | 8 | 8 MIPS | 16 | 16 PPC * | 8/16 | 8/16 SH | 4 | 8 SIMNT | 8 | 8 SIMSOLARIS| 8 | 8 SPARC | 8 | 8.TE* On PowerPC, the boundary and overhead values are 16 bytes for system basedon the PPC604 CPU type (including ALTIVEC). For all other PowerPC CPU types(PPC403, PPC405, PPC440, PPC860, PPC603, etc...), the boundary and overhead are 8 bytes.INCLUDE FILES: memLib.h, stdlib.hSEE ALSO: memLib, smMemLibINTERNALThis package is initialized by kernelInit() which calls memInit() with apointer to a block of memory from which memory will be allocated.Blocks allocated by malloc() are actually larger than the size requestedby the user. Each block is prefaced by a header which contains the sizeand status of that block and a pointer to the previous block. The pointerreturned to the user points just past this header. Likewise when a blockis freed, the header is found just in front of the block pointer passed bythe user.The header data is arranged so that the pointer to the previous blockcomes first and is therefore adjacent to that previous block. Thus eachblock has 4 bytes of redundant information on either side of it (the 4bytes of size and status before it in its own header, and the 4-bytepointer after it in the next header). This redundant information isoptionally used in free() and realloc() to make a consistency check onblocks specified by the user. This mechanism helps to detect two commonerrors: (1) bad block pointers passed to free() or realloc() are usuallydetected, and (2) trashing up to 4 bytes on either side of the block willonly affect that block and will also be detected by free() or realloc().There is a minimum block size which malloc() allocates; this is to insurethat there will be enough room for the free list links that must be usedwhen the block is freed if it cannot be coalesced with an adjacent block.The malloc() and realloc() routines always allocate memory aligned to the boundary defined in the global variable memDefaultAlignment, which is initialized to the alignment required for the specific architecture.The memory partition semaphore is a structure in the partition descriptorrather than a pointer to a dynamically created semaphore structure.This is because of the chicken-and-the-egg problem of memLib using semaphoresand semCreate calling malloc. Instead the structure is simply declareddirectly in the partition structure and we call semInit() instead ofsemCreate().*/#include "vxWorks.h"#include "semLib.h"#include "dllLib.h"#include "logLib.h"#include "taskLib.h"#include "stdlib.h"#include "stdio.h"#include "string.h"#include "errnoLib.h"#include "smObjLib.h"#include "private/memPartLibP.h"#include "private/eventP.h"/* forward static functions */LOCAL void memPartSemInit (PART_ID partId);LOCAL STATUS memPartDestroy (PART_ID partId);LOCAL BLOCK_HDR *memAlignedBlockSplit (PART_ID partId, BLOCK_HDR *pHdr, unsigned nWords, unsigned minWords, unsigned alignment);/* local variables */LOCAL PARTITION memSysPartition; /* system partition used by malloc */LOCAL OBJ_CLASS memPartClass; /* memory partition object class */LOCAL BOOL memPartLibInstalled; /* TRUE if library has been installed */#ifdef WV_INSTRUMENTATIONLOCAL OBJ_CLASS memPartInstClass; /* mem part instrumented object class */#endif/* global variables */FUNCPTR smMemPartAddToPoolRtn = NULL;FUNCPTR smMemPartFreeRtn = NULL;FUNCPTR smMemPartAllocRtn = NULL;CLASS_ID memPartClassId = &memPartClass; /* partition class id */#ifdef WV_INSTRUMENTATIONCLASS_ID memPartInstClassId = &memPartInstClass; /* part inst class id */#endifPART_ID memSysPartId = &memSysPartition; /* sys partition id */UINT memDefaultAlignment = _ALLOC_ALIGN_SIZE; /* default alignment */FUNCPTR memPartBlockErrorRtn = NULL; /* block error method */FUNCPTR memPartAllocErrorRtn = NULL; /* alloc error method */FUNCPTR memPartSemInitRtn = (FUNCPTR) memPartSemInit;unsigned memPartOptionsDefault = MEM_BLOCK_ERROR_SUSPEND_FLAG | MEM_BLOCK_CHECK;/********************************************************************************* memPartLibInit - initialize the system memory partition** This routine initializes the system partition free list with the* specified memory block. It must be called exactly once before invoking any* other routine in memLib. It is called by kernelInit() in usrRoot()* in usrConfig.c.** RETURNS: OK or ERROR.* NOMANUAL*/STATUS memPartLibInit ( char *pPool, /* pointer to memory block */ unsigned poolSize /* block size in bytes */ ) { if ((!memPartLibInstalled) && (classInit (memPartClassId, sizeof (PARTITION), OFFSET (PARTITION, objCore), (FUNCPTR) memPartCreate, (FUNCPTR) memPartInit, (FUNCPTR) memPartDestroy) == OK)) {#ifdef WV_INSTRUMENTATION /* Instrumented class for windview */ memPartClassId->initRtn = (FUNCPTR) memPartInstClassId; classInstrument (memPartClassId, memPartInstClassId); #endif memPartInit (&memSysPartition, pPool, poolSize); memPartLibInstalled = TRUE; } return ((memPartLibInstalled) ? OK : ERROR); }/********************************************************************************* memPartCreate - create a memory partition** This routine creates a new memory partition containing a specified* memory pool. It returns a partition ID, which can then be passed to* other routines to manage the partition (i.e., to allocate and free* memory blocks in the partition). Partitions can be created to manage* any number of separate memory pools.** NOTE* The descriptor for the new partition is allocated out of the system memory* partition (i.e., with malloc()).** RETURNS:* The partition ID, or NULL if there is insufficient memory in the system* memory partition for a new partition descriptor.** SEE ALSO: smMemLib*/PART_ID memPartCreate ( char *pPool, /* pointer to memory area */ unsigned poolSize /* size in bytes */ ) { FAST PART_ID pPart; /* allocate a partition structure from the system memory partition */ pPart = (PART_ID) objAlloc (memPartClassId); if (pPart != NULL) memPartInit (pPart, pPool, poolSize);#ifdef WV_INSTRUMENTATION EVT_OBJ_2 (OBJ, pPart, memPartClassId, EVENT_MEMPARTCREATE, pPart, poolSize);#endif return (pPart); }/********************************************************************************* memPartInit - initialize a memory partition** This routine initializes a partition free list, seeding it with the* memory block passed as an argument. It must be called exactly once* for each memory partition created.** SEE ALSO: memPartCreate()** NOMANUAL*/void memPartInit ( FAST PART_ID partId, /* partition to initialize */ char *pPool, /* pointer to memory block */ unsigned poolSize /* block size in bytes */ ) { /* initialize partition descriptor */ bfill ((char *) partId, sizeof (*partId), 0); partId->options = memPartOptionsDefault; partId->minBlockWords = sizeof (FREE_BLOCK) >> 1; /* initialize partition semaphore with a virtual function so semaphore * type is selectable. By default memPartLibInit() will utilize binary * semaphores while memInit() will utilize mutual exclusion semaphores * with the options stored in _mutexOptionsMemLib. */ (* memPartSemInitRtn) (partId); dllInit (&partId->freeList); /* init. free list */#ifdef WV_INSTRUMENTATION if (wvObjIsEnabled) { /* windview - connect object class event logging routine */ objCoreInit (&partId->objCore, memPartInstClassId); } else#endif objCoreInit (&partId->objCore, memPartClassId); /* initialize core */ (void) memPartAddToPool (partId, pPool, poolSize); }/********************************************************************************* memPartDestroy - destroy a partition and optionally free associated memory** This routine is not currently supported. Partitions may not be destroyed.** ARGSUSED*/LOCAL STATUS memPartDestroy ( PART_ID partId /* partition to initialize */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -