1    /* --COPYRIGHT--,TI
     2     * Copyright (c) $(CPYYEAR)
     3     * Texas Instruments
     4     *
     5     *  All rights reserved.  Property of Texas Instruments
     6     *  Restricted rights to use, duplicate or disclose this code are
     7     *  granted through contract.
     8     * 
     9     * --/COPYRIGHT--*/
    10    /*
    11     *  ======== HeapMultiBufMP.xdc ========
    12     *
    13     * 
    14     *! Revision History
    15     *! ================
    16     *! 12-Feb-2009 skp     SDOCM00066723 (Remove 'version' field from Attrs)
    17     *! 09-Dec-2009 skp     Common-header changes
    18     *! 10-Nov-2009 skp     Minor pre-review cleanup
    19     *! 11-Sep-2009 skp     Support for GateMP and new SharedRegion
    20     *! 20-Aug-2009 skp     Added ROV views, static support
    21     *! 03-Aug-2008 toddm   Stolen from avala-i18
    22     */
    23    
    24    package ti.sdo.ipc.heaps;
    25    
    26    import ti.sdo.ipc.SharedRegion;
    27    import ti.sdo.ipc.Ipc;
    28    import ti.sdo.ipc.GateMP;
    29    import ti.sdo.utils.NameServer;
    30    
    31    import xdc.rov.ViewInfo;    /* Display local/shared state + FreeBlockView */
    32    
    33    import xdc.runtime.Error;
    34    import xdc.runtime.Assert;
    35    import xdc.runtime.Memory;
    36    import xdc.runtime.Startup;
    37    
    38    /*!
    39     *  ======== HeapMultiBufMP ========
    40     *  Multi-processor fixed-size buffer heap implementation
    41     *
    42     *  This module has a common header that can be found in the {@link ti.ipc}
    43     *  package.  Application code should include the common header file (not the 
    44     *  RTSC-generated one):
    45     *
    46     *  <PRE>#include &lt;ti/ipc/HeapMultiBufMP.h></PRE>
    47     *   
    48     *  The RTSC module must be used in the application's RTSC configuration file 
    49     *  (.cfg) if runtime APIs will be used in the application:
    50     *  
    51     *  <PRE>HeapMultiBufMP = xdc.useModule('ti.sdo.ipc.heaps.HeapMultiBufMP');
    52     *  </PRE>
    53     *
    54     *  Documentation for all runtime APIs, instance configuration parameters, 
    55     *  error codes macros and type definitions available to the application 
    56     *  integrator can be found in the 
    57     *  <A HREF="../../../../doxygen/html/files.html">Doxygen documenation</A>
    58     *  for the IPC product.  However, the documentation presented on this page 
    59     *  should be referred to for information specific to the RTSC module, such as
    60     *  module configuration, Errors, and Asserts.
    61     *  @p
    62     *
    63     *  It is important to note that max allocation tracking is disabled by default 
    64     *  in {@link #trackMaxAllocs}.  Disabling allocation tracking improves alloc/
    65     *  free performance especially when cache calls are required in shared memory.
    66     */
    67    @InstanceInitError
    68    @InstanceFinalize
    69    
    70    module HeapMultiBufMP inherits xdc.runtime.IHeap 
    71    {
    72        /*! @_nodoc */
    73        metaonly struct BasicView {
    74            String          name;
    75            Ptr             buf;
    76            Memory.Size     totalSize;
    77            String          objType;
    78            Ptr             gate;
    79            Bool            exact;
    80        }
    81        
    82        /*! @_nodoc */
    83        metaonly struct BucketsView {
    84            Ptr             baseAddr;
    85            UInt            blockSize;
    86            UInt            align;
    87            UInt            numBlocks;
    88            UInt            numFreeBlocks;
    89            UInt            minFreeBlocks;
    90        }
    91    
    92        /*! @_nodoc */
    93        @Facet
    94        metaonly config ViewInfo.Instance rovViewInfo =
    95            ViewInfo.create({
    96                viewMap: [
    97                [   
    98                    'Basic',
    99                    {
   100                        type: ViewInfo.INSTANCE,
   101                        viewInitFxn: 'viewInitBasic',
   102                        structName: 'BasicView'
   103                    }
   104                ],
   105                [   
   106                    'Buffer Information',
   107                    {
   108                        type: ViewInfo.INSTANCE_DATA,
   109                        viewInitFxn: 'viewInitData',
   110                        structName: 'BucketsView'
   111                    }
   112                ],
   113                ]
   114            });
   115            
   116        /*! 
   117         *  Structure for bucket configuration
   118         *
   119         *  An array of buckets is a required parameter to create any 
   120         *  HeapMultiBufMP instance.  The fields of each bucket correspond
   121         *  to the attributes of each buffer in the HeapMultiBufMP.  The actual
   122         *  block sizes and alignments may be adjusted per the process described
   123         *  at {@link #bucketEntries}.
   124         *
   125         *  @field(blockSize)       Size of each block (in MADUs)
   126         *  @field(numBlocks)       Number of blocks
   127         *  @field(align)           Alignment of each block (in MADUs)
   128         */    
   129        struct Bucket {
   130            SizeT       blockSize;
   131            UInt        numBlocks;
   132            SizeT       align;
   133        }
   134    
   135        /*!
   136         *  ======== ExtendedStats ========
   137         *  Stats structure for the getExtendedStats API.  
   138         *
   139         *  @field(numBuckets)         Number of buckets
   140         *  @field(numBlocks)          Number of blocks in each buffer
   141         *  @field(blockSize)          Block size of each buffer     
   142         *  @field(align)              Alignment of each buffer
   143         *  @field(maxAllocatedBlocks) The maximum number of blocks allocated from
   144         *                             this heap at any single point in time during
   145         *                             the lifetime of this HeapMultiBufMP instance
   146         *
   147         *  @field(numAllocatedBlocks) The total number of blocks currently
   148         *                             allocated in this HeapMultiBufMP instance
   149         */
   150        struct ExtendedStats {
   151            UInt numBuckets;
   152            UInt numBlocks          [8];
   153            UInt blockSize          [8];
   154            UInt align              [8];
   155            UInt maxAllocatedBlocks [8];
   156            UInt numAllocatedBlocks [8];
   157        }
   158            
   159        /*!
   160         *  Assert raised when the align parameter is not a power of 2.
   161         */
   162        config Assert.Id A_invalidAlign = 
   163            {msg: "align parameter must be a power of 2"};
   164    
   165        /*! 
   166         *  Assert raised when an invalid buffer size was passed to free() 
   167         */
   168        config Assert.Id A_sizeNotFound = 
   169            {msg: "an invalid buffer size was passed to free"};
   170            
   171        /*! 
   172         *  Assert raised when an invalid block address was passed to free() 
   173         */
   174        config Assert.Id A_addrNotFound = 
   175            {msg: "an invalid buffer address was passed to free"};
   176            
   177        /*!
   178         *  Error raised when exact matching failed
   179         */
   180        config Error.Id E_exactFail =
   181            {msg: "E_exactFail: Exact allocation failed (requested size = 0x%x and buffer size = 0x%x)"};        
   182      
   183        /*! 
   184         *  Maximum runtime entries 
   185         *
   186         *  Maximum number of HeapMultiBufMP's that can be dynamically created and
   187         *  added to the NameServer.
   188         *
   189         *  To minimize the amount of runtime allocation, this parameter allows
   190         *  the pre-allocation of memory for the HeapMultiBufMP's NameServer table.
   191         *  The default is to allow growth (i.e. memory allocation when 
   192         *  creating a new instance).
   193         */
   194        metaonly config UInt maxRuntimeEntries = NameServer.ALLOWGROWTH;
   195            
   196        /*! 
   197         *  Maximum length for heap names
   198         */
   199        config UInt maxNameLen = 32;
   200        
   201        /*! 
   202         *  Section name is used to place the names table
   203         *
   204         *  The default value of NULL implies that no explicit placement is 
   205         *  performed.
   206         */
   207        metaonly config String tableSection = null;
   208        
   209        /*!
   210         *  Track the maximum number of allocated blocks
   211         * 
   212         *  This will enable/disable the tracking of the maximum number of
   213         *  allocations for a HeapMultiBufMP instance.  This maximum refers to the
   214         *  "all time" maximum number of allocations for the history of a 
   215         *  HeapMultiBufMP instance, not the current number of allocations.
   216         * 
   217         *  Tracking the maximum might adversely affect performance when allocating
   218         *  and/or freeing. If this feature is not needed, setting this to false
   219         *  avoids the performance penalty.
   220         */
   221        config Bool trackMaxAllocs = false;
   222         
   223    instance:
   224    
   225        /*! 
   226         *  GateMP used for critical region management of the shared memory 
   227         *
   228         *  Using the default value of NULL will result in use of the GateMP
   229         *  system gate for context protection.
   230         */
   231        config GateMP.Handle gate = null; 
   232    
   233        /*! @_nodoc
   234         *   by the open() call. No one else should touch this!
   235         */
   236        config Bool openFlag = false;
   237        
   238        /*!
   239         *  Use exact matching
   240         *
   241         *  Setting this flag will allow allocation only if the requested size
   242         *  is equal to (rather than less than or equal to) a buffer's block size.
   243         */
   244        config Bool exact = false;
   245        
   246        /*! 
   247         *  Name of this instance.
   248         *
   249         *  The name (if not NULL) must be unique among all HeapMultiBufMP
   250         *  instances in the entire system.  When creating a new
   251         *  heap, it is necessary to supply an instance name.
   252         */
   253        config String name = null;
   254    
   255        /*!
   256         *  Number of buckets in {@link #bucketEntries}
   257         *
   258         *  This parameter is required to create any instance.
   259         */
   260        config Int numBuckets = 0;
   261        
   262        /*!
   263         *  Bucket Entries
   264         * 
   265         *  The bucket entries are an array of {@link #Bucket}s whose values  
   266         *  correspond to the desired alignment, block size and length for each 
   267         *  buffer.  It is important to note that the alignments and sizes for each 
   268         *  buffer may be adjusted due to cache and alignment related constraints.  
   269         *  Buffer sizes are rounded up by their corresponding alignments.  Buffer 
   270         *  alignments themselves will assume the value of region cache alignment 
   271         *  size when the cache size is greater than the requested buffer alignment. 
   272         * 
   273         *  For example, specifying a bucket with {blockSize: 192, align: 256} will
   274         *  result in a buffer of blockSize = 256 and alignment = 256.  If cache 
   275         *  alignment is required, then a bucket of {blockSize: 96, align: 64} will 
   276         *  result in a buffer of blockSize = 128 and alignment = 128 (assuming 
   277         *  cacheSize = 128).
   278         */
   279        config Bucket bucketEntries[];
   280        
   281        /*! 
   282         *  Shared region ID
   283         *
   284         *  The index corresponding to the shared region from which shared memory
   285         *  will be allocated.
   286         */
   287        config UInt16 regionId = 0;
   288    
   289        /*! @_nodoc
   290         *  Physical address of the shared memory
   291         *
   292         *  This value can be left as 'null' unless it is required to place the
   293         *  heap at a specific location in shared memory.  If sharedAddr is null,
   294         *  then shared memory for a new instance will be allocated from the 
   295         *  heap belonging to the region identified by {@link #regionId}.
   296         */
   297        config Ptr sharedAddr = null;
   298    
   299    internal:
   300        
   301        /*! Used in the attrs->status field */
   302        const UInt32 CREATED = 0x05101920;
   303        
   304        /*! 
   305         *  This Params object is used for temporary storage of the
   306         *  module wide parameters that are for setting the NameServer instance.
   307         */
   308        metaonly config NameServer.Params nameSrvPrms;
   309    
   310        /*! slice and dice the buffer */
   311        Void postInit(Object *obj, Error.Block *eb);
   312        
   313        /*! 
   314         * Takes in modifiable array of bucket entries, performs an in-place sort
   315         * of the bucket entries, combines the entries as necessary, and returns
   316         * the new number of buckets in the combined entries
   317         */
   318        UInt processBuckets(Bucket *bucketEntries, Params *params, 
   319                            UInt16 regionId);
   320        
   321        /*! Comparison function for Buckets used in processBuckets */
   322        Int sizeAlignCompare(const Void *a, const Void *b);
   323    
   324        /*! 
   325         * Add the block to the tail; index specifies the buffer number
   326         *
   327         * Precondition: inv obj->attrs->bucket[index]
   328         * Postcondition: wb obj->attrs->bucket[index] and wb the block
   329         */
   330        Void putTail(Object *obj, Int index, Elem *block);
   331        
   332        /*! 
   333         * Removes a block from the head and returns it; index specifies 
   334         * the buffer number. The block is invalidated before returned
   335         *
   336         * Precondition: inv obj->attrs->bucket[index]
   337         * Postcondition: wb obj->attrs->bucket[index]
   338         */
   339        Elem *getHead(Object *obj, Int index);
   340        
   341        /*! Needed for freelist */    
   342        @Opaque struct Elem {
   343            /* must be volatile for whole_program */
   344            volatile SharedRegion.SRPtr next;   
   345        };
   346        
   347        /*! Shared memory state for a single buffer. */
   348        struct BucketAttrs {
   349            SharedRegion.SRPtr  head;
   350            SharedRegion.SRPtr  tail;
   351            SharedRegion.SRPtr  baseAddr;
   352            Bits32              numFreeBlocks;
   353            Bits32              minFreeBlocks;
   354            Bits32              blockSize;
   355            Bits32              align;
   356            Bits32              numBlocks;
   357        }
   358        
   359        /*! Shared memory state for a HeapMultiBufMP instance */    
   360        struct Attrs {
   361            Bits32              status;         /* Created stamp                 */
   362            SharedRegion.SRPtr  gateMPAddr;     /* GateMP SRPtr                  */
   363            Bits32              numBuckets;     /* Number of buffers             */
   364            BucketAttrs         buckets[8]; /* Buffer attributes        */
   365            Bits16              exact;          /* 1 = exact matching, 0 = no    */     
   366        }
   367        
   368        struct Instance_State {
   369            Attrs               *attrs;         /* Shared state                  */
   370            GateMP.Handle       gate;           /* Gate for critical regions     */
   371            Ipc.ObjType         objType;        /* See enum ObjType              */
   372            Ptr                 nsKey;          /* Used to remove NS entry       */
   373            Bool                cacheEnabled;   /* Whether to do cache calls     */
   374            UInt16              regionId;       /* SharedRegion index            */
   375            SizeT               allocSize;      /* Shared memory allocated       */
   376            Char                *buf;           /* Local pointer to buf          */
   377            Bucket              bucketEntries[];/* Optimized bucketEntries       */
   378                                                /* NULL for dynamic instance     */
   379            UInt                numBuckets;     /* # of optimized entries        */
   380            Bool                exact;          /* Exact match flag              */
   381        };
   382        
   383        struct Module_State {
   384            NameServer.Handle   nameServer;
   385        };
   386    }