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

📄 notes.txt

📁 eCos操作系统源码
💻 TXT
字号:
                Memory allocation package - Implementation Notes                ------------------------------------------------Made with loving care by Jonathan Larmour (jlarmour@redhat.com)Initial version: 2000-07-03Last updated:    2000-07-03Meta----This document describes some interesting bits and pieces about the memoryallocation package - CYGPKG_MEMALLOC. It is intended as a guide todevelopers, not users. This isn't (yet) in formal documentation format,and probably should be.Philosophy----------The object of this package is to provide everything required for dynamicmemory allocation, some sample implementations, the ability to plug inmore implementations, and a standard malloc() style interface to thoseallocators.The classic Unix-style view of a heap is using brk()/sbrk() to extend thedata segment of the application. However this is inappropriate for anembedded system because:- you may not have an MMU, which means memory may be disjoint, thus breaking  this paradigm- in a single process system there is no need to play tricks since there  is only the one address space and therefore heap area to use.Therefore instead, we base the heap on the idea of fixed size memory pools.The size of each pool is known in advance.Overview--------Most of the infrastructure this package provides is geared towardssupporting the ISO standard malloc() family of functions. A "standard"eCos allocator should be able to plug in to this infrastructure andtransparently work. The interface is based on simple use of C++ - nothingtoo advanced.The allocator to use is dictated by theCYGBLD_MEMALLOC_MALLOC_IMPLEMENTATION_HEADER option. Choosing theallocator can be done by ensuring the CDL for the new allocatorhas a "requires" that sets the location of the header to use when thatallocator is enabled. New allocators should default to disabled, so theydon't have to worry about which one is the default, thus causing CDLconflicts. When enabled the new allocator should also claim to implementCYGINT_MEMALLOC_MALLOC_ALLOCATORS.The implementation header file that is set must have a special propertythough - it may be included with __MALLOC_IMPL_WANTED defined. If thisis the case, then this means the infrastructure wants to find out thename of the class that is implemented in this header file. This is doneby setting CYGCLS_MEMALLOC_MALLOC_IMPL. If __MALLOC_IMPL_WANTED is definedthen no non-preprocessor output should be generated, as this will be includedin a TCL script in due course. An existing example from this package wouldbe:#define CYGCLS_MEMALLOC_MALLOC_IMPL Cyg_Mempool_dlmalloc// if the implementation is all that's required, don't output anything else#ifndef __MALLOC_IMPL_WANTEDclass Cyg_Mempool_dlmalloc{[etc.]To meet the expectations of malloc, the class should have the followingpublic interfaces (for details it is best to look at some of theexamples in this package):- a constructor taking arguments of the form:  ALLOCATORNAME( cyg_uint8 *base, cyg_int32 size );  If you want to be able to support other arguments for when accessing  the allocator directly you can add them, but give them default values,  or use overloading- a destructor- a try_alloc() function that returns new memory, or NULL on failure:    cyg_uint8 *    try_alloc( cyg_int32 size );- a free() function taking one pointer argument that returns a boolean  for success or failure:    cyg_bool    free( cyg_uint8 *ptr );  Again, extra arguments can be added, as long as they are defaulted.- resize_alloc() which is designed purely to support realloc(). It  has the prototype:     cyg_uint8 *    resize_alloc( cyg_uint8 *alloc_ptr, cyg_int32 newsize,                  cyg_int32 *oldsize );  The idea is that if alloc_ptr can be adjusted to newsize, then it will  be. If oldsize is non-NULL the old size (possibly rounded) is placed  there. However what this *doesn't* do (unlike the real realloc()) is  fall back to doing a new malloc(). All it does is try to do tricks  inside the allocator. It's up to higher layers to call malloc().- get_status() allows the retrieval of info from the allocator. The idea  is to pass in the bitmask OR of the flags defined in common.hxx, which  selects what information is requested. If the request is supported by  the allocator, the approriate structure fields are filled in; otherwise  unsupported fields will be left with the value -1. (The constructor for  Cyg_Mempool_Status initializes them to -1). If you want to reinitialize  the structure and deliberately lose the data in a Cyg_Mempool_Status  object, you need to invoke the init() method of the status object to  reinitialize it.    void    get_status( cyg_mempool_status_flag_t flags, Cyg_Mempool_Status &status );  A subset of the available stats are exported via mallinfo()Cyg_Mempolt2 template---------------------If using the eCos kernel with multiple threads accessing the allocators,then obviously you need to be sure that the allocator is accessed in athread-safe way. The malloc() wrappers do not make any assumptionsabout this. One helpful approach currently used by all the allocatorsin this package is to (optionally) use a template (Cyg_Mempolt2) thatprovides extra functions like a blocking alloc() that waits for memoryto be freed before returning, and a timed variant. Other calls aregenerally passed straight through, but with the kernel scheduler lockedto prevent pre-emption.You don't have to use this facility to fit into the infrastructure though,and thread safety is not a prerequisite for the rest of the infrastructure.And indeed certain allocators will be able to do scheduling at a finergranularity than just locking the scheduler every time.The odd name is because of an original desire to keep 8.3 filenames, whichwas reflected in the class name to make it correspond to the filename.There used to be an alternative Cyg_Mempoolt template, but that has falleninto disuse and is no longer supported.Automatic heap sizing---------------------This package contains infrastructure to allow the automatic definitionof memory pools that occupy all available memory. In order to do thisyou must use the eCos Memory Layout Tool to define a user-defined section.These sections *must* have the prefix "heap", for example "heap1", "heap2","heapdram" etc. otherwise they will be ignored.The user-defined section may be of fixed size, or of unknown size. If ithas unknown size then its size is dictated by either the location ofthe next following section with an absolute address, or if there areno following sections, the end of the memory region. The latter shouldbe the norm.If no user-defined sections starting with "heap" are found, a fallbackstatic array (i.e. allocated in the BSS) will be used, whose size canbe set in the configuration.It is also possible to define multiple heap sections. This isnecessary when you have multiple disjoint memory regions, and no MMUto join it up into one contiguous memory space. In which casea special wrapper allocator object is automatically used. This objectis an instantiation of the Cyg_Mempool_Joined template class,defined in memjoin.hxx. It is instantiated with a list of every heapsection, which it then records. It's sole purpose is to act as a gobetween to the underlying implementation, and does the right thing byusing pointer addresses to determine which memory pool the pointerallocator, and therefore which memory pool instantiation to use.Obviously using the Cyg_Mempool_Joined class adds overhead, but if thisis a problem, then in that case you shouldn't define multiple disjointheaps!Run-time heap sizing--------------------As a special case, some platforms support the addition of memory in thefield, in which case it is desirable to automatically make thisavailable to malloc. The mechanism for this is to define a macro inthe HAL, specifically, defined in hal_intr.h:HAL_MEM_REAL_REGION_TOP( cyg_uint8 *regionend )This macro takes the address of the "normal" end of the region. Thiscorresponds with the size of the memory region in the MLT, and wouldbe end of the "unexpanded" region. This makes sense because the memoryregion must be determined by the "worst case" of what memory will beinstalled.This macro then returns a pointer which is the *real* region end,as determined by the HAL at run-time.By having the macro in this form, it is therefore flexible enough towork with multiple memory regions.There is an example in the ARM HAL - specifically the EBSA285.How it works------------The MLT outputs macros providing information about user-defined sectionsinto a header file, available via system.h with the CYGHWR_MEMORY_LAYOUT_Hdefine. When the user-defined section has no known size, it determinesthe size correctly relative to the end of the region, and sets the SIZEmacro accordingly.A custom build rule preprocesses src/heapgen.cpp to generate heapgeninc.tclThis contains TCL "set"s to allow access to the values of variousbits of configuration data. heapgen.cpp also includes the mallocimplementation header (as defined byCYGBLD_MEMALLOC_MALLOC_IMPLEMENTATION_HEADER) with __MALLOC_IMPL_WANTEDdefined. This tells the header that it should define the macroCYGCLS_MEMALLOC_MALLOC_IMPL to be the name of the actual class. Thisis then also exported with a TCL "set".src/heapgen.tcl then includes heapgeninc.tcl which gives it access tothe configuration values. heapgen.tcl then searches the LDI file forany sections beginning with "heap" (with possibly leading underscores).It records each one it finds and then generates a file heaps.cxx in thebuild tree to instantiate a memory pool object of the required class foreach heap. It also generates a list containing the addresses of eachpool that was instantiated. A header file heaps.hxx is then generatedthat exports the number of pools, a reference to this list array andincludes the implementation header.Custom build rules then copy the heaps.hxx into the include/pkgconfsubdir of the install tree, and compile the heaps.cxx.To access the generated information, you must #include <pkgconf/heaps.hxx>The number of heaps is given by the CYGMEM_HEAP_COUNT macro. The type ofthe pools is given by CYGCLS_MEMALLOC_MALLOC_IMPL, and the array ofinstantiated pools is available with cygmem_memalloc_heaps. For example,here is a sample heaps.hxx:#ifndef CYGONCE_PKGCONF_HEAPS_HXX#define CYGONCE_PKGCONF_HEAPS_HXX/* <pkgconf/heaps.hxx> */ /* This is a generated file - do not edit! */ #define CYGMEM_HEAP_COUNT 1#include <cyg/memalloc/dlmalloc.hxx> extern Cyg_Mempool_dlmalloc *cygmem_memalloc_heaps[ 2 ]; #endif/* EOF <pkgconf/heaps.hxx> */The array has size 2 because it consists of one pool, plus a terminatingNULL.In future the addition of cdl_get() available from TCL scripts containedwithin the CDL scripts will remove the need for a lot of this magic.dlmalloc--------A port of dlmalloc is included. Far too many changes were required to makeit fit within the scheme above, so therefore there was no pointtrying to preserve the layout to make it easier to merge in new versions.However dlmalloc rarely changes any more - it is very stable.The version of dlmalloc used was a mixture of 2.6.6 and the dlmalloc fromnewlib (based on 2.6.4). In the event, most of the patches merged wereof no consequence to the final version.For reference, the various versions examined are included in thedoc/dlmalloc subdirectory: dlmalloc-2.6.4.c, dlmalloc-2.6.6.c,dlmalloc-newlib.c and dlmalloc-merged.c (which is the result of mergingthe changes between 2.6.4 and the newlib version into 2.6.6). Note itwas not tested at that point.            Remaining issues----------------You should be allowed to have different allocators for different memoryregions. The biggest hurdle here is host tools support to express this.Currently the "joined" allocator wrapper simply treats each memory poolas an equal. It doesn't understand that some memory pools may be fasterthan others, and cannot make decisions about which pools (and thereforeregions and therefore possibly speeds of memory) to use on the basisof allocation size. This should be (configurably) possible.History-------A long, long time ago, in a galaxy far far away.... the situation used tobe that the kernel package contained the fixed block and simple variableblock memory allocators, and those were the only memory allocatorimplementations. This was all a bit incongruous as it meant that any codewanting dynamic memory allocation had to include the whole kernel, eventhough the dependencies could be encapsulated. This was particularly sillybecause the implementation of malloc() (etc.) in the C library didn't useany of the features that *did* depend on the kernel, such as timed waitswhile allocating memory, etc.The C library malloc was pretty naff then too. It used a static bufferas the basis of the memory pool, with a hard-coded size, set in theconfiguration. You couldn't make it fit into all of memory.Jifl2000-07-03//####ECOSGPLCOPYRIGHTBEGIN####// -------------------------------------------// This file is part of eCos, the Embedded Configurable Operating System.// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.//// eCos is free software; you can redistribute it and/or modify it under// the terms of the GNU General Public License as published by the Free// Software Foundation; either version 2 or (at your option) any later version.//// eCos is distributed in the hope that it will be useful, but WITHOUT ANY// WARRANTY; without even the implied warranty of MERCHANTABILITY or// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License// for more details.//// You should have received a copy of the GNU General Public License along// with eCos; if not, write to the Free Software Foundation, Inc.,// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.//// As a special exception, if other files instantiate templates or use macros// or inline functions from this file, or you compile this file and link it// with other works to produce a work based on this file, this file does not// by itself cause the resulting work to be covered by the GNU General Public// License. However the source code for this file must still be made available// in accordance with section (3) of the GNU General Public License.//// This exception does not invalidate any other reasons why a work based on// this file might be covered by the GNU General Public License.//// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.// at http://sources.redhat.com/ecos/ecos-license/// -------------------------------------------//####ECOSGPLCOPYRIGHTEND####

⌨️ 快捷键说明

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